DS18B20溫度檢測


STM32F407VET6 -- FreeRTOS -- DS18B20溫度檢測

1、DS18B20 單線數字溫度傳感器,即“一線器件”,其具有獨特的優點:

  a、采用單總線的接口方式 與微處理器連接時僅需要一根線即可實現微處理器與 DS18B20 的雙向通訊。單總線具有經濟性好,抗干擾能力強,適合於惡劣環境的現場溫度測量。
  b、測量溫度范圍寬,測量精度高 DS18B20 的測量范圍為 -55 ℃ ~+ 125 ℃ ; 在 -10~+ 85°C范圍內,精度為 ± 0.5°C 。
  c、在使用中不需要任何外圍元件。
  d、支持多點組網功能,多個 DS18B20 可以並聯在惟一的單線上,實現多點測溫。
  e、供電方式靈活 DS18B20 可以通過內部寄生電路從數據線上獲取電源。因此,當數據線上的時序滿足一定的要求時,可以不接外部電源,從而使系統結構更趨簡單,可靠性更高。
  f、測量參數可配置 DS18B20 的測量分辨率可通過程序設定 9~12 位。
  g、負壓特性電源極性接反時,溫度計不會因發熱而燒毀,但不能正常工作。
  h、掉電保護功能 DS18B20 內部含有 EEPROM ,在系統掉電以后,它仍可保存分辨率及報警溫度的設定值。

2、DS18B20內部結構:

  DS18B20內部主要包括,64位ROM、2字節溫度輸出寄存器、1字節上下警報寄存器(TH和TL)和1字節配置寄存器。ROM中的64位序列號是出廠前被光刻好的,它可以看作是該DS18B20的地址序列碼,每個DS18B20的64位序列號均不相同,這樣就可以實現一根總線掛接多個DS18B20的目的。配置寄存器允許用戶將溫度 - 數字轉換的分辨率設置為9,10,11或12位。DS18B20控制引腳需要一個上拉電阻,並通過開漏模式連接到總線。DS18B20無需外部電源也可運行,當總線為高電平時,通過DQ引腳提高電源,並將電存儲在Cpp電容中,在總線處於低電平時為器件供電,這種方法稱為“寄生電源”。另外DS18B20也可通過VDD供電。

3、DS18B20內部構成:

  

  高速暫存存儲器由9個字節組成,分別為:

    1、溫度的低八位數據

    2、溫度的高8位數據

    3、高溫閾值

    4、低溫閾值

    5、配置寄存器

    6、保留

    7、保留

    8、保留

    9、CRC校驗

  器件斷電時,EEPROM寄存器中的數據保留,上電后,EEPROM數據被重新加載到相應的寄存器位置,也可以使用命令隨時將數據從EEPROM重新加載到暫存器中。

4、溫度寄存器數據格式:

  

  DS18B20中的溫度傳感器數據用16位二進制形式提供,其中S為符號位(正數S=0,負數S=1)。溫度傳感器的分辨率可由用戶配置為9、10、11或12位,分別對應0.5℃、0.25 ℃、0.125℃和0.0625℃的增量。開機時的默認分辨率是12位。如果DS18B20配置為12位分辨率,那么溫度寄存器中的所有位都將包含有效數據。對於11位分辨率,bit0沒有定義。對於10位分辨率,bit1和bit0沒有定義,對於9位分辨率,bit2、bit1和bit0沒有定義。

5、TH和TL報警寄存器格式:

  

  TH和TL寄存器存儲溫度報警觸發值,符號位S表示值是正還是負,對於正數,S=0,對於負數,S=1。DS18B20執行溫度轉換后,將溫度值與用戶定義的兩個報警觸發值進行比較,由於TH和TL是8位寄存器,因此在比較TH和TL時只使用溫度寄存器的第11位到第4位,如果被測溫度低於或等於TL值,或高於或等於TH值,則在DS18B20內部存在報警條件,並設置報警標志。主設備可以通過發出一個[EC]命令來檢查總線上所有DS18B20的報警標志狀態。TH和TL寄存器是非易失性的(EEPROM),當設備斷電時,它們將保留數據。可以通過內存部分暫存器的字節2和字節3訪問TH和TL。

