[TOC]
# **溫濕度傳感器設計**
板上設計了一款有已校準數字信號輸出的溫濕度傳感器:DHT11。
該傳感器是一款含有已校準數字信號輸出的溫濕度復合傳感器。它應用專用的數字模塊采集技術和溫濕度傳感技術,確保產品具有極高的可靠性不卓越的長期穩定性。傳感器包拪一個電阻式感濕元件和一個 NTC 測溫元件, 具有抗干擾能力強、性價比極高等優點。每個 DHT11 傳感器都在極 為精確的濕度校驗室中進行校準。校準系數以程序的形式儲存在 OTP 內存中, 傳感器內部在檢測信號的處理過程中要調用這些校準系數。單線制串行接口,使 系統集成變得簡易快捷。超小的體積、極低的功耗,信號傳輸距離可達 20 米以 上,產品為 4 針單排引腳封裝。連接方便,特殊封裝形式可根據我們的需求而修改。
## **DHT11外形及引腳排列**


VCC是電源腳,正電源輸入3.5-5.5V;DOUT是數據輸入/輸出腳,單總線;NC是空腳,擴展未用;GND是電源地腳。能夠同時對相對溫濕度進行檢測;輸出為數字信號,可以減少預處理信號的負擔,減輕用戶工作量;輸出為單總線結構,能夠有效減少對單片機的I/O口的占用,節省資源并且不用再額外的增加電器元件;單總線傳輸協議使單片機讀取傳感器的數據更加方便快;全部校準,為8位二進制數編碼方式。濕度測量范圍20%~90%RH;溫度測量范圍0~50℃;適用范圍廣泛,在恒濕控制、溫濕度計、消費類家電領域都有應用。
## **電路接口**

連接線長度短于20米時用5K上拉電阻;DHT11的供電電壓為 3-5.5V。傳感器上電后,要等待 1s 以越過不穩定狀態在此期間無需發送任何指令。電源引(VDD,GND)之間可增加一個100nF 的電容,用以去 耦濾波。
## **串行接口**
DATA 用于微處理器與 DHT11之間的通訊和同步,采用單總線數據格式,一次 通訊時間4ms左右,數據分小數部分和整數部分,具體格式在下面說明,當前小數 部分用于以后擴展,現讀出為零.操作流程如下:
一次完整的數據傳輸為40bit,高位先出。 數據格式:8bit濕度整數數據+8bit濕度小數數據 +8bi溫度整數數據+8bit溫度小數數據
+8bit校驗和 數據傳送正確時校驗和數據等于“8bit濕度整數數據+8bit濕度小數數據
+8bi溫度整數數據+8bit溫度小數數據”所得結果的末8位。 用戶MCU發送一次開始信號后,DHT11從低功耗模式轉換到高速模式,等待主
機開始信號結束后,DHT11發送響應信號,送出40bit的數據,并觸發一次信號采集, 用戶可選擇讀取部分數據.從模式下,DHT11接收到開始信號觸發一次溫濕度采集, 如果沒有接收到主機發送開始信號,DHT11不會主動進行溫濕度采集.采集數據后 轉換到低速模式。
### 通訊過程如圖所示

總線空閑狀態為高電平,主機把總線拉低等待DHT11響應,主機把總線拉低必
須大于18毫秒,保證DHT11能檢測到起始信號。DHT11接收到主機的開始信號后, 等待主機開始信號結束,然后發送80us低電平響應信號.主機發送開始信號結束 后,延時等待20-40us后, 讀取DHT11的響應信號,主機發送開始信號后,可以切換 到輸入模式,或者輸出高電平均可, 總線由上拉電阻拉高。

總線為低電平,說明DHT11發送響應信號,DHT11發送響應信號后,再把總線拉 高80us,準備發送數據,每一bit數據都以50us低電平時隙開始,高電平的長短定 了數據位是0還是1.格式見下面圖示.如果讀取響應信號為高電平,則DHT11沒有 響應,請檢查線路是否連接正常.當最后一bit數據傳送完畢后,DHT11拉低總線 50us,隨后總線由上拉電阻拉高進入空閑狀態。
### 數字0信號表示方法如圖所示

DHT11先把總線拉低12-14us然后拉高,高電平保持時間在26-28us范圍內,則此時為‘0’電平
### 數字1信號表示方法

DHT11先把總線拉低12-14us然后拉高,高電平保持時間在116-118us范圍內,則此時為‘1’電平。本次設計的程序是在高電平延時30us之后讀取,如果還是低電平,則輸出‘0’,如果是高電平,則輸出‘1’。
## **編程代碼**
~~~
#ifndef _DHT11_H__ //防止重載
#define _DHT11_H__
sbit p33= P3^7; //溫度數據線,根據個人情況修改
void Delay(U16 j) //100us延時
{
U8 i;
for(;j>0;j--)
{
for(i=0;i<27;i++);
}
}
void Delay_10us(void) //進入函數3us
{
U8 i; //1us
i--; //1us
i--;
i--;
i--;
i--;
i--;
}
void COM(void) //串行讀一個字節數據
{
U8 i;
for(i=0;i<8;i++)
{
U8FLAG=2;
while((!p33)&&U8FLAG++);//自加254次 默認執行下面程序 50us低電平結束判斷
Delay_10us();
Delay_10us();
Delay_10us();
U8temp=0; //判斷數據位是0還是1 如果高電平高過預定0高電平值則數據位為 1
if(p33)U8temp=1;
U8FLAG=2;
while((p33)&&U8FLAG++); //等待0/1高電平信號結束
//超時則跳出for循環
// if(U8FLAG==1)break; //經歷255us 在這里不會執行
U8comdata<<=1;
U8comdata|=U8temp;
}
}
void RH(void)
{
//主機拉低18ms
p33=0;
Delay(180);
p33=1;
//總線由上拉電阻拉高 主機延時20us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
//主機設為輸入 判斷從機響應信號
p33=1;
//判斷從機是否有低電平響應信號 如不響應則不讀數據,響應則向下運行
if(!p33) //p20==0往下執行
{
U8FLAG=2;
//判斷從機發出 80us 的低電平響應信號是否結束
while((!p33)&&U8FLAG++); //強制低電平信號最長為254us
U8FLAG=2;
//判斷從機發出 80us 的高電平,如發出則進入數據接收狀態
while((p33)&&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;
p33=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; //低八位為0
U8T_data_H=U8T_data_H_temp;
U8T_data_L=U8T_data_L_temp; //低八位為0
U8checkdata=U8checkdata_temp;
}
}
}
#endif
~~~
## 參考文獻
1.如何選擇好的溫濕度傳感器 http://www.chinabaike.com/z/yiqi/2011/0215/292956.html
2.溫濕度傳感器,不一樣的未來,你曉得么? http://sensor.ofweek.com/2016-03/ART-81002-8420-29075960.html