STM32 HAL驱动DHT11温湿度传感器完整指南
约 1127 字大约 4 分钟
2025-08-05
STM32 HAL驱动DHT11温湿度传感器完整指南
📋 前言
DHT11数字温湿度传感器是一款经过校准的复合型传感器,提供数字信号输出。采用专用数字采集技术和温湿度传感技术,确保产品具有卓越的可靠性和长期稳定性。广泛应用于:
- 🏠 暖通空调系统
- 🌾 智能农业监控
- 🚚 冷链物流仓储
- 🏡 智能家居设备
- 🏥 医疗设备

🔧 模块基础知识
1.1 引脚定义与连接

| 引脚 | 功能 | 电压范围 | 说明 |
|---|---|---|---|
| VCC | 电源 | 3.3V-5.5V | 供电正极 |
| GND | 地线 | 0V | 供电负极 |
| DAT | 数据 | - | 单总线数据线 |
⚠️ 重要提醒
上拉电阻连接 数据线(引脚2)需要上拉电阻,部分模块已集成,无需外接。
电路连接示例
1.2 数据格式详解
- 通讯方式:单总线协议
- 数据长度:40位数据,高位先出
- 数据格式:
[8位湿度整数][8位湿度小数][8位温度整数][8位温度小数][8位校验和]

📡 通讯协议时序
2.1 通讯流程
- 主机起始信号:STM32拉低数据线≥18ms
- 传感器响应:DHT11拉低80μs,再拉高80μs
- 数据传输:40位数据逐位发送

💻 代码实现
3.1 GPIO初始化
// DHT11引脚定义
#define DHT11_GPIO_CLK() __HAL_RCC_GPIOB_CLK_ENABLE()
#define DHT11_GPIO GPIOB
#define DHT11_PIN GPIO_PIN_11
/**
* @brief 配置DHT11引脚为输出模式
* @retval None
*/
void DHT11_OUTPUT(void) {
GPIO_InitTypeDef gpio_initstruct;
DHT11_GPIO_CLK();
gpio_initstruct.Pin = DHT11_PIN;
gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP;
gpio_initstruct.Pull = GPIO_PULLUP;
gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(DHT11_GPIO, &gpio_initstruct);
}
/**
* @brief 配置DHT11引脚为输入模式
* @retval None
*/
void DHT11_INPUT(void) {
GPIO_InitTypeDef gpio_initstruct;
DHT11_GPIO_CLK();
gpio_initstruct.Pin = DHT11_PIN;
gpio_initstruct.Mode = GPIO_MODE_INPUT;
gpio_initstruct.Pull = GPIO_PULLUP;
gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(DHT11_GPIO, &gpio_initstruct);
}3.2 启动信号
/**
* @brief 发送DHT11启动信号
* @retval None
*/
void DHT11_Start(void) {
DHT11_OUTPUT();
HAL_GPIO_WritePin(DHT11_GPIO, DHT11_PIN, GPIO_PIN_RESET);
delay_ms(20); // 拉低至少18ms
HAL_GPIO_WritePin(DHT11_GPIO, DHT11_PIN, GPIO_PIN_SET);
delay_us(30); // 拉高20-40μs
DHT11_INPUT(); // 切换为输入模式
delay_us(160); // 等待传感器响应
}💡 时序说明
主机拉低20ms后释放,DHT11将在160μs内开始响应。
3.3 数据读取
static uint8_t DHT11_buff[5]; // 存储40位数据
/**
* @brief 读取DHT11传感器数据
* @retval 读取成功返回1,失败返回0
*/
uint8_t DHT11_Read(void) {
uint8_t i, j;
for (j = 0; j < 5; j++) {
DHT11_buff[j] = 0;
for (i = 0; i < 8; i++) {
uint32_t timeout = 1000;
// 等待低电平结束
while (HAL_GPIO_ReadPin(DHT11_GPIO, DHT11_PIN) == GPIO_PIN_RESET && timeout--);
if (timeout == 0) return 0;
delay_us(40); // 判断数据位
if (HAL_GPIO_ReadPin(DHT11_GPIO, DHT11_PIN) == GPIO_PIN_SET) {
DHT11_buff[j] |= (1 << (7 - i));
}
timeout = 1000;
// 等待高电平结束
while (HAL_GPIO_ReadPin(DHT11_GPIO, DHT11_PIN) == GPIO_PIN_SET && timeout--);
if (timeout == 0) return 0;
}
}
return 1;
}3.4 数据校验
/**
* @brief 校验DHT11数据完整性
* @retval 校验成功返回1,失败返回0
*/
uint8_t DHT11_check(void) {
uint8_t sum = 0;
for (uint8_t i = 0; i < 4; i++) {
sum += DHT11_buff[i];
}
return (sum == DHT11_buff[4]);
}3.5 获取温湿度数据
/**
* @brief 获取DHT11温湿度数据
* @param temperature: 温度值存储指针
* @param humidity: 湿度值存储指针
* @retval None
*/
void DHT11_GetData(uint8_t *temperature, uint8_t *humidity) {
DHT11_Start();
if (DHT11_Read() && DHT11_check()) {
*humidity = DHT11_buff[0]; // 湿度整数部分
*temperature = DHT11_buff[2]; // 温度整数部分
} else {
*humidity = 0;
*temperature = 0;
}
}📁 完整代码文件
DHT11.h - 头文件
#ifndef _H_DHT11_
#define _H_DHT11_
#include "sys.h"
#include "delay.h"
#include "stdio.h"
// 引脚定义
#define DHT11_GPIO_CLK() __HAL_RCC_GPIOB_CLK_ENABLE()
#define DHT11_GPIO GPIOB
#define DHT11_PIN GPIO_PIN_11
// 函数声明
void DHT11_GetData(uint8_t *temperature, uint8_t *humidity);
uint8_t DHT11_check(void);
#endif /* _H_DHT11_ */DHT11.c - 实现文件
包含上述所有函数的实现...
🚀 使用示例
main.c 完整示例
#include "sys.h"
#include "uart1.h"
#include "delay.h"
#include "oled.h"
#include "font.h"
#include "SR04.h"
#include "DHT11.h"
uint8_t temperature = 0;
uint8_t humidity = 0;
int main(void) {
HAL_Init();
stm32_clock_init(RCC_PLL_MUL9);
// 初始化外设
led_init();
uart1_init(115200);
SR04_GPIO_Config();
OLED_Init();
printf("DHT11温湿度传感器测试程序启动...\r\n");
float distance = 0;
char display_buffer[64];
delay_ms(1000); // 等待传感器稳定
while (1) {
// 读取温湿度数据
DHT11_GetData(&temperature, &humidity);
// 串口输出
printf("温度: %d°C, 湿度: %d%%\r\n", temperature, humidity);
// 超声波测距
distance = SR04_distance();
printf("距离: %.2f cm\r\n", distance);
// OLED显示
OLED_NewFrame();
sprintf(display_buffer, "Temp: %d°C", temperature);
OLED_PrintASCIIString(0, 10, display_buffer, &afont8x6, OLED_COLOR_NORMAL);
sprintf(display_buffer, "Humidity: %d%%", humidity);
OLED_PrintASCIIString(0, 20, display_buffer, &afont8x6, OLED_COLOR_NORMAL);
sprintf(display_buffer, "Distance: %.1fcm", distance);
OLED_PrintASCIIString(0, 30, display_buffer, &afont8x6, OLED_COLOR_NORMAL);
OLED_ShowFrame();
delay_ms(1000); // 1秒刷新一次
}
}📊 运行效果



主机拉低20ms后释放,DHT11将在160μs内开始响应。