再谈DS18B20驱动程序--工作电压为3.3V
之前讨论过DS18B20的驱动,都是工作在5V电压下的,经过改良过的程序,直接移过来就可以用,不需要再调时序。由于项目需要,这次用的DS18B20的工作电压是3.3V,程序移过去之后运行,取得的温度值一直都是16,改变外界环境时,这个值也不会变,这肯定是不正常的。
网上也有人遇到类似的情况,解决办法无非就是换上拉电阻值,或是直接把工作电压改成5V,然后数据口直接与单片机相连。我测试的情况是,换上拉电阻没有任何作用,改电压的有点反应,就是器件时不时会取85这个值,也就是说取到值在85或16跳动,更多时候取出来的值是16。
想到低电压的抗干扰能力弱一些,时序上做些调整应该会好一点。于是把电路改回3.3V,然后对初始化及数据读写部分中用到_nop_()函数的部分进行统一修改,用固定的延时函数(5us)来取代,测试结果完成正确。以下为修改过的代码(主要修改部分就是DQ从高变低期间的延时):
/**************复位***********************/
unsigned char DS1B20Init(void)
{
unsigned char i;
DQ=1;
Delay5us_xn(1);
DQ=0;
Delay5us_xn(96); //延时480us
DQ=1;
Delay5us_xn(12); //延时60us
i=0;
while(DQ) //在480us内检测DQ是否变为低,如果为低则复位成功,否则复位不成功
{
Delay5us();
i++;
if(i>96)
{
i=255;
break;
}
}
if(i==255)
return 0; //初始化失败
while(!DQ); //等待DS18B20释放总线
return 1; //初始化成功
}
/**********写一个字节数据到DS18B20***********/
void WriteDat(unsigned char dat)
{
unsigned char i;
for (i=8; i>0; i--) //
{
DQ=1;
Delay5us_xn(1);
DQ=0;
Delay5us();
DQ=dat&0x01; //最低位移出
Delay5us_xn(13);
dat=dat>>1; //右移一位
}
DQ=1;
Delay5us_xn(2);
}
/**********读一个字节数据从DS18B20***********/
unsigned char ReadDat(void)
{
unsigned char dat,i;
for (i=8;i>0;i--)
{
DQ=1;
Delay5us_xn(1);
dat>>=1;
DQ=0; //
Delay5us_xn(1);
DQ=1;
Delay5us_xn(1);
if(DQ)
dat|=0x80;
Delay5us_xn(13);
}
DQ=1;
return(dat);
}至此,问题完美解决。再次提醒我们,涉及到时序操作的器件驱动,为了保证良好的可移植性,务必选用固定的延时函数来完成时序控制。以下为改良后的DS18B20的完整驱动程序。
http://pan.baidu.com/s/1mhN2DMK
凯特网版权声明:以上内容允许转载,但请注明出处,谢谢!
