Skip to content

STM32 HAL驱动DHT11温湿度传感器完整指南

约 1127 字大约 4 分钟

2025-08-05

STM32 HAL驱动DHT11温湿度传感器完整指南

📋 前言

DHT11数字温湿度传感器是一款经过校准的复合型传感器,提供数字信号输出。采用专用数字采集技术和温湿度传感技术,确保产品具有卓越的可靠性和长期稳定性。广泛应用于:

  • 🏠 暖通空调系统
  • 🌾 智能农业监控
  • 🚚 冷链物流仓储
  • 🏡 智能家居设备
  • 🏥 医疗设备
DHT11传感器实物图
DHT11传感器实物图

🔧 模块基础知识

1.1 引脚定义与连接

DHT11引脚图
DHT11引脚图
引脚功能电压范围说明
VCC电源3.3V-5.5V供电正极
GND地线0V供电负极
DAT数据-单总线数据线

⚠️ 重要提醒

上拉电阻连接
上拉电阻连接

数据线(引脚2)需要上拉电阻,部分模块已集成,无需外接。

电路连接示例
电路连接示例

1.2 数据格式详解

  • 通讯方式:单总线协议
  • 数据长度:40位数据,高位先出
  • 数据格式
    [8位湿度整数][8位湿度小数][8位温度整数][8位温度小数][8位校验和]
数据格式示意图
数据格式示意图

📡 通讯协议时序

2.1 通讯流程

  1. 主机起始信号:STM32拉低数据线≥18ms
  2. 传感器响应:DHT11拉低80μs,再拉高80μs
  3. 数据传输: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秒刷新一次
    }
}

📊 运行效果

系统运行效果
系统运行效果

串口输出示例