|
5黑幣
大佬們幫我看一下這個DS18B20溫度顯示在LCD屏上負數部分顯示的溫度與實際溫度誤差太大,這是哪了除了問題,應該怎么修改呢,正數部分顯示正常,主程序部分的程序void main()
{
bit res;
int temp; //讀取到的當前溫度值
int intT, decT; //溫度值的整數和小數部分
unsigned char len;
unsigned char str[12];
EA = 1; //開總中斷
ConfigTimer0(10); //T0 定時 10ms
Start18B20(); //啟動 DS18B20
InitLcd1602(); //初始化液晶
LcdStar();
while (1)
{
if (flag1s) //每秒更新一次溫度
{
flag1s = 0;
res = Get18B20Temp(&temp); //讀取當前溫度
if (res) //讀取成功時,刷新當前溫度顯示
{
intT = temp >> 4; //分離出溫度值整數部分
decT = temp & 0xF; //分離出溫度值小數部分
len = IntToString(str, intT); //整數部分轉換為字符串
str[len++] = '.'; //添加小數點
decT = (decT*10) / 16; //二進制的小數部分轉換為 1 位十進制位
str[len++] = decT + '0'; //十進制小數位再轉換為 ASCII 字符
while (len < 6) //用空格補齊到 6 個字符長度
{
str[len++] = ' ';
}
str[len] = '\0'; //添加字符串結束符
LcdShowStr(9, 1, str); //顯示到液晶屏上
LcdShowStr(14, 1, "C");//添加C溫度
}
else //讀取失敗時,提示錯誤信息
{
LcdShowStr(0, 0, "error!");
}
Start18B20(); //重新啟動下一次轉換
}
}
}
/* 整型數轉換為字符串, str-字符串指針, dat-待轉換數,返回值-字符串長度 */
unsigned char IntToString(unsigned char *str, int dat)
{
signed char i = 0;
unsigned char len = 0;
unsigned char buf[6];
if (dat < 0) //如果為負數,首先取絕對值,并在指針上添加負號
{
dat = -dat;
*str++ = '-';
len++;
}
do { //先轉換為低位在前的十進制數組
buf[i++] = dat % 10;
dat /= 10;
} while (dat > 0);
len += i; //i 最后的值就是有效字符的個數
while (i-- > 0) //將數組值轉換為 ASCII 碼反向拷貝到接收指針上
{
*str++ = buf[ i] + '0';
}
*str = '\0'; //添加字符串結束符
return len; //返回字符串長度
}
/* 配置并啟動 T0, ms-T0 定時時間 */
void ConfigTimer0(unsigned int ms)
{
unsigned long tmp; //臨時變量
tmp = 11059200 / 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;
}
}
圖片1.png (9.62 KB, 下載次數: 74)
下載附件
2021-5-26 09:50 上傳
|
|