基於DS18B20測溫系統解決方案

英創嵌入式主板以其優異的穩定性、獨特的設計及方便使用等優點,在嵌入式領域佔有一席之地。在工業現場,經常有監測環境溫度的需求,本方案應用DS18B20爲溫度採集芯片,與英創嵌入式主板的GPIO相連,就可以組成完整的測溫系統。由於DS18B20每條總線上可以最多接8個測溫點,那麼英創嵌入式主板至少可以接64個測溫點。 

        DS18B20數字溫度計是DALLAS公司生產的1-Wire即單總線器件,具有線路簡單,體積小的特點。實際應用中不需要外部任何元器件即可實現測溫,測量溫度範圍在-55°C到+125°C之間,數字溫度計的分辨率用戶可以從9位到12位選擇;並且內部有溫度上、下限告警設置,使用非常方便。 

        TO-92封裝的DS18B20的引腳排列見圖1,其引腳功能描述見表1。

 

        表1 DS18B20詳細引腳功能描述:

序號

名稱

引腳功能描述

1

GND

  地信號

2

DQ

 

  數據輸入/輸出引腳。開漏單總線接口引腳
  當被用着在寄生電源下,也可以向器件提供電源

 

3

VDD

  可選的VDD引腳。當工作於寄生電源時,此引腳必須接地

DS18B20的使用方法 
        由於DS18B20採用的是1-Wire總線協議方式,即在一根數據線實現數據的雙向傳輸,而對嵌入式主板來說,硬件上並不支持單總線協議,因此,我們必須採用GPIO的方法來模擬單總線的協議時序來完成對DS18B20芯片的訪問。在本示例中,只需把管腳2接英創嵌入式主板的GPIO,管腳3接5V電源,管腳1接地,就可以搭建起測試環境,如圖二所示。如果需要測試多點溫度,可以把多個DS18B20並起。

 

        由於DS18B20是在一根I/O線上讀寫數據,因此,對讀寫的數據位有着嚴格的時序要求。DS18B20有嚴格的通信協議來保證各位數據傳輸的正確性和完整性。該協議定義了幾種信號的時序:初始化時序、讀時序、寫時序。所有時序都是將嵌入式主板作爲主設備,單總線器件作爲從設備。每一次命令和數據的傳輸都是從主機主動啓動寫時序開始,如果要求單總線器件送回數據,在進行寫命令後,主機需要啓動讀時序完成數據接收。數據和命令的傳輸都是低位在先。 

        下面是18B20的時序圖,根據時序的要求,改變GPIO的電平,可以完成18B20的操作。

DS18B20復位時序

 

        根據以上DS18B20的時序,初始化的函數如下: 

Init18b20() 

        char flag; 
        OutBit(1); 
        Delayus(1); 
        OutBit(0); 
        Delayus(600); // 復位信號480—960us 
        OutBit(1); 
        Delayus(60); // 等待15-60us 
        if(ReadBit()) // 檢查存在電平,如果爲低,說明18B20正確復位 
        { 
                printf('init fail'); 
                return false; // detect 1820 fail! 
        } 
        else 
        { 
                Sleep(1); 
                OutBit(1); 
                return true; // detect 1820 success! 
        } 


        DS18B20的數據讀寫時通過時間間隙處理位和命令字來確認信息交換。 

DS18B20的寫時間隙 
        當主機把數據線從邏輯高電平拉到邏輯低電平的時候,寫時間隙開始。有兩種寫時間隙:寫1時間隙和寫0時間隙。所有寫時間隙必須最少持續60us,包括兩個寫週期間至少1us的恢復時間。 

        I/O線電平變低後,DS18B20在一個15us到60us的窗口內對I/O線採樣。如果線上是高電平,就是寫1,如果線上是低電平,就是寫0。如圖所示。

 

void DS18B20::WriteByte(uchar wr) 

        uchar i; 
        OutBit(1); 
        Delayus(1); 
        for (i=0;i<8;i++) // 寫8bit 
        { 
                OutBit(0) ; // 總線拉低,寫間隙開始 
                Delayus(10); // 延時 2-12us 
                OutBit(wr&0x01) ; // 寫數據到總線 
                Delayus(30); // 在15us-60us之間採用 
                OutBit(1); // 釋放總線 
                wr >>= 1; 
                Delayus(2); 
        } 
        Sleep(1); // 字節之間最好間隔的稍微長一點 


DS18B20的讀時間隙 
        當從DS18B20讀取數據時,主機生成讀時間隙。當主機把數據線從高電平拉到低電平時,讀時間隙開始,數據線必須保持至少1us;從DS8B20輸出的數據在讀時間隙的下降沿出現後15us內有效。對於DS18B20的讀時隙是從主機把總線拉低之後,在15微秒之內就得釋放單總線,以讓DS18B20把數據傳輸到單總線上。DS18B20在完成一個讀時序過程,至少要60us才能完成。

 

        根據以上的讀時序圖,讀字節函數如下: 

UCHAR DS18B20::ReadByte() 

        uchar i,u=0; 
        OutBit(1); 
        Delayus(1); 
        for(i=0;i<8;i++) // 讀一字節 
        { 
                OutBit(0) ; // 總線拉低,讀間隙開始 
                Delayus(2); 
                OutBit(1) ; // 拉高總線 
                Delayus(4); // 在1-14us之內讀取總線數據 
                u >>= 1; 
                if(ReadBit()==1) u |= 0x80; 
                        Delayus(60); // 讀取數據週期至少60us 
                OutBit(1) ; 
        } 
        return(u); 


        在讀溫度之前,要先啓動溫度轉換,如果採用寄生電源供電,溫度轉換的時間應該大於500毫秒。對於一條總線的多個18B20來說,啓動轉換不需要匹配18B20的ROM地址。 

void DS18B20::StartConvert() 

        Init18b20 (); 
        WriteByte(0xcc); // 跳過ROM 
        WriteByte(0x44); // 啓動轉換命令 


        在讀指定的18B20時,就要先發匹配命令,再發ROM序列號,具體請參考下面的程序: 

void DS18B20::TemperatuerResult(char id) 

        uchar i; 
        Init18b20 (); 
        WriteByte(0x55); // 匹配ROM地址 
        for(i=0;i<8;i++) // 發18B20地址碼 
        { 
                WriteByte(b20rom[id][i]); 
        } 
        WriteByte(0xbe); // 發讀溫度命令 
        read_bytes(2); // 前2個字節爲溫度值 
        temp=temp_buff[1]&0x0f; // 去掉符號位 
        temp=temp<<8; 
        temp=temp+temp_buff[0]; 
        Temperature=temp*0.0625; // 得到溫度值 


        源程序請參考光盤源碼。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章