您好,歡迎來(lái)電子發(fā)燒友網(wǎng)! ,新用戶?[免費(fèi)注冊(cè)]

您的位置:電子發(fā)燒友網(wǎng)>電子元器件>傳感器>

DS18B20的調(diào)試總結(jié)和程序 - 全文

2018年01月05日 08:57 網(wǎng)絡(luò)整理 作者: 用戶評(píng)論(0
關(guān)鍵字:DS18B20(79745)

DS18B20簡(jiǎn)介

DS18B20是常用的數(shù)字溫度傳感器,具有體積小,硬件開(kāi)銷低,抗干擾能力強(qiáng),精度高的特點(diǎn)。 DS18B20數(shù)字溫度傳感器接線方便,封裝成后可應(yīng)用于多種場(chǎng)合,如管道式,螺紋式,磁鐵吸附式,不銹鋼封裝式,型號(hào)多種多樣,有LTM8877,LTM8874等等。

主要根據(jù)應(yīng)用場(chǎng)合的不同而改變其外觀。封裝后的DS18B20可用于電纜溝測(cè)溫,高爐水循環(huán)測(cè)溫,鍋爐測(cè)溫,機(jī)房測(cè)溫,農(nóng)業(yè)大棚測(cè)溫,潔凈室測(cè)溫,彈藥庫(kù)測(cè)溫等各種非極限溫度場(chǎng)合。耐磨耐碰,體積小,使用方便,封裝形式多樣,適用于各種狹小空間設(shè)備數(shù)字測(cè)溫和控制領(lǐng)域。

單個(gè)18B20實(shí)現(xiàn)溫度測(cè)試步驟

該文檔所用程序?yàn)镕REESCALE JM60單片機(jī),總線時(shí)鐘為8M,若要移植到其它MCU上,需要將時(shí)間重新調(diào)節(jié),或者更改總線時(shí)鐘頻率的輸出;

DS18B20的調(diào)試總結(jié)和程序

電路圖

DS18B20的調(diào)試總結(jié)和程序

DS18B20工作協(xié)議:初始化,存儲(chǔ)器操作命令,處理數(shù)據(jù);

DS18B20的調(diào)試總結(jié)和程序

在關(guān)于時(shí)序的編寫(xiě)中,for循環(huán)中的NOP指令,和單獨(dú)調(diào)用的NOP指令所用時(shí)間完全不同;NOP占用1/總線時(shí)

鐘的時(shí)間;如JM60的總線時(shí)鐘為8M,則NOP指令一定占用0.125US,而將NOP放在FOR循環(huán)中,由于FOR的判斷指令,加法指令,以及轉(zhuǎn)子程序等等消耗的時(shí)間很長(zhǎng),遠(yuǎn)遠(yuǎn)大于一個(gè)NOP的指令,此時(shí),若要獲得執(zhí)行代碼的精確時(shí)間,最好用示波器觀察,再得出最直接的結(jié)果;

在單片機(jī)的使用中,不要用浮點(diǎn)數(shù),全部用整數(shù)代替,在數(shù)據(jù)進(jìn)行移位作乘法時(shí),一定要注意數(shù)據(jù)有沒(méi)有越界,算出來(lái)的數(shù)很容易出現(xiàn)錯(cuò)誤,并且在出現(xiàn)浮點(diǎn)數(shù)時(shí),可以將數(shù)據(jù)放大到一定的精度,然后在顯示時(shí),將小數(shù)點(diǎn)移到對(duì)應(yīng)的位置即可;

在數(shù)據(jù)做乘法容易越界時(shí),一般將其賦給一個(gè)字節(jié)多的整數(shù),作為中間變量運(yùn)算,在確保數(shù)據(jù)不會(huì)越界后,再將其賦給最后結(jié)果;

初始化時(shí)序

DS18B20的調(diào)試總結(jié)和程序

初始化時(shí)序步驟:

1. 主機(jī)將端口設(shè)為輸出,先發(fā)送一個(gè)高電平,然后再拉低,維持480-960US;(推薦500-600US)

2. 主機(jī)將端口設(shè)為輸入,上拉電阻此時(shí)將電平拉高,主機(jī)等待60US-200US;(推薦100-150US)

3. 主機(jī)讀取端口數(shù)據(jù),低電平則初始化成功;高電平表示初始化失敗;

4.讀取數(shù)據(jù)完畢后,主機(jī)等待至少400US; (推薦450-500US)

注:

l 第四步很重要,讀取初始化狀態(tài)后,仍然延時(shí)400US才可以初始化完畢,否則傳感器不能正常使用;

