学习笔记
学习科目: |
DS18B20的使用
结合Led1602 |
学习安排: |
改进金沙滩教程中的程序
使温度计能显示小数点后三位
能显示零下温度
最后显示单位 |
开始时间: |
2019-02-08 |
结束时间: |
2019-02-10 |
金沙滩教程里的程序虽然能测量并显示零下温度 但是显示的是错误的,因为对于零上和零下计算算式不一样,零上是可以用测量到的温度乘以0.0625得到实际温度,零下时需要把测量到的值取反减去一在乘以0.0625, 金沙滩的视频里也说了这个测量的是零上的温度,但是要是拿去测量零下的温度看着也是可以的,显示的有符号也很正常,但是多实验几次就发现金沙滩的程序从零上到零下不是连续的 没有零下零点几度,查了资料参看了DS18B20的温度值表,知道了算法,改进了程序,使在零下温度测量使显示的更加准确,最后还要显示温度℃才行,这样一眼就知道这是温度值。
DS18B20的程序基本没变,分享一下主程序吧,里面的加了温度零下时的算式。
[mw_shl_code=cpp,true]
#include <STC12C5A60S2.h>
bit lingxiaflag = 0;
bit flag1s = 0; //1s定时标志
unsigned char T0RH = 0; //T0重载值的高字节
unsigned char T0RL = 0; //T0重载值的低字节
void ConfigTimer0(unsigned int ms);
unsigned char IntToString(unsigned char *str, int dat);
extern bit StartDS();
extern bit GetDSTemp(int *temp);
extern void InitLcd1602();
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
void main()
{
bit res;
int temp; //读取到的当前温度值
int intT, decT; //温度值的整数和小数部分
unsigned char len;
unsigned char str[12];
EA = 1; //开总中断
ConfigTimer0(10); //T0定时10ms
StartDS(); //启动DS18B20
InitLcd1602(); //初始化液晶
while (1)
{
if (flag1s) //每秒更新一次温度
{
flag1s = 0;
res = GetDSTemp(&temp); //读取当前温度
if (res) //读取成功时,刷新当前温度显示
{
intT = temp >> 4; //分离出温度值整数部分
decT = temp & 0xF; //分离出温度值小数部分
len = IntToString(str, intT); //整数部分转换为字符串
str[len++] = '.'; //添加小数点
if(lingxiaflag == 1)
{
decT = decT | 0xfff0;
decT = ~decT;
decT = decT * 625 /10;
}
else
{
decT = (decT*1000) / 16; //二进制的小数部分转换为十进制位
}
str[len++] = decT/100%10 + '0'; //十进制小数位再转换为ASCII字符
str[len++] = decT/10%10 + '0';
str[len++] = decT%10 + '0';
str[len++] = 0xdf; //加上 ℃
str[len++] = 'C';
while (len < 6) //用空格补齐到6个字符长度
{
str[len++] = ' ';
}
str[len] = '\0'; //添加字符串结束符
lingxiaflag = 0;
LcdShowStr(0, 0, str); //显示到液晶屏上
}
else //读取失败时,提示错误信息
{
LcdShowStr(0, 0, "error!");
}
StartDS(); //重新启动下一次转换
}
}
}
/* 整型数转换为字符串,str-字符串指针,dat-待转换数,返回值-字符串长度 */
unsigned char IntToString(unsigned char *str, int dat)
{
signed char i = 0;
unsigned char len = 0;
unsigned char buf[6];
if (lingxiaflag == 1) //如果为负数,首先取绝对值,并在指针上添加负号
{
dat = ~dat;
*str++ = '-'; //显示符号表示零下温度
len++;
//lingxiaflag = 0;
}
do { //先转换为低位在前的十进制数组
buf[i++] = dat % 10;
dat /= 10;
} while (dat > 0);
len += i; //i最后的值就是有效字符的个数
while (i-- > 0) //将数组值转换为ASCII码反向拷贝到接收指针上
{
*str++ = buf + '0';
}
*str = '\0'; //添加字符串结束符
return len; //返回字符串长度
}
/* 配置并启动T0,ms-T0定时时间 */
void ConfigTimer0(unsigned int ms)
{
unsigned long tmp; //临时变量
tmp = 33177600 / 12; //定时器计数频率
tmp = (tmp * ms) / 1000; //计算所需的计数值
tmp = 65536 - tmp; //计算定时器重载值
tmp = tmp + 12; //补偿中断响应延时造成的误差
T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
T0RL = (unsigned char)tmp;
TMOD &= 0xF0; //清零T0的控制位
TMOD |= 0x01; //配置T0为模式1
TH0 = T0RH; //加载T0重载值
TL0 = T0RL;
ET0 = 1; //使能T0中断
TR0 = 1; //启动T0
}
/* T0中断服务函数,完成1秒定时 */
void InterruptTimer0() interrupt 1
{
static unsigned char tmr1s = 0;
TH0 = T0RH; //重新加载重载值
TL0 = T0RL;
tmr1s++;
if (tmr1s >= 100) //定时1s
{
tmr1s = 0;
flag1s = 1;
}
}
[/mw_shl_code]
这几天温度比较低,同学们注意保暖哦。
|
|