51单片机定时器和DS18B20共存出乱码现象

项目场景:

当我们在学习51单片机的时候,有一部分的题目需要时间和温度数据同时存在,而使用51单片机产生时钟数据的最常用手段为定时器中断和使用DS1302时钟芯片。

问题描述:

定时器中断在实际应用中容易出现温度的读取数据出现乱码,影响了对温度的采集可靠性。 在下图中是DS18B20读取温度数据的部分函数以及部分定时器中断函数。
void Ds18b20WriteByte(u8 dat)//写入一个字节
{
	u16 i, j;

	for(j=0; j<8; j++)
	{
		DSPORT = 0;	     	  
		i++;
		DSPORT = dat & 0x01; 
		i=6;
		while(i--);//延时68us,至少为60us
		DSPORT = 1;	
		dat >>= 1;
	}
}

u8 Ds18b20ReadByte()//读取一个字节
{
	u8 byte, bi;
	u16 i, j;	
	for(j=8; j>0; j--)
	{
		DSPORT = 0;
		i++;
		DSPORT = 1;
		i++;
		i++;//延时6us等待数据稳定
		bi = DSPORT;	
		byte = (byte >> 1) | (bi << 7);						  
		i = 4;//等待48us后读取下一个数
		while(i--);
	}				
	return byte;
}

void Timer0_Init() //定时器中断函数
{
   TMOD = 0x01;
    TH0 = 0xFF;
    TL0 = 0x9C;
    EA = 1;//打开总中断
    ET0 = 1;
    TR0 = 1;
}

原因分析:

在图中可以看到在定时器中断里使用的是100us的初始值,在此时温度读取的数据在LCD1602上显示会出现乱码,原因在定时器的中断打断了温度的传输等待时间,使数据传输不完整。

解决方案:

解决的方案是在进行DS18B20温度数据读写的进程前关闭总中断,也就是令EA=0;在温度数据读写进程完成之后在打开总中断,需要注意的是,这种操作会影响定时的精确度,因为这样会有一段定时器中断无法产生时钟数据的空白期。所以如果采用这种方式,建议降低对温度读写函数的调用频率。(本文中采用的DS18B20驱动引自普中科技官方例程,只为分享解决bug的经验)
int Ds18b20ReadTemp()
{
	int temp = 0;
	
	uchar tmh, tml;
	EA=0;//关闭总中断
	Ds18b20ChangTemp();			 	
	Ds18b20ReadTempCom();			
	tml = Ds18b20ReadByte();		
	tmh = Ds18b20ReadByte();		
	temp <<= 8;
	temp |= tml;
	EA=1;//打开总中断
	return temp;
}
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值