「正點原子NANO STM32開發板資料連載」第28章 數字溫溼度傳感器

1)實驗平臺:alientek NANO STM32F411 V1開發板

2)摘自《正點原子STM32F4 開發指南(HAL 庫版》關注官方微信號公眾號,獲取更多資料:正點原子

「正點原子NANO STM32開發板資料連載」第28章 數字溫溼度傳感器

第二十八章 DHT11 數字溫溼度傳感器實驗

上一章,我們介紹了數字溫度傳感器 DS18B20 的使用,本章我們將介紹數字溫溼度傳感器DHT11 的使用,該傳感器不但能測溫度,還能測溼度。本章我們將向大家介紹如何使用 STM32F4來讀取DHT11 數字溫溼度傳感器,從而得到環境溫度和溼度等信息,並把從溫溼度值顯示在數碼管上。本章分為如下幾個部分:

28.1 DHT11 簡介

28.2 硬件設計

28.3 軟件設計

28.4 下載驗證

28.1 DHT11 簡介

DHT11 是一款溼溫度一體化的數字傳感器。該傳感器包括一個電阻式測溼元件和一個 NTC測溫元件,並與一個高性能 8 位單片機相連接。通過單片機等微處理器簡單的電路連接就能夠實時的採集本地溼度和溫度。DHT11 與單片機之間能採用簡單的單總線進行通信,僅僅需要一個 I/O 口。傳感器內部溼度和溫度數據 40Bit 的數據一次性傳給單片機,數據採用校驗和方式進行校驗,有效的保證數據傳輸的準確性。DHT11 功耗很低,5V 電源電壓下,工作平均最大電流 0.5mA。

DHT11 的技術參數如下:

工作電壓範圍:3.3V-5.5V

工作電流 :平均 0.5mA

輸出:單總線數字信號

測量範圍:溼度 20~90%RH,溫度 0~50℃

精度 :溼度±5%,溫度±2℃

分辨率 :溼度 1%,溫度 1℃

DHT11 的管腳排列如圖 28.1.1 所示:

「正點原子NANO STM32開發板資料連載」第28章 數字溫溼度傳感器

圖 28.1.1 DHT11 管腳排列圖

雖然 DHT11 與 DS18B20 類似,都是單總線訪問,但是 DHT11 的訪問,相對 DS18B20 來

說要簡單很多。下面我們先來看看 DHT11 的數據結構。

DHT11 數字溼溫度傳感器採用單總線數據格式。即,單個數據引腳端口完成輸入輸出雙向

傳輸。其數據包由 5Byte(40Bit)組成。數據分小數部分和整數部分,一次完整的數據傳輸為

40bit,高位先出。DHT11 的數據格式為:8bit 溼度整數數據+8bit 溼度小數數據+8bit 溫度整數

數據+8bit 溫度小數數據+8bit 校驗和。其中校驗和數據為前四個字節相加。

傳感器數據輸出的是未編碼的二進制數據。數據(溼度、溫度、整數、小數)之間應該分開

處理。例如,某次從 DHT11 讀到的數據如圖 28.1.2 所示:

「正點原子NANO STM32開發板資料連載」第28章 數字溫溼度傳感器

圖 28.1.2 某次讀取到 DHT11 的數據

由以上數據就可得到溼度和溫度的值,計算方法:

溼度= byte4 . byte3=45.0 (%RH)

溫度= byte2 . byte1=28.0 ( ℃)

校驗= byte4+ byte3+ byte2+ byte1=73(=溼度+溫度)(校驗正確)

可以看出,DHT11 的數據格式是十分簡單的,DHT11 和 MCU 的一次通信最大為 3ms 左右,

建議主機連續讀取時間間隔不要小於 100ms。

下面,我們介紹一下 DHT11 的傳輸時序。DHT11 的數據發送流程如圖 27.1.3 所示:


「正點原子NANO STM32開發板資料連載」第28章 數字溫溼度傳感器

圖 28.1.3 DHT11 數據發送流程

首先主機發送開始信號,即:拉低數據線,保持 t1(至少 18ms)時間,然後拉高數據線 t2

(20~40us)時間,然後讀取 DHT11 的響應,正常的話,DHT11 會拉低數據線,保持 t3(40~50us)

時間,作為響應信號,然後 DHT11 拉高數據線,保持 t4(40~50us)時間後,開始輸出數據。

DHT11 輸出數字‘0’的時序如圖 28.1.4 所示:

「正點原子NANO STM32開發板資料連載」第28章 數字溫溼度傳感器

圖 27.1.4 DHT11 數字‘0’時序

DHT11 輸出數字‘1’的時序如圖 28.1.5 所示:

「正點原子NANO STM32開發板資料連載」第28章 數字溫溼度傳感器

圖 28.1.5 DHT11 數字‘1’時序

通過以上了解,我們就可以通過 STM32 來實現對 DHT11 的讀取了。DHT11 的介紹就到這

裡,更詳細的介紹,請參考 DHT11 的數據手冊。

28.2 硬件設計

由於開發板上標準配置是沒有 DHT11 這個傳感器的,只有接口,所以要做本章的實驗,

大家必須找一個 DHT11 插在預留的 DHT11 接口上。

本章實驗功能簡介:開機的時候先檢測是否有 DHT11 存在,如果沒有,則串口打印提示

錯誤,並且DS3快速閃爍。只有在檢測到DHT11之後才開始讀取溫溼度值,如果發現了DHT11,

則程序每隔 1s 左右讀取一次數據,並把溫溼度顯示在數碼管上。同樣我們也是用 DS0 來指示

程序正在運行。

所要用到的硬件資源如下:

1) 指示燈 DS0、DS3

