👨?💻個人主頁:@開發者-削好皮的Pineapple!
👨?💻 hello 歡迎 點贊👍 收藏? 留言📝 加關注?!
👨?💻 本文由 削好皮的Pineapple! 原創
👨?💻 收錄于專欄:C語言到基于STM32 的智能礦探小車
文章目錄
- ?前言?
- 🎶一、DHT11模塊硬件連接
- 🎶二、DHT11模塊工作原理及數據格式
- 1. 工作原理
- 2. 數據傳輸時序
- (1)整體時序
- (2)響應與數據準備階段
- (3)數據位表示方法
- 3. 數據格式
- 🎶三、DHT11獲取溫濕度代碼實現
- 1. 頭文件(dht11.h)
- 2. 源文件(dht11.c)
- 結束語🥇
?前言?
在嵌入式開發中,溫濕度檢測是許多項目的基礎功能,DHT11模塊因其操作簡便、成本較低等特點,常被用于溫濕度數據的采集。本文將圍繞基于STM32的DHT11模塊溫濕度檢測展開介紹,幫助開發者了解相關硬件連接、工作原理、數據格式及代碼實現。
🎶一、DHT11模塊硬件連接
DHT11模塊與開發板的連接較為簡單,具體接線方式如下:
- vcc(+) --------- 3v3 / 5v:模塊電源引腳,可連接開發板的3.3V或5V電源
- GND(-) --------- GND:模塊接地引腳,連接開發板的GND
- DAT(out) ------- GPIO引腳上:模塊數據輸出引腳,開發板上自帶的DHT11模塊的DATA接在PG9上
通過以上連接,可實現DHT11模塊與開發板之間的通信,為后續的數據采集做好硬件準備。有關更詳細的硬件參數等信息,可參考手冊《DHT11說明書最新版.pdf》。
🎶二、DHT11模塊工作原理及數據格式
1. 工作原理
總線空閑狀態為高電平,當主機需要獲取溫濕度數據時,會把總線拉低,且拉低時間必須大于18毫秒,以保證DHT11能檢測到起始信號。
DHT11接收到主機的開始信號后,會等待主機開始信號結束,然后發送80us低電平響應信號。
主機發送開始信號結束后,延時等待20-40us,之后就可以讀取DHT11的響應信號。主機發送開始信號后,可以切換到輸入模式,或者輸出高電平均可,此時總線由上拉電阻拉高。
2. 數據傳輸時序
(1)整體時序
一次完整的數據傳輸包含起始信號、響應信號及數據傳輸階段,時序圖如下:
總線空閑狀態為高電平,主機拉低總線>18ms發送起始信號;DHT11收到后,先發送80us低電平響應,再拉高80us準備發送數據。
(2)響應與數據準備階段
- 總線為低電平時,說明DHT11發送響應信號;
- 響應后總線拉高80us,進入數據發送準備階段;
- 每一bit數據以50us低電平時隙開始,高電平持續時間決定數據位是0還是1;
- 若讀取響應信號為高電平,說明DHT11無響應,需檢查線路;
- 最后一bit數據傳送完畢后,DHT11拉低總線50us,隨后總線由上拉電阻拉高進入空閑狀態。
(3)數據位表示方法
-
數字0信號:低電平50us后,高電平持續26-28us,時序圖如下:
-
數字1信號:低電平50us后,高電平持續70us,時序圖如下:
3. 數據格式
一次完整的數據傳輸為40bit,高位先出,格式為:
8bit濕度整數數據 + 8bit濕度小數數據 + 8bit溫度整數數據 + 8bit溫度小數數據 + 8bit校驗和
- 校驗和 = 濕度整數 + 濕度小數 + 溫度整數 + 溫度小數
- 通過校驗和可驗證數據傳輸的正確性。
🎶三、DHT11獲取溫濕度代碼實現
1. 頭文件(dht11.h)
#ifndef __DHT11_H_
#define __DHT11_H_//dht11初始化接口
void dht11_init(void);extern unsigned char dht11_data[5];
void dht11_read_data(void);#endif
2. 源文件(dht11.c)
#include "stm32f4xx.h"
#include "dht11.h"
#include "delay.h"//DHT11的data引腳接在PG9上
#define DHT11_RCC RCC_AHB1Periph_GPIOG
#define DHT11_PORT GPIOG
#define DHT11_PIN GPIO_Pin_9 //GPIO引腳模式切換
//m=1:輸出模式;m=0:輸入模式
void gpio_mode_changed(int m)
{//使能時鐘RCC_AHB1PeriphClockCmd(DHT11_RCC, ENABLE);GPIO_InitTypeDef GPIO_InitStruct;if(m) //輸出模式配置{GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;GPIO_InitStruct.GPIO_Pin = DHT11_PIN;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;}else //輸入模式配置{GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;GPIO_InitStruct.GPIO_Pin = DHT11_PIN;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;}GPIO_Init(DHT11_PORT, &GPIO_InitStruct);
}//dht11初始化接口
void dht11_init(void)
{gpio_mode_changed(1) ; //初始化為輸出模式GPIO_SetBits(DHT11_PORT, DHT11_PIN); //DATA引腳默認拉高
}//dht11發送起始信號
void dht11_start(void)
{gpio_mode_changed(1); //配置為輸出模式GPIO_ResetBits(DHT11_PORT, DHT11_PIN); //拉低總線>18msdelay_ms(18);GPIO_SetBits(DHT11_PORT, DHT11_PIN); //釋放總線delay_us(30); //等待20-40usgpio_mode_changed(0); //切換為輸入模式//等待DHT11響應while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == SET);//等待響應結束while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == RESET);//等待數據發送開始while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == SET);
}//讀取一個字節數據
unsigned char dht11_read_byte(void)
{gpio_mode_changed(0); //配置為輸入模式unsigned char d = 0; //存儲讀取到的字節for(int i = 0; i < 8; i++){//等待50us低電平時隙結束while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == RESET);//延時35us:區分0和1(0的高電平≤28us,1的高電平≈70us)delay_us(35);//若仍為高電平,則為1if(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == SET){d |= (1 << (7 - i)); //高位先存}//等待當前bit的高電平結束while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == SET);}return d;
}//讀取溫濕度數據
unsigned char dht11_data[5] = {0}; //存儲:濕度整+濕小小+溫度整+溫度小+校驗和
void dht11_read_data(void)
{dht11_start(); //發送起始信號//讀取40bit數據(5個字節)for(int i = 0; i < 5; i++){dht11_data[i] = dht11_read_byte();}
}
結束語🥇
🔥 訂閱專欄持續學習:C語言到基于STM32的智能礦探小車
💬 歡迎點贊、收藏、留言討論,一起攻克嵌入式開發!