DS18B20 51单片机仿真温度显示每隔8位整数 显示错误

2019-07-15 08:21发布

int tmpget()//获取DS18B20温度{
        int temp;        float tt;
        dsreset();//复位与应答        tmpwritebyte(0xcc);//允许不通过匹配温度计编码直接操作(总线上只有一个DS18B20)        tmpwritebyte(0xbe);//从暂存器中读取数据,第一字节为温度低8位,第二字节为温度高8位        tmp_L8=tmpreadbyte();//读取温度低8位        tmp_H8=tmpreadbyte();//读取温度高8位                temp=tmp_H8;        temp=temp<<8;        temp=temp | tmp_L8;//将高低8位都放入temp中                tt=temp*0.0625;//根据分辨率算出温度        temp=tt*100;        return temp;//将高低8位温度处理后 返回从左往右第三位位为个位        }
void display(int temperature)//LCD温度显示函数{        uchar table_temp[4];        LCD_WRITE_COM(0x80);//从初始位开始显示        if(temperature<0)        {                LCD_WRITE_DATA('-');//负温度显示负                temperature*=-1;//将负温度转为正温度便于显示        }        else                LCD_WRITE_DATA('+');//负温度显示正                table_temp[0]=temperature/10000%10;//温度百位        table_temp[1]=temperature/1000%10;//温度十位        table_temp[2]=temperature/100%10;//温度个位        table_temp[3]=temperature/10%10;//温度小数点后第一位                if(table_temp[0]==0)        {                LCD_WRITE_DATA(' ');                if(table_temp[1]==0)                        LCD_WRITE_DATA(' ');                else                        LCD_WRITE_DATA(table_temp[1]+'0');        }        else        {                LCD_WRITE_DATA(table_temp[0]+'0');                LCD_WRITE_DATA(table_temp[1]+'0');        }
        LCD_WRITE_DATA(table_temp[2]+'0');        LCD_WRITE_DATA('.');        LCD_WRITE_DATA(table_temp[3]+'0');        LCD_WRITE_DATA(0xdf);        LCD_WRITE_DATA('C');}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
12条回答
awellpoint
1楼-- · 2019-07-16 04:54
人中狼 发表于 2018-5-26 14:13
最好还是对比一下读出来的原始数据,再看看有没有例如中断程序等干扰了DS8B20的操作时序

没有加入中断程序
按你说的 将原始数据读出来 发现也是每8个温度错误 算出来也是错的
awellpoint
2楼-- · 2019-07-16 10:53
温度值         读出来合并高低8位        高8位后3位+低8位前5位 为温度整数       
36        00000010 01000000        0100100        正确
37        00000010 01010000        0100101        正确
38        00000010 01100000        0100110        正确
39        00000010 01110000        0100111        正确
40        11111111 10000000        1111000        错误
41        11111111 10010000        1111001        错误
42        11111111 10100000        1111010        错误
43        11111111 10110000        1111011        错误
44        11111111 11000000        1111100        错误
45        11111111 11010000        1111101        错误
46        11111111 11100000        1111110        错误
47        11111111 11110000        1111111        错误
48        00000011 00000000        0110000        正确
49        00000011 00010000        0110001        正确
人中狼
3楼-- · 2019-07-16 16:50
 精彩回答 2  元偷偷看……
awellpoint
4楼-- · 2019-07-16 18:05
人中狼 发表于 2018-5-28 12:58
试试这样,在两个dsreset();后面加一点延时

int temp;

我看datasheet中有讲 如过用寄生电源 需要在初始化后延时480us 外接电源不用 我在dsrest()中加了800us延时

怕转换时间不够 又在dsrest()后加了100ms延时 发现 加不加对结果不影响
看这读出的高低8位 应该是在读出的时候就错了 40多的时候应该高8位的前5位不应该是1的
awellpoint
5楼-- · 2019-07-16 21:48
        int temp;
        char tmp_H8;//高8位温度
        char tmp_L8;//低8位温度
        temp=0x00;
        dsreset();//复位与应答
        tmpwritebyte(0xcc);//允许不通过匹配温度计编码直接操作(总线上只有一个DS18B20)
        tmpwritebyte(0xbe);//从暂存器中读取数据,第一字节为温度低8位,第二字节为温度高8位
        tmp_L8=tmpreadbyte();//读取温度低8位
        tmp_H8=tmpreadbyte();//读取温度高8位
        display_char(tmp_H8,0x80);
        display_char(tmp_L8,0x80+0x40);
        temp=tmp_H8;
        temp<<=8;
        temp|=tmp_L8;//将高低8位都放入temp中
        display_int(temp,0x80);

基本上发现问题了 我在将两个高低位放在一起后 值就变了
display_char 和display_int 出来的两个数不同
awellpoint
6楼-- · 2019-07-16 23:23
人中狼 发表于 2018-5-28 12:58
试试这样,在两个dsreset();后面加一点延时

int temp;

我找出问题了 出在合并两个char为int那里

将A B合并成整形
char a,b;
int num;

num=a;
num<<=8;
num|=b;//错(实际等式 num= num + 0xff00 & b )
num|=(b&0x00ff);//对

一周热门 更多>