6、配置寄存器數據格式:

  

  在配置寄存器中,我們可以通過R0和R1設置DS18B20的轉換分辨率,DS18B20在上電后默認R0=1和R1=1(12分辨率),寄存器中的第7位和第0位到4位保留給設備內部使用。

7、 初始化時序:

  

  主機首先拉低總線,並至少持續480微秒;然后拉高釋放總線,並在隨后的480微秒時間內對總線進行檢測;如果有低電平出現說明總線上有器件已做出應答,若一直都是高電平說明總線上無器件應答。做為從器件的DS18B20在一上電后就一直在檢測總線上是否有至少480微秒的低電平出現,如果有,在總線轉為高電平后等待15-60微秒后將總線電平拉低60-240微秒做出響應存在脈沖,告訴主機本器件已做好准備。若沒有檢測到就一直在檢測等待。
8、寫操作時序:
  
  寫周期最少為60微秒,最長不超過120微秒。若主機想寫0,則把總線拉低電平最少60微秒直至寫周期結束。若主機想寫1,則一開始主機先把總線拉低1微秒表示寫周期開始,1微秒后就釋放總線為高電平,一直到寫周期結束。做為從機的DS18B20則在檢測到總線被拉底后等待15微秒然后從15us到45us開始對總線采樣,在采樣期內總線為高電平則為1,若采樣期內總線為低電平則為0。

9、讀操作時序:
  
  對於讀數據操作時序也分為讀0時序和讀1時序兩個過程。讀時序是從主機把單總線拉低之后,在1微秒之后就得釋放單總線為高電平,以讓DS18B20把數據傳輸到單總線上。DS18B20在檢測到總線被拉低1微秒后,便開始送出數據,若是要送出0就把總線拉為低電平直到讀周期結束。若要送出1則釋放總線為高電平。主機在一開始拉低總線1微秒后釋放總線,然后在包括前面的拉低總線電平1微秒在內的15微秒時間內完成對總線進行采樣檢測,采樣期內總線為低電平則確認為0。采樣期內總線為高電平則確認為1。完成一個讀時序過程,至少需要60us才能完成。
 
 
10、STM32F407VET6 -- FreeRTOS -- 讀寫DS18B20溫度傳感器例程
 

static ePinType_t pin;
static eGpioType_t gpio;
static float TemperatureValue = 0.0f;

/********************************************************
 * 函數功能:DS18B20器件復位
 * 形    參:無
 * 返 回 值:0=成功,1=失敗
 ********************************************************/
static unsigned char ds18b20_reset(void)
{
   unsigned char status = 0;
   unsigned short timeout = 0;
   gpio_set_pin(gpio, pin, 0); // 拉低總線
   delay_us(520); // 持續最少480us
   gpio_set_pin(gpio, pin, 1); // 釋放總線
   delay_us(10); // 需要等待15 - 60us
   gpio_config(gpio, pin, eGPIO_IN_UP, 1); // 設置總線為輸入模式
   // 進入接收模式,此時傳感器會拉低總線,持續時間:60 - 240us
   while(gpio_read_pin(gpio, pin) != 0)
   {
      if(++timeout > 0xFFF0U)
      {
         status = 1;
         break;
      }
   }
   // 等待總線被釋放(被拉高)
   timeout = 0;
   while(gpio_read_pin(gpio, pin) == 0)
   {
      if(++timeout > 0xFFF0U)
      {
         status = 1;
         break;
      }
   }
   gpio_config(gpio, pin, eGPIO_OUT_PP_UP, 1); // 設置為輸出
   return status;
}
/********************************************************
 * 函數功能:向DS18B20寫一個字節數據
 * 形    參:寫入的字節數據
 * 返 回 值:無
 ********************************************************/
