//DS18B20温度采样与结果处理参考代码
void Read_Temperature()
{
unsigned char LSB,MSB ;
Init_DS18B20(); //DS18B20复位
Write_DS18B20(0xCC); //跳过ROM操作指令
Write_DS18B20(0x44); //开始温度转换
Delay(1000); //延时700ms左右,等待温度转换完成
Init_DS18B20(); //DS18B20复位
Write_DS18B20(0xCC); //跳过ROM操作指令
Write_DS18B20(0xBE); //开始读取高速暂存器
LSB = Read_DS18B20(); //读取温度数据的低8位
MSB = Read_DS18B20(); //读取温度数据的高8位
Init_DS18B20(); //DS18B20复位,停止暂存器数据读取
T_dat = 0x0000;
T_dat = MSB;
T_dat <<= 8;
T_dat = T_dat | LSB; //将LSB和MSB整合成为一个16位的整数
//首先通过温度数据的高5位判断采用结果是正温度还是负温度
if((T_dat & 0xf800) == 0x0000) //正温度的处理办法
{
T_dat >>= 4; //取出温度结果的整数部分
T_dat = T_dat*10; //放大10倍,然后加上小数部分
T_dat = T_dat + (LSB&0x0f)*0.625;
}
}
小蜜蜂老师关于数据处理的特别注释
这是很多同学和网友向我提出的问题,在这里特别的解释一下。
首先你要知道两个知识点,DS18B20的分辨率是0.0625,并且了解16位温度数据的格式定义。
没有这两个概念,就无法理解为什么温度采样结果要这样处理。
举一个例子来给大家说明这个处理的具体过程:
假设DS18B20的温度采样结果是:LSB = 0x96,MSB = 0x01。
温度数据变量T_dat为16位无符号int整型,初始值为0x0000。
执行T_dat = MSB;语句后, T_dat 的值为:0x0001。
执行T_dat <<= 8;语句后, T_dat 的值为:0x0100。
执行T_dat = T_dat | LSB;语句后, T_dat 的值为:0x0196。
通过高5位的符号扩展位判断,进行正温度的处理算法,正常来说,应该是:
T_dat = 0x0196 × 0.0625 = 406 × 0.0625 = 25.375 摄氏度。
如果要求温度结果保留1位小数,为了简化在单片机中的运算,可以放大10倍进行整型处理:
首先将温度结果的整数部分取出: T_dat >>= 4;即 T_dat = 0x0019 = 25。
然后将整数部分放大10倍: T_dat = T_dat × 10 ;即 T_dat = 250。
然后将小数部分取出: LSB&0x0f,其结果为0x06。
再将小数部分乘以0.0625的10倍,即0x06 × 0.625 = 3.73。
最后将整数部分和小数部分相加: T_dat = 250 + 3.73 = 253。为什么?因为 T_dat 是整型。
对于温度数据253,在数码管显示的时候,在十位出加上一个小数点,就变成了:25.3。
这样可以让单片机避免很多浮点运算,而且数码管显示也会很简洁很方便。
如果要求温度结果只显示整数部分,那就不用这么罗嗦,直接显示整数部分即可:
T_dat >>= 4;即 T_dat = 0x0019 = 25 摄氏度。
其实,在之前的蓝桥杯单片机比赛中,只要求大家显示整数部分而已。