单片机 C51中关于18B20读出数据的处理

来源:百度知道 编辑:UC知道 时间:2024/05/13 06:51:33
下面是源程序中的一段,没看懂在读出两个字节的数据后是怎么处理的,
t = b; t <<= 8; t = t | a;
t <<= 8;这不是把t左移8位,这样t不就等于0了吗?这三句不是相当于 t=a;?

void Read_Display(void)//读取并显示温度
{
unsigned int a = 0, b = 0, c = 0, t = 0;
unsigned char i;
float tt = 0;

Init_18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换

Init_18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器

a = ReadOneChar();
b = ReadOneChar();

t = b;
t <<= 8;
t = t | a;

tt = t * 0.0625;
t = tt * 10 + 0.5; //放大10倍输出并四舍五入

a = t / 100; //十位
b = t / 10 - a * 10; //个位
c = t - a * 100 - b * 10; //小数位

Write_Comm(0x01);//清显示
Write_Comm(0x80);//写首地址
for(i=0;i<16;i++)
{
Write_Data( Temp[i] );//显示Temperature:字样
}
Write_Comm(0xc5);
Write_Data( num[a] );

t = b; t <<= 8; t = t | a;
这三句话相当于:t=b<<8+a; 由于a,b,t都是unsigned int 型,也就是16位的 ,这样是可以的。其目的就是将两个温度值寄存器合成一个,方便处理。

上面的程序采用的是12位精度的,此时最小分辨率为0.0625°。下面是是温度操作过程 ,我在旁边帮你注释了。

a = ReadOneChar(); //读取LSB,温度值低位字节
b = ReadOneChar(); //读取MSB,温度值高位字节

t = b;
t <<= 8;
t = t | a; //最终结果是t = b*(2^8) + a;

tt = t * 0.0625; //总的温度值,分辨率是0.0625
t = tt * 10 + 0.5; //放大10倍输出并四舍五入

a = t / 100; //十位
b = t / 10 - a * 10; //个位
c = t - a * 100 - b * 10; //小数位

小数会有一定的误差,最好用查找表的方式,可取多位小数更准确。

与18B20中的数据格式有关。

a = ReadOneChar();
b = ReadOneChar();

两次读出的,分别是高八位和低8位,
t = b;
t <<= 8;
t = t | a;
合成为一个16位数。这些步骤是正确的。
后面是数据处理、显示过程,小数的处理方式,有些草率。

tt = t * 0.0625;
t = tt * 10 + 0.5; //放大10倍输出并四舍五入

a = t / 100; //十位
b = t / 10 - a * 10; //个位
c = t