static void ds18b20_write_byte(unsigned char dat)
{
   unsigned char i = 0;
   for(i = 0; i < 8; i++)
   {
      gpio_set_pin(gpio, pin, 0);
      delay_us(2); // 總線拉低持續時間要大於1us
      if(dat & (0x01U << i)) // 低位先發
      {
         gpio_set_pin(gpio, pin, 1);
      }
  
      delay_us(60); // 延時60us,等待ds18b20采樣讀取
      gpio_set_pin(gpio, pin, 1); // 釋放總線
      delay_us(2);
   }
}

/********************************************************
 * 函數功能:從DS18B20讀一個字節數據
 * 形    參:無
 * 返 回 值:讀出的字節數據
 ********************************************************/
static unsigned char ds18b20_read_byte(void)
{
   unsigned char i = 0;
   unsigned char dat = 0;
 
   for(i = 0; i < 8; i++)
   {
      gpio_set_pin(gpio, pin, 0); // 拉低總線
      delay_us(2);
      gpio_set_pin(gpio, pin, 1); // 釋放總線
      gpio_config(gpio, pin, eGPIO_IN_UP, 1); // 設置總線為輸入模式
      delay_us(10);
      if(gpio_read_pin(gpio, pin) != 0) // 讀時隙產生7 us后讀取總線數據
      {
         dat |= 0x01U << i; // 低位先收
      }
      delay_us(50); // 延時60us,滿足讀時隙的時間長度要求
      gpio_config(gpio, pin, eGPIO_OUT_PP_UP, 1); // 釋放總線
      delay_us(2);
   }
   return dat;
}
/********************************************************
 * 函數功能:DS18B20溫度采集線程
 * 形    參:parg:線程形參
 * 返 回 值:無
 ********************************************************/
static void ds18b20_task(void *parg)
{
   unsigned char data = 0;
   unsigned short temp = 0;
 
   while(1)
   {
      if(ds18b20_reset() != 0)
      {
         continue;
      }
  
      os_critical_enter(); // 進入臨界區
      ds18b20_write_byte(0xCC); // skip rom
      ds18b20_write_byte(0x44); // 啟動溫度轉換
      os_critical_exit(); // 退出臨界區
      os_delay(500);
  
      if(ds18b20_reset() != 0)
      {
         continue;
      }
  
      os_critical_enter(); // 進入臨界區
      ds18b20_write_byte(0xCC); // skip rom
      ds18b20_write_byte(0xBE); // 發出讀取命令
      data = ds18b20_read_byte(); // 讀出溫度低八位
      temp = ds18b20_read_byte(); // 讀出溫度高八位
  
      // 計算溫度值
      temp = (temp << 8) | data;
  
      // 高五位為符號位,當溫度為正的時候,高五位的字節是0,當溫度為負的時候,高五位字節為1
      if((temp & 0xF800) != 0)
      {
         temp = (~temp) + 1; // 正溫度值直接計算,負溫度值需取反加1
         TemperatureValue = -0.0625f; // 溫度為負
      }
      else
      {
         TemperatureValue = 0.0625f;
      }
  
      // DS18B20的分辨率是0.0625度
      TemperatureValue = TemperatureValue * temp;
      os_critical_exit(); // 退出臨界區
  
      os_delay(1500); // 1.5s采集一次溫度數據
   }
}

/********************************************************
 * 函數功能:DS18B20初始化
 * 形    參:gpiox:引腳端口
             pinx:引腳號
 * 返 回 值:無
 ********************************************************/
unsigned int ds18b20_init(eGpioType_t gpiox, ePinType_t pinx)
{
   gpio = gpiox;
   pin = pinx;
 
   // 初始化引腳
   gpio_config(gpio, pin, eGPIO_OUT_PP_UP, 1);
 
   // 創建溫度采集線程
   if(os_task_create(ds18b20_task, NULL, 128, eOS_PRIO_LL) != 0)
   {
      return 1; // 創建失敗
   }
 
   return 0;
}

/********************************************************
 * 函數功能:讀取溫度值
 * 形    參:無
 * 返 回 值:溫度值
 ********************************************************/
float ds18b20_temperature_value_get(void)
{
   return TemperatureValue;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM