DHT溫濕度傳感器的基本探究
掃描二維碼
隨時隨地手機(jī)看文章
作為物聯(lián)網(wǎng)IOT的Things,溫濕度傳感器也是一個重要的研究對象。本文以DHT11為主要的研究對象,通過對該傳感器的研究,分析一下具體的使用方法。
1. 說明
DHT11數(shù)字溫濕度傳感器是一款含有已校準(zhǔn)數(shù)字信號輸出的溫濕度復(fù)合傳感器
采集范圍:溫度0-50°±2°,濕度:20-90%RH。
供電電壓:5V。
外觀如下圖所示:

2. 工作原理
對于DHT11傳感器的工作原理,首先需要從典型的應(yīng)用電路說起

數(shù)字溫濕度傳感器采用單數(shù)據(jù)格式,單個數(shù)據(jù)引腳完成輸入輸出單向傳輸。
2.1 工作時序
由于DHT11需要與主控進(jìn)行通信,所以必須要涉及到通信時序。也就是約定好通信規(guī)則。那么對于DHT11溫濕度傳感器的通信時序又是怎樣的呢?
該傳感器通信是通過奧松電子有限公司開發(fā)的單總線協(xié)議和主控進(jìn)行數(shù)據(jù)通信??梢苑譃橐韵滤膫€步驟
(1)主機(jī)發(fā)起開始信號
(2)主機(jī)等待接收DHT11響應(yīng)信號
(3)主機(jī)連續(xù)接收40Bit數(shù)據(jù)和校驗和
(4)主機(jī)進(jìn)行數(shù)據(jù)處理

從上圖可以看到,當(dāng)主機(jī)首先需要將DATA線上的信號拉低至少18ms,以保證DHT能夠正常檢測到起始信號,當(dāng)主機(jī)拉高20-40us后,主機(jī)起始信號結(jié)束。此時,主機(jī)引腳作為輸入,檢測傳感器輸出過來的數(shù)據(jù)。
傳感器也需要回應(yīng)數(shù)據(jù),首先將DATA線上的信號拉低40-50us,然后再拉高40-50us。主控接收到準(zhǔn)備信號后,再開始接收數(shù)據(jù)。
數(shù)據(jù)”0“的表示

數(shù)據(jù)“0”,首先DHT把總線拉低12-14us然后拉高,高電平保持在26-28us這個范圍。表示“0”。
數(shù)據(jù)“1”的表示

數(shù)字“1”,首先DHT把總線拉低12-14us然后拉高,高電平保持在116-118us這個范圍。表示“1”。
2.2 數(shù)據(jù)格式
DHT單向數(shù)據(jù)傳輸?shù)臄?shù)據(jù)量大小為5Byte(40bit)。一次通信時長約為3ms。
濕度整數(shù) | 濕度小數(shù) | 溫度整數(shù) | 溫度小數(shù) | 校驗和(數(shù)據(jù)相加) |
---|---|---|---|---|
8bit | 8bit | 8bit | 8bit | 8bit |
數(shù)據(jù)處理
傳感器的數(shù)據(jù)從高位到低位傳輸

那么從上述的數(shù)據(jù)可以得到計算公式如下

3. 代碼實現(xiàn)
因為采用STM32的主控作為測試,所以需要選定特定的引腳做輸入輸出。這里可以采用位帶操作的方式。
3.1 DHT初始化
初始化其實就是配置GPIO引腳功能的作用
可以將引腳先配置為輸出即可。
3.2 向DHT1發(fā)出起始信號
void DHT11_Rst(void) {
DHT11_IO_OUT(); //SET OUTPUT DHT11_DQ_OUT=0; //GPIOA.0=0 Delay_ms(20); //Pull down Least 18ms DHT11_DQ_OUT=1; //GPIOA.0=1 Delay_us(30); //Pull up 20~40us }
3.3 讀1 bit的數(shù)據(jù)
u8 DHT11_Read_Bit(void) {
u8 retry=0; while(DHT11_DQ_IN&&retry<100) //wait become Low level {
retry++;
Delay_us(1);
}
retry=0; while(!DHT11_DQ_IN&&retry<100) //wait become High level {
retry++;
Delay_us(1);
}
Delay_us(40);//wait 40us if(DHT11_DQ_IN) return 1; else return 0;
}
3.4 讀一個字節(jié)的數(shù)據(jù)
u8 DHT11_Read_Byte(void) {
u8 i,dat;
dat=0; for (i=0;i<8;i++)
{
dat<<=1;
dat|=DHT11_Read_Bit();
} return dat;
}
3.4 讀溫濕度數(shù)據(jù)
u8 DHT11_Read_Data(u8 *temperature,u8 *humidity) {
u8 buf[5];
u8 i;
DHT11_Rst(); if(DHT11_Check()==0)
{ for(i=0;i<5;i++)
{
buf[i]=DHT11_Read_Byte();
} if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
*humidity=buf[0];
*temperature=buf[2];
}
} else return 1; return 0;
}
4.效果演示
我在main函數(shù)中通過每1ms采集一次數(shù)據(jù)通過串口打印出來,在串口調(diào)試助手上可以看到溫濕度的信息。

上述演示中,并未取小數(shù)部分?jǐn)?shù)據(jù)。
5.調(diào)試心得
在調(diào)試過程中也遇到一些問題,特別的留意一下。
(1)配置gpio時,不要忘記開啟相應(yīng)的時鐘,否則不起作用。
(2)對于有引腳復(fù)用的模式,比如JTAG,需要先禁止掉JTAG模式接口
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); // 改變指定管腳的映射 GPIO_Remap_SWJ_Disable SWJ 完全禁用(JTAG+SW-DP) GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); // 改變指定管腳的映射 GPIO_Remap_SWJ_JTAGDisable ,JTAG-DP 禁用 + SW-DP 使能
(3)DHT的數(shù)據(jù)引腳,主控這邊輸出的時候,就配置成推挽輸出模式,當(dāng)配置為輸入的時候,就配置成上拉輸入模式。
(4)準(zhǔn)守下面的原則基本不會出錯
1.復(fù)位的時候,主機(jī)向程序發(fā)送數(shù)據(jù),也就是MCU會發(fā)送一定的指令到dht11上
2.檢測狀態(tài),這里就是從機(jī)的應(yīng)答狀態(tài),這里的應(yīng)答狀態(tài)會直接看出是否該引腳有效
3.數(shù)據(jù)的讀出
4.Bit位的組合狀態(tài)