DS18B20温度读取总是1,苦思冥想几天不得解,求大神指点~
调试:
1、试过其他人编写的代码,仿真可行
2、在protues 下观察DS18B20的9个字节的RAM发现温度可以转换,放在LSB和MSB位,如当前温度为27℃时,此两位为B0 01;表明指令可以写入。
问题:
调用readonebyte()函数读取不出DS18B20的温度数据,返回全为1。
请大神指点~~~,由衷的感谢!
部分代码如下
//延函数
void delay_B20(uint x)
{
while(x--);
}
//从DS18B20存储器中读入一个字节的数据
uchar readonebyte()
{
uchar i = 8;
uchar ret;
while(i-->0)
{
DQ = 1;
ret >>= 1;
_nop_();
DQ = 0; //拉低DQ口,制造读时序
_nop_();
_nop_();
DQ = 1; //释放DQ口,为读取数据做准备
_nop_();
_nop_();
_nop_();
_nop_();
if(DQ)
ret |=0x80;
delay_B20(10); //延时>60us
DQ = 1;
_nop_();
}
return ret;
}
//温度读取函数
void read_temperature()
{
if(Init_DS18B20() == 1)
B20_ready = 0;
else
{
DQ = 1;
Init_DS18B20();
writeonebyte(0xCC);
writeonebyte(0x44);
delayms(675);
if(Init_DS18B20() == 0)
{
writeonebyte(0xCC);
writeonebyte(0xBE);
temp_value[0] = readonebyte();
temp_value[1] = readonebyte();
B20_ready = 1;
}
}
}
delayms(675);//是不是等待时间不够
应该够的了,我看一了一下DS18B20的内部存储器,最低两个字节存放的温度数据已经完成了温度转换,同时我看了一下,这一条延时语句花了700ms,应该超过了12位精度的最长转换时间。有点费解,我觉得可能问题出在读时序方面
uchar readonebyte()
{
uchar i = 8;
uchar ret = 0;//ret = 0;
while(i-->0)
{
DQ = 1;
ret >>= 1;
_nop_();
DQ = 0; //拉低DQ口,制造读时序
_nop_();//延时改成4us
_nop_();
DQ = 1; //释放DQ口,为读取数据做准备
_nop_();
_nop_();
_nop_();
_nop_();
if(DQ)
ret |=0x80;
delay_B20(10); //延时>60us
}
DQ = 1;
return ret;
}
你试试
嗯嗯,谢谢,我找出问题来了,是在初始化中的一个小细节问题~~~~
我的原来的初始化程序是:uchar Init_DS18B20(){
uchar con; //DS18B20状态
con = 0;
DQ = 1;
_nop_();
DQ = 0;
delay_B20(70); //让DS18B20单数据拉低时间大于480us(延迟645us)
DQ = 1;
delay_B20(8); //获取DS18B20的初始化状态(88us) 满足60 - 240us
con = DQ;
DQ = 1; //采样DQ状态
return con;
}
后来我根据示波器追踪一个个DQ口的输出值,发现在初始化的过程中电平信号不正确,最后发现少了一条延时语句,补上去应该是:
uchar Init_DS18B20()
{
uchar con; //DS18B20状态
con = 0;
DQ = 1;
_nop_();
DQ = 0;
delay_B20(70); //让DS18B20单数据拉低时间大于480us(延迟645us)
DQ = 1;
delay_B20(8); //获取DS18B20的初始化状态(88us) 满足60 - 240us
delay_B20(60);//------------补上此语句,让DS18B20的存在脉冲有足够的时间(>480us)持续,不影响之后对DQ口的操作
con = DQ;
DQ = 1; //采样DQ状态
return con;
}
哈哈,困扰了几天的问题终于解决了,开心开心极了,也很很很感谢你的帮忙,继续努力~~~
厉害!加油
加油,又进步一次了!
修改后的是
uchar Init_DS18B20(){
uchar con; //DS18B20状态
con = 0;
DQ = 1;
_nop_();
DQ = 0;
delay_B20(70); //让DS18B20单数据拉低时间大于480us(延迟645us)
DQ = 1;
delay_B20(8); //获取DS18B20的初始化状态(88us) 满足60 - 240us
con = DQ;
delay_B20(60);//------------补上此语句,让DS18B20的存在脉冲有足够的时间(>480us)持续,不影响之后对DQ口的操作
DQ = 1; //采样DQ状态
return con;
}
之前一激动发错了,嘻嘻
你好,我是一名大一新生,遇到了同样的问题解决不了,请问能把你的完整代码发一下吗
?