l 在這里注意端口需要不停地改變方向;在主機(jī)發(fā)送時(shí),設(shè)為輸出,主機(jī)接收時(shí),設(shè)為輸出;

/*****************18B20的初始化程序***************************/

byte INIT_18B20() {

byte DQ_RETURN=2;

DQ_OUT=1; //引腳設(shè)置為輸出

DQ=1;

DELAY1(); //稍微延時(shí),即可

DQ=0; //將電平拉低至少480uS,最大為960US

DELAY9(70);

DQ_OUT=0;

//設(shè)置為輸入,設(shè)為輸入15到60US

DELAY9(6); //等待18B20響應(yīng),如果為低電平表示初始化成功,維持60到240 //微秒

DQ_RETURN=DQ;

DELAY9(70); //讀完數(shù)據(jù)后,仍然延時(shí),至少480US

return(DQ_RETURN); //返回值為1,表示失敗,返回值為0表示成功

}

端口寫(xiě)數(shù)據(jù)時(shí)序

DS18B20的調(diào)試總結(jié)和程序

1. 主機(jī)將電平拉高,稍微延時(shí)(推薦值:2US),然后拉低電平,產(chǎn)生一個(gè)下降沿,表示寫(xiě)數(shù)據(jù)開(kāi)始;低電平維持至少1US;(此時(shí)推薦2US)

2. 此時(shí),將要寫(xiě)的1或0放在數(shù)據(jù)線上;(從寫(xiě)數(shù)據(jù)第一步開(kāi)始到現(xiàn)在,整個(gè)過(guò)程在15US之內(nèi)完成;

3. 然后主機(jī)延時(shí)等待至少50US;(推薦60US)

4. 主機(jī)最后將電平拉高;

5. 每寫(xiě)兩位數(shù)據(jù)之間的間隔要大于1US;

注:

l 在寫(xiě)步驟中,整個(gè)過(guò)程端口方向均為輸出;

這里對(duì)時(shí)序要求高,最好用示波器調(diào)整出精確的時(shí)序;

/*****************向18B20寫(xiě)數(shù)據(jù)********************************/

void WRITE_18B20(unsigned char ch){

byte i;

for(i=0;i《8;i++) {

DQ_OUT=1; //端口設(shè)為輸出,并給個(gè)拉低電平的下降沿

DQ=1;

DELAY1();

DQ=0; //拉低電平,并維持一微秒以上,表示要發(fā)送數(shù)據(jù)

DELAY1();

DELAY1();

//在15US內(nèi)將要寫(xiě)的電平寫(xiě)在線上

if((ch&0x01)==1) //將數(shù)據(jù)按位取出,從LSB到MSB依次送出

DQ=1;

else

DQ=0;

ch=ch》》1;

DELAY9(8); //電平維持40US以上,18B20將在此時(shí)將數(shù)取出

DQ=1;

}

DQ=1; //最后將電平重新拉高

}

讀數(shù)據(jù)時(shí)序

DS18B20的調(diào)試總結(jié)和程序

1. 主機(jī)將電平拉高,稍微延時(shí)(推薦2US),然后將電平拉低,產(chǎn)生一個(gè)下降沿,表示讀數(shù)據(jù);這個(gè)低電平至少維持1US,此處推薦2US;

2. 將端口方向設(shè)為輸入,必須在下降沿之后的15US內(nèi)將端口數(shù)據(jù)讀?。淮颂幫扑]端口方向設(shè)為輸入后,延時(shí)5US,讀取端口數(shù)據(jù);

3. 讀取數(shù)據(jù)完畢后,延時(shí)60US即可;

4. 每?jī)蓚€(gè)數(shù)據(jù)位之間間隔大于1US;

注:

在這個(gè)時(shí)序內(nèi),要不斷改變端口方向;

如果上拉電阻阻值合理設(shè)置,可以小于4.7K歐姆,利于提高時(shí)序速度; l

讀數(shù)據(jù)和寫(xiě)數(shù)據(jù)都是8位,從LSB開(kāi)始發(fā)送;

/***************從18B20取出字符*******************************/

