單片機(jī) 測溫芯片 18B20 是一款常用的IC,優(yōu)勢特點(diǎn)不多說,這里主要討論溫度值的處理,尤其是負(fù)溫度。
18B20片內(nèi)有一個(gè)9Byte的 SRAM 和一個(gè)3Byte的 EEPROM。如下圖:
其中我們需要使用的就是SRAM中的前兩個(gè)字節(jié),這里儲(chǔ)存的就是我們要的溫度值。這兩個(gè)字節(jié)的結(jié)構(gòu)如下:
我們可以看到,LS(低字節(jié))的高四位 和 MS(高字節(jié))的低四位共8個(gè)字節(jié)構(gòu)成了實(shí)際的一個(gè)帶符號(hào)位的字節(jié)數(shù)據(jù)可以表示(-128~127)足夠表示18B20的溫度范圍。MS的高四位為符號(hào)為的擴(kuò)展,當(dāng)溫度值為正時(shí)MS高5位(圖中S的五位)全為0,溫度值為負(fù)時(shí)全為1。LS的低四位為小數(shù)部分,不是要求太高的話可以忽略。我們這里暫不套路小數(shù)部分的處理方法。
下面我們就來討論整數(shù)部分的數(shù)據(jù)處理方法。
整數(shù)部分我們實(shí)際只要高字節(jié)的第四位和低字節(jié)的高四位。首先通過移位求或后生成一個(gè)無符號(hào)位的字節(jié)。然后判斷這個(gè)無符號(hào)的值是否大于127,如果大于128說明是個(gè)負(fù)溫度需要處理,否則就可以直接返回。
18B20的負(fù)溫度使用補(bǔ)碼形式輸出,我們只需要對(duì)這個(gè)字節(jié)進(jìn)行取反加1后就是這個(gè)負(fù)溫度的絕對(duì)值,這時(shí)候我們需要一個(gè)符號(hào)標(biāo)記告訴輸出函數(shù)這是個(gè)負(fù)溫度需要顯示負(fù)號(hào)即可。
下面貼出數(shù)據(jù)處理部分的代碼:
uchar readtemp() //讀取溫度
{
uchar temp = 0;
uchar tmp[2]
reset();
writebyte(0xCC); // 跳過序列號(hào)
writebyte(0x44); // 啟動(dòng)溫度轉(zhuǎn)換
delayms(1000);
reset();
writebyte(0xCC);
writebyte(0xBE); //讀9個(gè)寄存器,前兩個(gè)為溫度
tmp[0]=readbyte(); //低位
tmp[1]=readbyte(); //高位
temp = ((tmp[1]《《4)&0xF0)|((tmp[0]》》4)&0x0F);
if(temp》127)
{
temp = ~temp + 1;
}
return (temp);
}
如何用51單片機(jī)讀取ds18b20的取負(fù)溫度?
18b20的ram中,前兩個(gè)字節(jié)放的是溫度信息。其中第二個(gè)字節(jié)的高五位是符號(hào)位,當(dāng)溫度為正的時(shí)候,高五位的字節(jié)是0,當(dāng)溫度為負(fù)的時(shí)候,高五位字節(jié)為一。當(dāng)溫度為正的時(shí)候,只需要將兩個(gè)字節(jié)的數(shù)合到一個(gè)字節(jié),然后乘以0.0625就是實(shí)際的溫度。
那么,當(dāng)溫度為負(fù)的時(shí)候,該怎么讀取溫度呢?是將兩個(gè)字節(jié)合為一個(gè)字節(jié),然后先取反,再加一,最后再和0.0625相乘嗎?這樣得出的結(jié)果就是實(shí)際的負(fù)溫度值嗎?
判斷是否是負(fù),就是取高幾位的讀取值采用與的方式判斷,比如(000) 11111 00001000,那么高5位可以這樣弄,tempH&0x1f,如果這個(gè)值=1;說明是負(fù)的,否則就是正的啊,不過有一點(diǎn),取反是對(duì)的,還要加1啊,記得哦。
至于在LCD中顯示的,確實(shí)是按你說的那樣,直接寫上一個(gè)符號(hào)即可。
DS18b20 輸出的負(fù)溫度數(shù)據(jù)是定點(diǎn)補(bǔ)碼(小數(shù)點(diǎn)后固定二進(jìn)制四位),符號(hào)可由最高位判定(0為正,1為負(fù))。若是負(fù)數(shù),則求其補(bǔ)碼即可,具體為“取反加一”或 0x10000 - T (T為度出來的補(bǔ)碼)。
把讀出來的數(shù)temperaturebuffer定義成16位的帶符號(hào)整形,進(jìn)行帶符號(hào)的移位,直接轉(zhuǎn)成浮點(diǎn)數(shù),正負(fù)號(hào)就在里面了,用下面的表達(dá)式,你不用判斷正負(fù)。
((float)(temperaturebuffer》》4))+((temperaturebuffer&0x0F)/16.0)
其內(nèi)有兩個(gè)溫度上下限寄存器TH和TL,所采溫度若超過此溫度范圍后會(huì)置相應(yīng)的報(bào)警標(biāo)志位。至于那個(gè)校驗(yàn),是CRC-8,這并不太復(fù)雜,可以找些相關(guān)資料了解一下便知。