蓝桥杯单片机基础模块

该代码段展示了在嵌入式系统中如何读取和设置DS1302实时时钟的时间,读取DS18B20温度传感器的温度,进行ADC转换,读写24C02EEPROM,以及使用PWM和中断处理NE555定时器和超声波测距功能。同时,还包括了串口通信的部分实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/* 时间读取 */
/*****************************************************
#define DecToBCD(dec) (dec / 10 * 16) + (dec % 10)
#define BCDToDec(bcd) (bcd / 16 * 10) + (bcd % 16)

u8 hour,minute,second;
void Read_Time()
{
	hour = BCDTODec(Read_Ds1302_Byte (0x85));
	minute = BCDTODec(Read_Ds1302_Byte (0x83));
	second = BCDTODec(Read_Ds1302_Byte (0x81));
}

void Write_Time(u8 hour,u8 min,u8 sec)
{
	Write_Ds1302_Byte(0x84,DecToBCD(hour));
	Write_Ds1302_Byte(0x82,DecToBCD(min));
	Write_Ds1302_Byte(0x80,DecToBCD(sec));
}

Write_Ds1302_Byte(0x8e,0x00);//关闭写保护
Write_Ds1302_Byte(0x80,DecToBCD(second) & 0x7f);//时间继续
Write_Ds1302_Byte(0x8e,0x80);//打开写保护

Write_Ds1302_Byte(0x8e,0x00);
Write_Ds1302_Byte(0x80,DecToBCD(second) | 0x80);//时间暂停
Write_Ds1302_Byte(0x8e,0x80);

*****************************************************/
/* 温度读取 */
u8 Read_Temp()
{
	u8 temp,low,high;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);

	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	low = Read_DS18B20();
	high = Read_DS18B20();
	temp = (high << 8 | low) * 0.0625;
	if(temp >= 85) temp = 20;
	
	return temp;
}
/* AT24C02,PCF8591 */
/*********************************/
u8 Read_ADC(u8 Dadd,u8 Wadd)
{
	u8 dat;
	I2CStart();
	I2CSendByte(Dadd);
	I2CWaitAck();
	I2CSendByte(Wadd);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(Dadd | 0x01);
	I2CWaitAck();
	dat = I2CReceiveByte();
	I2CSendAck(1);
    I2CStop();
	
	return dat;
}
/* 连续写入必须延迟5ms以上,驱动所带延时无法延时5ms*/
void Delay5ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 59;
	j = 90;
	do
	{
		while (--j);
	} while (--i);
}


void Write_EERPROM(u8 add,u8 dat) 
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(add);
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
	Delay5ms();
}

u8 Read_EERPROM(u8 add)
{
	u8 dat;
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(add);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	dat = I2CReceiveByte();
	I2CSendAck(1);
    I2CStop();
	
	return dat;
}

/*********************************/
/* PWM输出,放到中断 */
/********************************************
u8 count;
u8 interval;

void Out_PWM()
{
	count = count % 10 + 1
	if(count <= interval )
	{
		P34 = 1;
	}
	else P34 = 0;
}

void Timer2Init(void)		//100微秒@12.000MHz
{
	AUXR |= 0x04;		//定时器时钟1T模式
	T2L = 0x50;		//设置定时初始值
	T2H = 0xFB;		//设置定时初始值
	AUXR |= 0x10;		//定时器2开始计时
	EA = 1;
	IE2 |= 0x04;
}
************************************************/
/* NE555,放进中断 */
/****************************************
u16 NEcount;
u16 frq;

void Counter_Init()
{
	
	TMOD |= 0x05;
	TH0 = 0x00;
	TL0 = 0x00;
	TR0 = 1;
}

u16 Read_NE555()
{
	NEcount++;
	if(NEcount >= 1000)
	{
		NEcount = 0;
		frq = TH0 << 8 | TL0;
		TH0 = 0;TL0 = 0;
	}
	return frq;
}
****************************************/
/* 超声波 */
void Delay12us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 33;
	while (--i);
}


void Send_Wave()
{
	u8 i;
	for(i = 0;i < 8;i++)
	{
		P10 = 1;
		Delay12us();
		P10 = 0;
		Delay12us();
	}
	
}

u16 Get_distance()
{
	u16 dist;
	Send_Wave();
	TH1 = 0;TL1 = 0;
	TR1 = 1;
 	while(P11 == 1);
	TR1 = 0;
	dist = (TH1 << 8 | TL1) * 0.017;
	
	return dist;
}
/* 串口 */
/**********************************************************
void UartInit(void)		//4800bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器时钟12T模式
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xCC;		//设置定时初始值
	TH1 = 0xFF;		//设置定时初始值
	ET1 = 0;		//禁止定时器%d中断
	TR1 = 1;		//定时器1开始计时
	ES = 1;
}
bit busy;

void Uart() interrupt 4
{
    if (RI)
    {
        RI = 0;                 //清除RI位
        
    }
    if (TI)
    {
        TI = 0;                 //清除TI位
        busy = 0;               //清忙标志
    }
}

void SendData(u8 dat)
{
    while (busy);               //等待前面的数据发送完成
    busy = 1;
    SBUF = dat;                 //写数据到UART数据寄存器
}

void SendString(char *s)
{
    while (*s)                  //检测字符串结束标志
    {
        SendData(*s++);         //发送当前字符
    }
}

**********************************************************/
SendData(frq / 10000 + '0');
SendData(frq / 1000 % 10 + '0');
SendData(frq / 100 % 10 + '0');
SendData(frq / 10 % 10 + '0');
SendData(frq % 10 + '0');
SendString("\r\n");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值