4.5.1 原理圖介紹編程
圖4-5-1ide
實驗板上的DS18B20模塊接在單片機的P3.7 IO口上,在插入DS18B20芯片時,圓弧朝上插入,具體效果能夠看上面圖片。函數
4.5.2 DS18B20溫度傳感器介紹編碼
DS18B20是經常使用的數字溫度傳感器,其輸出的是數字信號,它的溫度檢測與數字數據輸出全集成於一個芯片之上,從而抗干擾力更強。spa
DS18B20的主要特徵以下:設計
(1)、全數字溫度轉換及輸出。code
(2)、先進的單總線數據通訊。(一根線便可採集溫度)regexp
(3)、最高 12 位分辨率,精度可達土 0.5 攝氏度。blog
(4)、12 位分辨率時的最大工做週期爲 750 毫秒。接口
(5)、可選擇寄生工做方式。
(6)、檢測溫度範圍爲–55° C ~+125° C (–67° F ~+257° F)
(7)、內置 EEPROM,限溫報警功能。
(8)、64位光刻 ROM,內置產品序列號,方便多機掛接。(支持一根線操做多個芯片)
(9)、多樣封裝形式,適應不一樣硬件系統,封裝能夠看下面的圖片。
圖4-5-3
圖片裏芯片的引腳功能:GND電壓地 、DQ單數據總線、VDD電源電壓、NC 空引腳
4.5.3 DS18B20的工做原理介紹
DS18B20的溫度檢測與數字數據輸出全集成於一個芯片之上,從而抗干擾力更強。
它的一個工做週期可分爲兩個部分,溫度檢測和數據處理。
DS18B20內部有三種形態的存儲器:
(1) ROM只讀存儲器:用於存放 DS18B20ID 編碼,其前 8 位是單線系列編碼(DS18B20 的編碼是19H),後面 48 位是芯片惟一的序列號,最後8位是以上56的位的 CRC 碼(冗餘校驗),數據在芯片出廠時設置不可由用戶更改。DS18B20 共 64 位 ROM(8+48+8)。
(2) RAM數據暫存器:用於內部計算和數據存取,數據在掉電後丟失,DS18B20 共 9 個字節 RAM,每一個字節爲 8 位。第 一、 2 個字節是溫度轉換後的數據值信息,第 三、 4 個字節是用戶 EEPROM(經常使用於溫度報警值儲存)的鏡像。在上電覆位時其值將被刷新。第 5 個字節則是用戶第 3 個 EEPROM的鏡像。第 六、 七、 8 個字節爲計數寄存器,是爲了讓用戶獲得更高的溫度分辨率而設計的,一樣也是內部溫度轉換、計算的暫存單元。第 9 個字節爲前 8 個字節的 CRC 碼。
(3) EEPROM非易失性記憶體:用於存放長期須要保存的數據。好比: 上下限溫度報警值和校驗數據,DS18B20共有3個字節的EEPROM,並在 RAM 都存在鏡像,以方便用戶操做。
圖4-5-4
DS18B20默認工做在12位分辨率模式,轉換後獲得的12位數據,存儲在DS18B20的兩個8比特的RAM中(最前面的兩個字節),二進制中的前面5位是符號位,若是測得的溫度大於0,這5位爲0,只要將測到的數值乘於0.0625便可獲得實際溫度;若是溫度小於0,這5位爲1,測到的數值須要取反加1再乘於0.0625便可獲得實際溫度。
數據提取也可使用位運算,讀取出來的數據是2個字節一共16位(H和L),最低4位是小數位,剩下的是整數位。若是讀取的數據是負數,須要-1再取反便可獲得真實數據。
例如:
(硬件平臺說明:CPU是STC90C516RD 、晶振頻率12MHZ 、工做在12T模式下、一個機器週期爲1us時間)
int temp=0;temp=DS18B20_ReadTemp(); //讀取一次DS18B20採集的溫度(返回H+L位)if(temp<0) //若是溫度是負數{ temp=temp-1; temp=~temp; printf("DS18b20=-%d.%d\r\n",temp>>4,temp&0xF);}else{printf("DS18b20=%d.%d\r\n",temp>>4,temp&0xF);}
4.5.4 DS18B20操做ROM/RAM的經常使用指令介紹
1. 讀取64位ROM編碼指令:0x33
這個命令容許總線控制器讀到DS18B20的64位ROM。只有當總線上只存在一個 DS18B20的時候纔可使用此指令,若是掛接不僅一個,當通訊時將會發生數據衝突。
2. 匹配芯片指令:0x55
這個指令後面緊跟着由控制器發出的64 位序列號,當總線上有多隻 DS18B20 時,只有與控制發出的序列號相同的芯片才能夠作出反應,其它芯片將等待下一次復位。這條指令適應單芯片和多芯片掛接。
3. 跳過ROM編碼匹配:0xCC
這條指令使芯片不對 ROM 編碼作出反應,在單總線的狀況之下,爲了節省時間則能夠選用此指令。若是在多芯片掛接時使用此指令將會出現數據衝突,致使錯誤出現。
4. 啓動溫度轉換:0x44
收到此指令後芯片將進行一次溫度轉換,將轉換的溫度值放入 RAM 的第 一、 2 地址。此後因爲芯片忙於溫度轉換處理,當控制器發一個讀時間隙時,總線上輸出「0」,當儲存工做完成時,總線將輸出「1」。在寄生工做方式時必須在發出此指令後馬上超用強上拉並至少保持 500MS,來維持芯片工做。
5. 從RAM中讀數據指令:0xBE
此指令將從 RAM中讀數據,讀地址從地址0開始,一直能夠讀到地址 9,完成整個 RAM 數據的讀出。芯片容許在讀過程當中用復位信號停止讀取,便可以不讀後面不須要的字節以減小讀取時間。
4.5.5 DS18B20時序圖
(1). DS18B20復位與應答時序圖
圖4-5-5 復位及應答時序圖
圖4-5-6
每一次與DS18B20通訊以前都必須進行復位,復位的時間、等待時間、迴應時間應嚴格按時序編程。
(2) 寫數據時序
圖4-5-7 寫數據時序圖
上面的時序圖是向DS18B20寫數據的時序圖,該圖分爲兩部分,左邊部分是發送數據0的時序圖,右邊部分是發送數據1的時序圖。
根據時序圖提示(右邊部分),每次發送數據以前(不論是數據0仍是數據1)都須要先將總線拉低至少1us。
若是接下來發送的數據是0,那麼須要將數據線拉低至少60us的時間,DS18B20對總線的採樣時間在15~60us內;在採樣時間內,若是總線爲低電平,則表示寫0,若是總線爲高電平,則表示寫1。
若是接下來發送的數據是1,那麼也須要將數據線拉低至少60us的時間,DS18B20對總線的採樣時間在15~60us內;在採樣時間內,若是總線爲低電平,則表示寫0,若是總線爲高電平,則表示寫1。
注意: 在通訊時,是以一個字節爲單位向DS18B20進行傳輸,字節的讀或者寫是從低位開始的。
(3) 讀數據時序
圖4-5-8 讀數據時序圖
上面的時序圖是從DS18B20讀取數據的時序圖,該圖分爲兩部分展現,左邊部分是讀取數據0時,總線電平變化過程,右邊部分是讀取數據1時,總線電平的變化過程。
根據時序圖提示(右邊部分),每次讀取數據以前(不論是數據0仍是數據1),總線都須要由主機拉低至少1us,而後再釋放總線(拉高);
隨後須要等待15us的時間,才能夠讀取總線數據。DS18B20會在隨後的45us內維持總線的電平,這段時間內讀取總線的數據都是有效數據。
注意: 再總線拉低1us以後,必須等待15us以後才能夠讀取總線數據,這樣才能保證總線數據是準確的。
在通訊過程當中,DS18B20輸出的數據是從低位開始傳輸的。
4.5.6 讀取溫度的步驟
總線上只有單隻DS18B20的情景(讀取一次DS18B20的溫度):
1. 向總線發送復位脈衝並檢測DS18B20的響應信號(能夠確保DS18B20硬件沒有問題)
2. 發送指令跳過ROM編號檢查 (指令0xCC)
3. 發送溫度轉換命令(指令0x44)
(DS18B20在轉換溫度的過程當中,總線會一直保持高電平狀態,不會響應總線命令)
4. 向總線發送復位脈衝並檢測DS18B20的響應信號
5. 發送指令跳過ROM編號檢查 (指令0xCC)
6. 發送讀取溫度的指令(指令 0xBE)
7. 接着讀取溫度數據低8位
8. 接着讀取溫度數據高8位
4.5.7 讀取DS18B20溫度示例代碼(單隻DS18B20情景)
下面代碼演示了循環讀取DS18B20溫度的過程,在主函數裏1秒的間隔讀取一次溫度。
在編寫DS18B20時序代碼時,要注意時間的把控。
當前實驗板的環境:採用STC90C516RD單片機,晶振是12MHZ,工做在12T模式下,代碼中執行一條i++語句大概消耗的時間是12us。程序中的延時時間,都是經過該時間推算的,若是程序要移植到其餘單片機上,要注意時間的問題。
示例代碼:
(硬件平臺說明:CPU是STC90C516RD 、晶振頻率12MHZ 、工做在12T模式下、一個機器週期爲1us時間)
/*DS18B20硬件接口: P3.7*/sbit DS18B20_GPIO=P3^7;int DS18B20_ReadTemp(void);/*說明: 在12MHZ晶振下,12T模式下,i++消耗的時間差很少是12us*//*函數名稱:u8 DS18B20_Init(void)函數功能:向DS18B20發送復位脈衝,並檢測應答信號返 回 值:1表示失敗,0表示成功說明: 51單片機IO口默認輸出高電平*/u8 DS18B20_ResetSignal(void){ u8 i=0; //1. 發送復位信號 DS18B20_GPIO=0;//將總線拉低480us i=50; while(i--){} //延時600us ,最少480us i=0; DS18B20_GPIO=1;//而後釋放(拉高)總線,若是DS18B20作出反應會將在15us~60us後總線拉低 //2. 等待DS18B20拉低總線 while(DS18B20_GPIO) { i++; if(i>10)return 1;//失敗 ,大概120us
} //3. 等待DS18B20釋放總線 i=0; while(DS18B20_GPIO==0) //60us~240us { i++; if(i>20)return 1;//失敗,大概240us } return 0;//初始化成功}/*函數名稱:u8 DS18B20_WriteByte(void)函數功能:向DS18B20寫入一個字節的數據函數形參:寫入的字節數據*/void DS18B20_WriteByte(u8 byte){ u16 i=0,j=0; for(j=0;j<8;j++) { DS18B20_GPIO=0;//每寫入一位數據以前先把總線拉低1us i++; //+1消耗的時間是12us DS18B20_GPIO=byte&0x01;//而後寫入一個數據,從最低位開始 i=6; while(i--){}//持續時間最少60us,這裏大概72us DS18B20_GPIO=1;//而後釋放總線 byte>>=1;//繼續發送 }}/*函數名稱:u8 DS18B20_ReadByte(void)函數功能:從DS18B20讀取一個字節的數據返 回 值:讀到的數據*/u8 DS18B20_ReadByte(void){ u8 byte=0; u16 i=0,j=0; for(j=0;j<8;j++) { DS18B20_GPIO=0;//先將總線拉低1us i++;//+1消耗的時間是12us DS18B20_GPIO=1;//而後釋放總線 i++; i++;//至少等待15us的時間,在讀取數據 byte>>=1; //先從低位開始接收數據 if(DS18B20_GPIO)byte|=0x80; i=4; //讀取完以後等待48us再接着讀取下一個數據 while(i--){} } return byte;}/*函數名稱:u16 DS18B20_ReadTemp(void)函數功能:讀取一次DS18B20的溫度數據返 回 值:讀取的溫度值注意: 返回值要使用有符號的數據類型,由於溫度能夠返回負數。*/int DS18B20_ReadTemp(void){ int temp=0;//存放溫度數據 u8 TH,TL; //第一步: 啓動溫度轉換 DS18B20_ResetSignal(); //發送復位脈衝並檢測應答信號 DS18B20_WriteByte(0xcc);//跳過ROM操做命令 DS18B20_WriteByte(0x44);//溫度轉換命令 //第二步: 讀取溫度 DS18B20_ResetSignal();//發送復位脈衝並檢測應答信 DS18B20_WriteByte(0xcc);//跳過ROM操做命令 DS18B20_WriteByte(0xbe);//發送讀取溫度命令 TL=DS18B20_ReadByte();//讀取溫度值共16位,先讀低字節 TH=DS18B20_ReadByte();//再讀高字節 temp=TH<<8|TL; //合併成16位 return temp;}int main(){ int temp=0; UART_Init(); //初始化串口波特率爲4800 while(1) { temp=DS18B20_ReadTemp(); if(temp<0) //若是溫度是負數 { temp=temp-1; temp=~temp; printf("DS18b20=-%d.%d\r\n",temp>>4,temp&0xF); } else { printf("DS18b20=%d.%d\r\n",temp>>4,temp&0xF); } DelayMs(1000); }}