标题: 这是ds18b20部分的代码,lcd显示总是几千的数值,请有心人指正!!!谢谢!!! [打印本页]

作者: 不好不坏    时间: 2019-4-5 10:42
标题: 这是ds18b20部分的代码,lcd显示总是几千的数值,请有心人指正!!!谢谢!!!
本帖最后由 不好不坏 于 2019-4-5 11:10 编辑

void init_ds18b20()
{
        u8 i;
        bit flag;
        do
        {
        dq=1;
        _nop_();
        dq=0;
        i=103;
        while(i>0)i--;//延时
        dq=1;
        flag=dq;
        i=4;
        while(i>0)i--;
        }while(flag);
}
bit read_onebit()
{
                u8 i;
                u8 onebit;
                dq=0;
                i++;
                dq=1;
                i++;
                onebit=dq;
                i=8;while(i>0)i--;//延时
        return onebit;
}
u8 read_onebyte()
{
        u8 dat=0,a,k;
        for(a=0;a<8;a++)
        {
        k=read_onebit();
        dat=(k<<7)|(dat>>1);//循环把读到的低位放在低位
        }
        return dat;
}
void write_onebyte(u8 dat)
{
        u8 d=0,i;        
        bit testbit;
        for(d=8;d>0;d--)
        {
                dq=dat&0x01;                //从dat最低位开始传送
                dat>>=1;                                //移除已经传送的最低位
                if(testbit==1)                //写1
                {
                        dq=0;
                        _nop_();        
                        _nop_();
                        dq=1;
                        i=8;while(i>0)i--;//延时
                }
                else                        //写0
                {
                        dq=1;
                        i=8;while(i>0)i--;
                        dq=0;
                        i++;i++;
                }
        }
}
float get_temp()
{
        u8 a,b;
        u16 temp;float tmp;
        init_ds18b20();                //初始化
        write_onebyte(0xcc);        //忽略ROM指令
        write_onebyte(0x64);
        delay_ms(10);

        init_ds18b20();                        //再度初始化
        write_onebyte(0xcc);        //忽略ROM指令
        write_onebyte(0x00);
        delay_ms(10);

        init_ds18b20();                //初始化
        write_onebyte(0xcc);        //忽略ROM指令
        write_onebyte(0x44);        //温度转换指令+
        delay_ms(800);

        init_ds18b20();                //初始化
        write_onebyte(0xcc);        //忽略ROM指令
        write_onebyte(0xbe);        //读暂存器指令


        a=read_onebyte();                //第一个字节是LSB,低八位
        b=read_onebyte();                //第二个字节是MSB,高八位
        temp=b;                                        //先把高八位b装进temp,一定是进入到temp低八位
        temp<<=8;                                //左移8次;让B回到原位
        temp|=a;                                        //再和A相加,
        tmp=(float)(temp*0.0625);
        return tmp;
}


psb.jpg (121.01 KB, 下载次数: 97)

psb.jpg

作者: wulin    时间: 2019-4-5 13:22
对比一下就知道问题在哪里 ds18b20温度LCD显示.zip (159.01 KB, 下载次数: 34)

作者: HC6800-ES-V2.0    时间: 2019-4-5 13:37
18B20是12位精度的话:
正数这样转换:temp=tp*0.0625*100+0.5;//tp是有符号实数型变量,就是读到的温度值,这个计算保留两位小数

负数这样转换:tp=tp-1;
                      tp=~tp;
                      temp=tp*0.0625*100+0.5;

作者: 不好不坏    时间: 2019-4-5 18:17
wulin 发表于 2019-4-5 13:22
对比一下就知道问题在哪里

完全套用你的程序,显示出负的温度,而且整数位还在跳动,不知缘故
作者: 不好不坏    时间: 2019-4-5 18:18
HC6800-ES-V2.0 发表于 2019-4-5 13:37
18B20是12位精度的话:
正数这样转换:temp=tp*0.0625*100+0.5;//tp是有符号实数型变量,就是读到的温度值 ...

试过了,还是不正常

作者: wulin    时间: 2019-4-6 07:03
不好不坏 发表于 2019-4-5 18:17
完全套用你的程序,显示出负的温度,而且整数位还在跳动,不知缘故

软件是建立在硬件基础上的,硬件条件不同不要直接套用,否则会出错。
作者: 1577721710    时间: 2021-5-26 09:57
大佬们看看我的那个温度显示,负数部分异常怎么改呢

作者: 名字不是重点    时间: 2021-5-26 10:08
其实这类问题,你能在线跟踪一下代码,很容易发现问题的。
1、读写时序对不对?
2、数值转换对不对?
3、显示传参对不对?
18B20的代码还是很友善的,不行的话就多下载一些人家现成的代码来改。
作者: 名字不是重点    时间: 2021-5-26 10:15
bit read_onebit()
{
                u8 i;
                u8 onebit;
                dq=0;
                i++;
                dq=1;
                i++;
                onebit=dq; ///????
                i=8;while(i>0)i--;//延时
        return onebit;////onebit永远是1,
}
也就是说你读出的数值都是1 ,12位刚好是4096,与你显示的一致?





欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1