2) 數碼管

3) DHT11 溫溼度傳感器

這些我們都已經介紹過了,DHT11 和 DS18B20 的接口是共用一個的,不過 DHT11 有 4 條

腿,需要把 U2 的 4 個接口都用上,將 DHT11 傳感器插入到這個上面就可以通過 STM32F1 來

讀取溫溼度值了。連接示意圖如圖 28.2.1 所示:

「正點原子NANO STM32開發板資料連載」第28章 數字溫溼度傳感器

圖 28.2.1 DHT11 連接示意圖

這裡要注意,將 DHT11 貼有字的一面朝內,而有很多孔的一面(網面)朝外,然後然後插入

如圖所示的四個孔內就可以了。

28.3 軟件設計

打開 DHT11 數字溫溼度傳感器實驗工程可以發現,我們在工程中添加了 dht11.c 文件和

dht11.h 文件,所有 DHT11 相關的驅動代碼和定義都在這兩個文件中。

打開 dht11.c 代碼如下:

//復位 DHT11

void DHT11_Rst(void)

{

DHT11_IO_OUT();

//設置為輸出

DHT11_DQ_OUT=0; //拉低 DQ

delay_ms(20);

//拉低至少 18ms

DHT11_DQ_OUT=1; //DQ=1

delay_us(30);

//主機拉高 20~40us

}

//等待 DHT11 的回應

//返回 1:未檢測到 DHT11 的存在

//返回 0:存在

u8 DHT11_Check(void)

{

u8 retry=0;

DHT11_IO_IN();

//設置為輸出

while (DHT11_DQ_IN&&retry<100)//DHT11 會拉低 40~80us

{

retry++;

delay_us(1);

};

if(retry>=100)return 1;

else retry=0;

while (!DHT11_DQ_IN&&retry<100)//DHT11 拉低後會再次拉高 40~80us

{

retry++;

delay_us(1);

};

if(retry>=100)return 1;

return 0;

}

//從 DHT11 讀取一個位

//返回值:1/0

u8 DHT11_Read_Bit(void)

{

u8 retry=0;

while(DHT11_DQ_IN&&retry<100)//等待變為低電平

{

retry++;

delay_us(1);

}

retry=0;

while(!DHT11_DQ_IN&&retry<100)//等待變高電平

{

retry++;

delay_us(1);

}

delay_us(40);//等待 40us

if(DHT11_DQ_IN)return 1;

else return 0;

}

//從 DHT11 讀取一個字節

//返回值:讀到的數據

u8 DHT11_Read_Byte(void)

{

u8 i,dat;

dat=0;

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

{

dat<<=1;

dat|=DHT11_Read_Bit();

}

return dat;

}

//從 DHT11 讀取一次數據

//temp:溫度值(範圍:0~50°)

//humi:溼度值(範圍:20%~90%)

//返回值:0,正常;1,讀取失敗

u8 DHT11_Read_Data(u8 *temp,u8 *humi)

{

u8 buf[5];

u8 i;

DHT11_Rst();

if(DHT11_Check()==0)

{

for(i=0;i<5;i++)//讀取 40 位數據

{

buf[i]=DHT11_Read_Byte();

}

if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])

