DS18B20的核心功能是它的直接讀數字的溫度傳感器。溫度傳感器的精度為用戶可編程的9,10,11或12位,分別以0.5℃,0.25℃,0.125℃和0.0625℃增量遞增。在上電狀態下默認的精度為12位(所以最后獲取的數據要乘以0.0625得到實際溫度)。DS18B20啟動后保持低功耗等待狀態;當需要執行溫度測量(和AD轉換)時,總線控制器必須發出[44h]命令。
在那之后,產生的溫度數據以兩個字節的形式被存儲到高速暫存器的溫度寄存器中(所以后期獲取數據時,必須連續讀取兩次數據),下面介紹時序及相應代碼(以12MHz的晶振為例,數據線定義為DQ),其中DS18B20的所有通信都是以由復位脈沖組成的初始化序列開始的,并采用的是單總線協議。
操作順序:初始化——》寫相應的控制指令(用寫數據函數完成)——》讀取DS18B20所采集到的數據(用讀數據函數完成)———》把采集的數據轉化成實際的溫度。
時序圖及代碼分析如下
一、初始化
在初始化序列期間,總線控制器拉低總線并保持480us(改延時可以在480~960us之間,但需要在480us以內釋放總線)以發出一個復位脈
沖,然后釋放總線,進入接收狀態(等待DS18B20應答)??偩€釋放后,單總線由上拉電阻拉到高電平。當DS18B20探測到I/O引腳上的上升沿后,等待15-60us,然后其以拉低總線60-240us的方式發出存在脈沖。至此,初始化時序完畢。
初始化代碼,初始化代碼寫至此,其實我們便可以用數碼管顯示來檢驗初始化是否成功(即DS18B20有應答),數碼管顯示”0“,初始化失敗,顯示”1“,則初始化成功。
bit DS18B20_init()
{
bit ack = 1;
DQ = 0; //主機拉低總線
delay_us(32); //延時495us
DQ = 1; //釋放總線,同時IO口產生的上升沿能被DS18B20所檢測到
delay_us(4); //延時大于60us,確保接下來DS18B20能發出60~240us的存在脈沖應答
ack = DQ; //在此60~240us之內DQ被DS18B20所占用,若存在,則其會發送一個低電平信號,DQ被DS18B20拉低,則ack為0,反之為1
delay_us(15); //延時達240us,讓DS18B20釋放總線
DQ = 1;
return(ack);
}
二、DS18B20的寫時序
主機在寫時隙向DS18B20寫入數據,其中分為寫”0”時隙,和寫”1”時隙。總線主機使用寫“1”時間隙向DS18B20寫入邏輯1,使用寫“0”時間隙向DS18B20寫入邏輯0.所有的寫時隙必須有最少60us的持續時間,相鄰兩個寫時隙必須要有最少1us的恢復時間。兩種寫時隙都通過主機拉低總線產生(見下圖)為了產生寫1時隙。
在拉低總線后主機必須在15μs內釋放總線。在總線被釋放后,由于上拉電阻將總線恢復為高電平。為了產生寫”0”時隙,在拉低總線后主機必須繼續拉低總線以滿足時隙持續時間的要求(至少60μs)。
在主機產生寫時隙后,DS18B20會在其后的15~60us的一個時間段內采樣單總線(DQ)。在采樣的時間窗口內,如果總線為高電平,主機會向DS18B20寫入1;如果總線為低電平,主機會向DS18B20寫入0。
綜上所述,所有的寫時隙必須至少有60us的持續時間。相鄰兩個寫時隙必須要有最少1us的恢復時間。所有的寫時隙(寫0和寫1)都由拉低總線產生。
DS18B20的寫時序代碼 :寫字節函數、由低位至高位,向DS18B20寫入一個字節的數據。無返回值,形參byte是待寫入的字節數據,讀取8次,移位8次,保證每位都傳輸至DQ。
void DS18B20_write_byte(uchar byte)
{
uchar i;
for(i=0 ; i《8 ; i++)
{
DQ = 0; //拉低總線,產生寫時隙
_nop_();
_nop_(); //大于1us的延時
DQ = 1; //15us之內釋放總線
_nop_();
_nop_(); //適當延時
DQ = byte & 0x01; //將字節低位寫入單總線
delay_us(3); //在15~60us內等待DS18B20來采集信號
DQ = 1; //釋放總線
byte 》》= 1; //每次講要讀取的數據位移至最低位,
}
}
三、DS18B20的讀時序
主機發起讀時序時,DS18B20僅被用來傳輸數據給控制器。因此,總線控制器在發出讀暫存器指令[0xBE]或讀電源模式指令[0xB4]后必須立刻開始讀時序,DS18B20可以提供請求信息。除此之外,總線控制器在發出發送溫度轉換指令[0x44] (或召回EEPROM指令[0xB8])之后讀時序,詳見DS18B20 的芯片手冊上的功能指令。
所有讀時序必須最少60us,包括兩個讀周期間至少1us的恢復時間。當總線控制器把數據線從高電平拉到低電平時,讀時序開始,數據線必須至少保持1us,然后總線被釋放。DS18B20 通過拉高或拉低總線上來傳輸”1”或”0”。當傳輸邏輯”0”結束后,總線將被釋放,通過上拉電阻回到上升沿狀態。從DS18B20輸出的數據在讀時序的下降沿出現后15us 內有效。因此,總線控制器在讀時序開始后必須停止把I/O口驅動為低電15us,以讀取I/O口狀態。
DS18B20的讀時序的代碼 :讀字節函數、由低位至高位,讀取DS18B20所采集到的數據。帶返回值,可結合前面的寫時序,對寫、讀數據函數進行檢驗(后面會提到檢驗過程及效果)byte 是讀取到的字節數據。其中,此函數讀取8次,移位7次(實際移位8次)。
uchar DS18B20_read_write()
{
uchar i;
uchar byte; //byte為要接收到的數據
for(i=0 ; i《8 ; i++)
{
DQ = 0; //產生讀時序
_nop_();
_nop_(); //簡單延時
DQ = 1; //釋放總線,有從機DS18B20占用
byte 》》= 1; //先進行移位
if(DQ) //讓DS18B20占用總線,發出采集到的信號
byte |= 0x80; //若DQ=1,則讓當前byte最高位為1,在下次循環中移位至次高位,最后達到從低位到高位接收的目的;若DQ=0,則可跳過此語句,直接在下次循環對byte進行移位補0。以上操作15us以內完成
delay_us(3); //延時60us
DQ = 1; //釋放總線
_nop_();
}
}