上一篇博客的例子中,讲解了用DS18B20读取温度时保留整数部分,现在讲解一下,如何保留小数部分,并在数码管上显示出来。
原来的读取温度的代码:
unsigned char temperature;
unsigned char cnt_temp;
void Read_DS18B20(void)
{
if(cnt_temp>=100) //每0.1s读取一次温度
{
cnt_temp=0;
temperature=(unsigned char)Read_Temperature(); //这里使用强制类型转换,使读到的温度是整数
}
}
修改后的代码如下:(以保留一位小数为例)
程序解释:
1.这里Read_Temperature()读取温度后的数值*10,是为了将数字扩大10倍,从而保留第一位小数。例如:读到的温度为23.5554度,那么*10后得到的值就是235.554,再使用强制类型转换,转换成unsigned int型,保留整数部分。然后再在数码管显示模块时/10就可以得到正确的温度值了
2.temperature这里使用unsigned int是因为unsigned int的取值范围更大(0~65535),而unsigned char的取值范围只有(0~255)。例如:当我读到的温度是30度时,在扩大10倍就超出了unsigned char的取值范围了,这时就会出现问题。
unsigned int temperature;
void Read_DS18B20(void)
{
if(cnt_temp>=100) //每0.1s读取一次温度
{
cnt_temp=0;
temperature=(unsigned int)(Read_Temperature()*10); //
}
}
数码管显示部分:
大家可以参考一下我之前讲的数码管那一篇博文
完整的代码如下:
#include <STC15F2K60S2.H>
#include <intrins.h>
void Timer2_Init(void)
{
AUXR &= 0xFB;
T2L = 0x18;
T2H = 0xFC;
AUXR |= 0x10;
IE2 |= 0x04;
EA = 1;
}
unsigned char smg_code[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //0-9
unsigned char smg_buf[8]; //保存显示在8位数码管的值
unsigned int temperature;
//读取温度函数
void Read_DS18B20(void)
{
if(cnt_temp>=100) //每0.1s读取一次温度
{
cnt_temp=0;
temperature=(unsigned int)(Read_Temperature()*10);
}
}
//数码管读取函数
void SMG_Display()
{
static u8 i=0;
vDevice_Ctrl(0xc0,0);
vDevice_Ctrl(0xe0,~smg_buf[i]);
vDevice_Ctrl(0xc0,0x01<<i);
i=(i+1)%8;
}
//数码管显示函数
void SMG_process()
{
smg_buf[0]=smg_code[temperature/100];
smg_buf[1]=smg_code[temperature/10%10]|0x80;
smg_buf[2]=smg_code[temperature%10];
//这里我们保留一位数字,所以显示前三位即可
}
void main(void)
{
Timer2_Init();
while(1)
{
SMG_Process();
DS18B20_Read();
}
}
void vTimer2_ISR() interrupt 12
{
cnt_temp++;
SMG_Display();
}
注意:
1.要让数码管某位显示小数,在smg_code[位数]后面 |0x80即可
2.因为在读取温度时将温度*10,所以在计算的时候需要 /100,才能得到温度的十位数字,后面的数字同理。