byte READ_18B20(){

byte ch=0;

byte i;

for(i=0;i《8;i++){

DQ_OUT=1; //端口輸出

DQ=1;

DELAY1(); //產(chǎn)生下降沿,至少維持一微秒

DQ=0;

DELAY1(); //將端口設(shè)為輸入,等待讀取

DQ_OUT=0; //在15US之內(nèi)讀取數(shù)據(jù)

ch=ch》》1;

//延時(shí)大概5US

DELAY5();

if(DQ)

ch=ch|0x80;

else

ch=ch&0x7f;

DELAY9(8);

//每?jī)蓚€(gè)讀數(shù)據(jù)之間間隔要大于60US }

return(ch); //返回讀到的數(shù)據(jù)

}

以上三段為底層基本函數(shù);DELAY后面的數(shù)字DELAY1,DELAY5,DELAY9為延時(shí)的微秒時(shí)長(zhǎng); DQ設(shè)置為硬件連接的端口,DQ_OUT為端口方向的設(shè)置

然后就是調(diào)用函數(shù)了:

當(dāng)數(shù)據(jù)線上還有一個(gè)18B20時(shí),通常步驟如下:

初始化;

跳過(guò)ROM;

溫度開(kāi)始轉(zhuǎn)換命令;

等待溫度轉(zhuǎn)換完成;//當(dāng)使用18B20默認(rèn)的12位轉(zhuǎn)換精度,用時(shí)750MS,經(jīng)檢驗(yàn),一般耗時(shí)比理論稍長(zhǎng);

初始化;

跳過(guò)ROM;

讀暫存器命令;

將溫度數(shù)據(jù)低八位,高八位依次取出;

初始化;//注:最后仍然要進(jìn)行初始化

結(jié)束;

對(duì)應(yīng)的函數(shù)如下

/********************溫度開(kāi)始轉(zhuǎn)換命令程序*******************************/

byte TEMP_DETECT_18B20(){

byte dummy=2;

dummy=INIT_18B20(); //初始化

if(dummy==0){

WRITE_18B20(0XCC); //跳過(guò)ROM,不讀地址,直接通訊

WRITE_18B20(0x44); //溫度開(kāi)始轉(zhuǎn)換命令

}

return(dummy); //返回0表示成功初始化,開(kāi)始轉(zhuǎn)換溫度

}

注:在開(kāi)始轉(zhuǎn)換命令和讀取溫度之間,若18B20忙于轉(zhuǎn)換溫度,電平為低電位;

轉(zhuǎn)換完畢將電平拉高;若不想用DELAY等待溫度轉(zhuǎn)換,可讀取DQ值,為1則表示轉(zhuǎn)換完畢,可以開(kāi)始讀取數(shù)據(jù)了;

/****************讀取溫度命令程序***************************************/

uint TEMP_READ_18B20(){

byte dummy=0;

byte TEMH=0,TEML=0;

uint TEM_RESULT;

dummy=INIT_18B20(); //初始化

if(dummy==0){

WRITE_18B20(0XCC); //跳過(guò)ROM

WRITE_18B20(0xBE); //讀暫存存儲(chǔ)器的值命令

TEML=READ_18B20();

TEMH=READ_18B20(); //讀溫度的高8位和低八位

dummy=INIT_18B20(); //最后初始化,表示讀取溫度結(jié)束

}

TEM_RESULT=(TEML》》3)+(TEMH《《5); //分辨率為0.5°

TEM_RESULT=TEM_RESULT*5;

if((TEMH&0X80)!=0)

//最高位為1,則為負(fù)溫度 ;;

// TEM_RESULT=~TEMP_RESULT+1; //溫度為負(fù),取補(bǔ)碼

return(TEM_RESULT); //返回值為溫度的十倍,小數(shù)點(diǎn)后一位

}

主函數(shù)中調(diào)用:

SIGNAL=TEMP_DETECT_18B20();

if(SIGNAL==0){

if(DQ) //此時(shí)端口為1,則表示轉(zhuǎn)換完成

TEMP_RESULT=TEMP_READ_18B20(); //返回溫度的十倍值

若時(shí)序錯(cuò)誤,很有可能讀出的數(shù)據(jù)位0XFF;若溫度傳感器燒壞,容易讀到85°; l

使用默認(rèn)12位轉(zhuǎn)換精度,分辨率為0.0625°,此處不需要這么高的精度因此:

TEM_RESULT=(TEML》》3)+(TEMH《《5); //分辨率為0.5°

舍棄后面三位數(shù)據(jù),并且只有11位是溫度值,高八位中的前五位是符號(hào)位;

讀取為1時(shí)溫度為負(fù);讀取為0時(shí),溫度為正;

DS18B20的調(diào)試總結(jié)和程序

非常好我支持^.^

(87) 93.5%

不好我反對(duì)

(6) 6.5%

( 發(fā)表人:李倩 )

      發(fā)表評(píng)論

      用戶評(píng)論
      評(píng)價(jià):好評(píng)中評(píng)差評(píng)

      發(fā)表評(píng)論,獲取積分! 請(qǐng)遵守相關(guān)規(guī)定!

      ?