//温度值小数部分对照表
code uchar table_tempfh[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
//读取DS18B20当前温度
void read_temp(void)
{
uchar a=0;
uchar b=0;
//DS18B20默认为12位精度
ds18b20_init();
ds18b20w_byte(0xCC); // 跳过读序号列号的操作
ds18b20w_byte(0x44); // 启动温度转换
delayus(100); // 等待足够长时间以读取温度值
ds18b20_init();
ds18b20w_byte(0xCC);
ds18b20w_byte(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
delayus(100);
a=ds18b20r_byte(); //读取温度值低位
b=ds18b20r_byte(); //读取温度值高位
tempvalue=b<<4; //转化成字节温度
tempvalue+=(a&0xf0)>>4; //整数部分
tempvalue_fh=table_tempfh[a&0x0f]; //小数部分(查表对照,获取小数位)
}
上面的程序采用12位精度,查阅18B20手册,LSB的最低四位代表小数,MSB的最高5位为符号位,其余的7位为整数部分,其分辨率为0.0625°,根据此规律,整数就是两字节凑在一起,而小数部分则是最低四位的值,乘以0.0625,看你取几位小数,再取整即可。上述的对照表是取1位小数的结果,取四舍五入。比如现在LSB的最低四位是0111,那么小数部分就是0.0625*7=0.4375,如果取1位小数,就是“4”,两位小数就是“44”..依次类推。
假如读出的数值是:0000 0000 1111 1111,那么该值的前五位表示温度的符号,0000 0表示正温度,1111 1表示负温度,然后将值乘以0.0625,那么得出的值就是温度的实际值。后9位000 1111 1111为256,256乘0.0625=?就是实际温度值。
很简单,两次读出16位数,把它当成一个数来看。
其高5位是相同的,代表符号。
后面11位,是温度的二进制数,7位整数、4位小数。
就是这些,就是这么简单。
有很多程序,是故弄玄虚。