DHT11溫溼度傳感器

一.簡介

DHT11作爲一款低價、入門級的溫溼度傳感器,常用於我們的單片機設計實例中;它應用專用的數字模塊採集技術和溫溼度傳感技術,確保產品具有極高的可靠性與卓越的長期穩定性。傳感器包括一個電阻式感溼元件和一個NTC測溫元件,並與一個高性能8位單片機相連接。

DHT11爲 4 針單排引腳封裝,如下圖,採用單線制串行接口,只需加適當的上拉電阻,信號傳輸距離可達20米以上,使其成爲各類應用甚至最爲苛刻的應用場合的最佳選擇。

二.傳感器參數

1.DHT11電氣參數如下

2.引腳定義

3.典型電路

DHT11的供電電壓爲 3-5.5V,電源引腳(VDD,GND)之間可增加一個100nF 的電容,用以去耦濾波。DATA引腳並聯一個5K以上的上拉電阻,增強信號的抗干擾額能力。傳感器上電後,要等待 1s 以越過不穩定狀態在此期間無需發送任何指令。

 

 

三.傳感器控制時序

1.數據格式

DATA 用於微處理器與 DHT11之間的通訊和同步,採用單總線數據格式,一次通訊時間4ms左右,數據分小數部分和整數部分,具體格式在下面說明,當前小數部分用於以後擴展,現讀出爲零,操作流程如下:

一次完整的數據傳輸爲40bit,高位先出。

數據格式:

8bit溼度整數數據+8bit溼度小數數據+8bi溫度整數數據+8bit溫度小數數據+8bit校驗和

8位校驗和:

"8bit溼度整數數據+8bit溼度小數數據+8bi溫度整數數據+8bit溫度小數數據"相加所得結果的末8位。

 

2.控制時序

要實現對DHT11傳感器的控制和數據的讀取,需先學會分析DHT11的控制時序。時序主要分爲三部分:

  1. 觸發DHT11採集數據;

  2. 讀取數字0;

  3. 讀取數字1;

(1)觸發DHT11採集數據

總線空閒狀態爲高電平,單片機把總線拉低等待DHT11響應,單片機把總線拉低必須大於18ms,保證DHT11能檢測到起始信號。

當DHT11接收到單片機的開始信號後,等待單片機開始信號結束,然後發送80us低電平響應信號。

單片機發送開始信號結束後,延時等待20-40us後,切換爲輸入狀態,等待DHT11的80us低電平信號結束,然後判斷DHT11是否是否發出 80us 的高電平;如果是,即可開始採集數據。

(2)數字0信號時序

當DHT11輸出數字0時, 單片機讀取到的信號爲50 us的低電平,之後爲26-28 us的高電平。

(3)數字1信號時序

當DHT11輸出數字0時, 單片機讀取到的信號爲50 us的低電平,之後爲70 us的高電平。

由此可知DHT11輸出數字0和數字1的區別在於高電平的時間,由此單片機可在讀取到高電平後,延時30us後,識別此時總線的電平,高電平爲數字1,低電平爲數字0;

(4)總時序圖

用戶MCU發送一次開始信號後,DHT11從低功耗模式轉換到高速模式,等待主機開始信號結束後,DHT11發送響應信號,送出40bit的數據,並觸發一次信號採集,用戶可選擇讀取部分數據。

從模式下,DHT11接收到開始信號觸發一次溫溼度採集,如果沒有接收到主機發送開始信號,DHT11不會主動進行溫溼度採集。當一次完整的採集數據後,DHT11會轉換到低速模式。

 

四.控制程序

1.單字節採集

void  COM(void)
{
  U8 i;    
  for(i=0;i<8;i++)     
  {
    U8FLAG=2;  
    while((!P2_0)&&U8FLAG++);
    Delay_10us();
    Delay_10us();
    Delay_10us();
    U8temp=0;
     if(P2_0)U8temp=1;
      U8FLAG=2;
     while((P2_0)&&U8FLAG++);
    //超時則跳出for循環      
     if(U8FLAG==1)break;
    //判斷數據位是0還是1      
    // 如果高電平高過預定0高電平值則數據位爲 1    
     U8comdata<<=1;
     U8comdata|=U8temp;        //0
   }
}

2.完整一次數據採集

void RH(void)
{
  //主機拉低18ms 
  P2_0=0;
   Delay(180);
   P2_0=1;
   //總線由上拉電阻拉高 主機延時20us
   Delay_10us();
   Delay_10us();
   Delay_10us();
   Delay_10us();
   //主機設爲輸入 判斷從機響應信號 
   P2_0=1;
   //判斷從機是否有低電平響應信號 如不響應則跳出,響應則向下運行    
   if(!P2_0)     //T !    
   {
     U8FLAG=2;
     //判斷從機是否發出 80us 的低電平響應信號是否結束   
     while((!P2_0)&&U8FLAG++);
     U8FLAG=2;
     //判斷從機是否發出 80us 的高電平,如發出則進入數據接收狀態
     while((P2_0)&&U8FLAG++);
     //數據接收狀態     
     COM();
     U8RH_data_H_temp=U8comdata;
     COM();
     U8RH_data_L_temp=U8comdata;
    COM();
     U8T_data_H_temp=U8comdata;
     COM();
     U8T_data_L_temp=U8comdata;
     COM();
     U8checkdata_temp=U8comdata;
     P2_0=1;
     //數據校驗 
     U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
    if(U8temp==U8checkdata_temp)
     {
      U8RH_data_H=U8RH_data_H_temp;
      U8RH_data_L=U8RH_data_L_temp;
      U8T_data_H=U8T_data_H_temp;
      U8T_data_L=U8T_data_L_temp;
      U8checkdata=U8checkdata_temp;
     }
   }/
}

 

3.獲取DHT11數據

void GetTemp(void)
{
  //------------------------
   //調用溫溼度讀取子程序 
    RH();
   //串口顯示程序 
   //--------------------------
  Send_string("Humidity:");
    str[0]=U8RH_data_H/10+0x30;
    str[1]=U8RH_data_H%10+0x30;
    str[2]='.';
    str[3]=U8RH_data_L/10+0x30;
    str[4]=U8RH_data_L%10+0x30;
    str[5]='\0';
    Send_string(str);
    Send_string("%\r\n");
    
    Send_string("Temperature:");
    str[0]=U8T_data_H/10+0x30;
    str[1]=U8T_data_H%10+0x30;
    str[2]='.';
    str[3]=U8T_data_L/10+0x30;
    str[4]=U8T_data_L%10+0x30;
    str[5]='\0';
    Send_string(str);
    Send_string("℃\r\n");
}

 

發佈了21 篇原創文章 · 獲贊 4 · 訪問量 1537
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章