微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > DS18B20温度读取总是1,苦思冥想几天不得解,求大神指点~

DS18B20温度读取总是1,苦思冥想几天不得解,求大神指点~

时间:10-02 整理:3721RD 点击:
在protues下仿真12MHZ的AT89C51单片机出现DS18B20温度读取总是1,即在readonebyte()函数中ret为全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;
}
之前一激动发错了,嘻嘻

你好,我是一名大一新生,遇到了同样的问题解决不了,请问能把你的完整代码发一下吗
?

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top