{

*humi=buf[0];

*temp=buf[2];

}

}else return 1;

return 0;

}

//初始化 DHT11 的 IO 口 DQ 同時檢測 DHT11 的存在

//返回 1:不存在

//返回 0:存在

u8 DHT11_Init(void)

{

GPIO_InitTypeDef GPIO_Initure;

__HAL_RCC_GPIOB_CLK_ENABLE();

//開啟 GPIOB 時鐘

GPIO_Initure.Pin=GPIO_PIN_9;

//PB9

GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推輓輸出

GPIO_Initure.Pull=GPIO_PULLUP;

//上拉

GPIO_Initure.Speed=GPIO_SPEED_HIGH;

//高速

HAL_GPIO_Init(GPIOB,&GPIO_Initure);

//初始化

DHT11_Rst();

return DHT11_Check();

}

該部分代碼首先是通過函數 DHT11_Init 初始化傳感器,然後根據我們前面介紹的單總線

操作時序來讀取 DHT11 的溫溼度值的,DHT11 的溫溼度值通過 DHT11_Read_Data 函數讀取,如

果返回 0,則說明讀取成功,返回 1,則說明讀取失敗。同樣我們打開 dht11.h 可以看到,頭文

件中主要是一些端口配置以及函數申明,代碼比較簡單。 接下來我們打開 main.c,該文件代

碼如下:

// 共陰數字數組

// 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, .,全滅

u8 smg_num[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,

0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e,0x01,0x00};

u8 smg_wei=2;//數碼管位選

u8 num=0;//數值

u16 led_t=0;//led 統計時間

u16 dht11_t=0;//dht11 採樣時間

u8 temperature;//溫度值

u8 humidity;//溼度值

int main(void)

{

HAL_Init();

//初始化 HAL 庫

Stm32_Clock_Init(96,4,2,4);

//設置時鐘,96Mhz

delay_init(96);

//初始化延時函數

LED_Init();

//初始化 LED

LED_SMG_Init();

//數碼管初始化

uart_init(115200);

//串口初始化為 115200

printf("NANO STM32\r\n");

printf("DHT11 TEST\r\n");

while(DHT11_Init())

//DHT11 初始化

{

printf("DHT11 Error\r\n");

delay_ms(200);

LED3=!LED3;//LED3 閃爍表示 DHT11 初始化失敗

}

LED3=1;

printf("DHT11 OK\r\n");

TIM3_Init(19,7199);//數碼管 2ms 定時顯示

while(1)

{

}

}

//回調函數,定時器中斷服務函數調用

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

if(htim==(&TIM3_Handler))

{

dht11_t++;

if(dht11_t==500)//DHT11 1S 採樣

{

dht11_t=0;

DHT11_Read_Data(&temperature,&humidity);//讀取溫溼度值

}

switch(smg_wei)

{

case 2: num = smg_num[temperature/10]; break;//溫度值

case 3: num =smg_num[temperature%10];break;

case 6: num = smg_num[humidity/10]; break;//溼度值

case 7: num =smg_num[humidity%10];break;

}

LED_Write_Data(num,smg_wei);//寫數據到數碼管

LED_Refresh();//更新顯示

smg_wei++;

if(smg_wei==4) smg_wei=6;

if(smg_wei==8) smg_wei=2;

led_t++;

if(led_t==250)//LED0 每 500ms 閃爍

{

led_t=0;

LED0=!LED0;

}

}

}

從上面代碼可以看到,DHT11 溫溼度的讀取跟 DS18B20 實驗同樣在定時器中斷執行,以每

隔 1S 時間採集溫度和溼度,數碼管同樣是以 2ms 時間動態掃描顯示,DS0 以每 500ms 閃爍一次,

以表示程序正在運行。

至此,我們本章的軟件設計就結束了。

28.4 下載驗證

在代碼編譯成功之後,我們通過下載代碼到 ALIENTEK NANO STM32F4 開發板上,可以

看到數碼管顯示當前的溫溼度值(假定 DHT11 已經接上去了),如圖 28.4.1 所示:

「正點原子NANO STM32開發板資料連載」第28章 數字溫溼度傳感器

圖 28.4.1 DHT11 讀取到的溫溼度值

至此,本章實驗結束。大家可以將本章通過 DHT11 讀取到的溫度值,和前一章的通過

DS18B20 讀取到的溫度值對比一下,看看哪個更準確?


分享到:


相關文章: