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

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

DS18B20的時序及代碼解析

2017年11月06日 17:02 網(wǎng)絡(luò)整理 作者: 用戶評論(0

  DS18B20的核心功能是它的直接讀數(shù)字的溫度傳感器。溫度傳感器的精度為用戶可編程的9,10,11或12位,分別以0.5℃,0.25℃,0.125℃和0.0625℃增量遞增。在上電狀態(tài)下默認(rèn)的精度為12位(所以最后獲取的數(shù)據(jù)要乘以0.0625得到實際溫度)。DS18B20啟動后保持低功耗等待狀態(tài);當(dāng)需要執(zhí)行溫度測量(和AD轉(zhuǎn)換)時,總線控制器必須發(fā)出[44h]命令。

  在那之后,產(chǎn)生的溫度數(shù)據(jù)以兩個字節(jié)的形式被存儲到高速暫存器的溫度寄存器中(所以后期獲取數(shù)據(jù)時,必須連續(xù)讀取兩次數(shù)據(jù)),下面介紹時序及相應(yīng)代碼(以12MHz的晶振為例,數(shù)據(jù)線定義為DQ),其中DS18B20的所有通信都是以由復(fù)位脈沖組成的初始化序列開始的,并采用的是單總線協(xié)議。

  操作順序:初始化——》寫相應(yīng)的控制指令(用寫數(shù)據(jù)函數(shù)完成)——》讀取DS18B20所采集到的數(shù)據(jù)(用讀數(shù)據(jù)函數(shù)完成)———》把采集的數(shù)據(jù)轉(zhuǎn)化成實際的溫度。

  時序圖及代碼分析如下

  一、初始化

  在初始化序列期間,總線控制器拉低總線并保持480us(改延時可以在480~960us之間,但需要在480us以內(nèi)釋放總線)以發(fā)出一個復(fù)位脈

  沖,然后釋放總線,進(jìn)入接收狀態(tài)(等待DS18B20應(yīng)答)??偩€釋放后,單總線由上拉電阻拉到高電平。當(dāng)DS18B20探測到I/O引腳上的上升沿后,等待15-60us,然后其以拉低總線60-240us的方式發(fā)出存在脈沖。至此,初始化時序完畢。

  DS18B20的時序及代碼解析

  初始化代碼,初始化代碼寫至此,其實我們便可以用數(shù)碼管顯示來檢驗初始化是否成功(即DS18B20有應(yīng)答),數(shù)碼管顯示”0“,初始化失敗,顯示”1“,則初始化成功。

  bit DS18B20_init()

  {

  bit ack = 1;

  DQ = 0; //主機拉低總線

  delay_us(32); //延時495us

  DQ = 1; //釋放總線,同時IO口產(chǎn)生的上升沿能被DS18B20所檢測

  delay_us(4); //延時大于60us,確保接下來DS18B20能發(fā)出60~240us的存在脈沖應(yīng)答

  ack = DQ; //在此60~240us之內(nèi)DQ被DS18B20所占用,若存在,則其會發(fā)送一個低電平信號,DQ被DS18B20拉低,則ack為0,反之為1

  delay_us(15); //延時達(dá)240us,讓DS18B20釋放總線

  DQ = 1;

  return(ack);

  }

  二、DS18B20的寫時序

  主機在寫時隙向DS18B20寫入數(shù)據(jù),其中分為寫”0”時隙,和寫”1”時隙??偩€主機使用寫“1”時間隙向DS18B20寫入邏輯1,使用寫“0”時間隙向DS18B20寫入邏輯0.所有的寫時隙必須有最少60us的持續(xù)時間,相鄰兩個寫時隙必須要有最少1us的恢復(fù)時間。兩種寫時隙都通過主機拉低總線產(chǎn)生(見下圖)為了產(chǎn)生寫1時隙。

  在拉低總線后主機必須在15μs內(nèi)釋放總線。在總線被釋放后,由于上拉電阻將總線恢復(fù)為高電平。為了產(chǎn)生寫”0”時隙,在拉低總線后主機必須繼續(xù)拉低總線以滿足時隙持續(xù)時間的要求(至少60μs)。

  在主機產(chǎn)生寫時隙后,DS18B20會在其后的15~60us的一個時間段內(nèi)采樣單總線(DQ)。在采樣的時間窗口內(nèi),如果總線為高電平,主機會向DS18B20寫入1;如果總線為低電平,主機會向DS18B20寫入0。

  綜上所述,所有的寫時隙必須至少有60us的持續(xù)時間。相鄰兩個寫時隙必須要有最少1us的恢復(fù)時間。所有的寫時隙(寫0和寫1)都由拉低總線產(chǎn)生。

  DS18B20的時序及代碼解析

  DS18B20的寫時序代碼 :寫字節(jié)函數(shù)、由低位至高位,向DS18B20寫入一個字節(jié)的數(shù)據(jù)。無返回值,形參byte是待寫入的字節(jié)數(shù)據(jù),讀取8次,移位8次,保證每位都傳輸至DQ。

  void DS18B20_write_byte(uchar byte)

  {

  uchar i;

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

  {

  DQ = 0; //拉低總線,產(chǎn)生寫時隙

  _nop_();

  _nop_(); //大于1us的延時

  DQ = 1; //15us之內(nèi)釋放總線

  _nop_();

  _nop_(); //適當(dāng)延時

  DQ = byte & 0x01; //將字節(jié)低位寫入單總線

  delay_us(3); //在15~60us內(nèi)等待DS18B20來采集信號

  DQ = 1; //釋放總線

  byte 》》= 1; //每次講要讀取的數(shù)據(jù)位移至最低位,

  }

  }

  三、DS18B20的讀時序

  主機發(fā)起讀時序時,DS18B20僅被用來傳輸數(shù)據(jù)給控制器。因此,總線控制器在發(fā)出讀暫存器指令[0xBE]或讀電源模式指令[0xB4]后必須立刻開始讀時序,DS18B20可以提供請求信息。除此之外,總線控制器在發(fā)出發(fā)送溫度轉(zhuǎn)換指令[0x44] (或召回EEPROM指令[0xB8])之后讀時序,詳見DS18B20 的芯片手冊上的功能指令。

  所有讀時序必須最少60us,包括兩個讀周期間至少1us的恢復(fù)時間。當(dāng)總線控制器把數(shù)據(jù)線從高電平拉到低電平時,讀時序開始,數(shù)據(jù)線必須至少保持1us,然后總線被釋放。DS18B20 通過拉高或拉低總線上來傳輸”1”或”0”。當(dāng)傳輸邏輯”0”結(jié)束后,總線將被釋放,通過上拉電阻回到上升沿狀態(tài)。從DS18B20輸出的數(shù)據(jù)在讀時序的下降沿出現(xiàn)后15us 內(nèi)有效。因此,總線控制器在讀時序開始后必須停止把I/O口驅(qū)動為低電15us,以讀取I/O口狀態(tài)。

  DS18B20的時序及代碼解析

  DS18B20的讀時序的代碼 :讀字節(jié)函數(shù)、由低位至高位,讀取DS18B20所采集到的數(shù)據(jù)。帶返回值,可結(jié)合前面的寫時序,對寫、讀數(shù)據(jù)函數(shù)進(jìn)行檢驗(后面會提到檢驗過程及效果)byte 是讀取到的字節(jié)數(shù)據(jù)。其中,此函數(shù)讀取8次,移位7次(實際移位8次)。

  uchar DS18B20_read_write()

  {

  uchar i;

  uchar byte; //byte為要接收到的數(shù)據(jù)

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

  {

  DQ = 0; //產(chǎn)生讀時序

  _nop_();

  _nop_(); //簡單延時

  DQ = 1; //釋放總線,有從機DS18B20占用

  byte 》》= 1; //先進(jìn)行移位

  if(DQ) //讓DS18B20占用總線,發(fā)出采集到的信號

  byte |= 0x80; //若DQ=1,則讓當(dāng)前byte最高位為1,在下次循環(huán)中移位至次高位,最后達(dá)到從低位到高位接收的目的;若DQ=0,則可跳過此語句,直接在下次循環(huán)對byte進(jìn)行移位補0。以上操作15us以內(nèi)完成

  delay_us(3); //延時60us

  DQ = 1; //釋放總線

  _nop_();

  }

  }

非常好我支持^.^

(248) 50%

不好我反對

(248) 50%

( 發(fā)表人:陳翠 )

      發(fā)表評論

      用戶評論
      評價:好評中評差評

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

      ?