DHT11数字温湿度传感器驱动开发详解(进阶篇)| STM32零基础开发第88步实践解析

主题 内容 教学目的/扩展视频
DHT11芯片 电路连接,手册分析。驱动程序,读出数据。 能读出温湿度值即可。

师从洋桃电子,杜洋老师


📑文章目录

  • 一、硬件接口与通信原理
  • 1.1 硬件连接拓扑
  • 1.2 单总线通信时序
  • 二、驱动代码深度解析(dht11.c)
  • 2.1 GPIO模式切换
  • 2.2 起始信号生成
  • 2.3 单bit数据读取
  • 2.4 单字节数据读取
  • 2.5 完整数据读取流程
  • 三、关键优化策略
  • 3.1 时序精度提升
  • 3.2 错误重试机制
  • 3.3 数据滤波处理
  • 四、典型应用场景
  • 五、开发注意事项
  • 六、相关资源

  • ▲ 回顾上期🔍DHT11数字温湿度传感器驱动开发全解析(上) | 零基础入门STM32第八十六步

    ▲ 回顾上期🔍DHT11数字温湿度传感器驱动开发全解析(中) | 零基础入门STM32第八十七步


    一、硬件接口与通信原理

    1.1 硬件连接拓扑

    引脚 连接目标 说明
    VDD 3.3V电源 供电范围3-5.5V DC
    DATA PA15 单总线双向通信引脚
    GND 系统GND 电源参考地

    1.2 单总线通信时序

    MCU

    DHT11

    拉低总线≥18ms(起始信号)

    80μs低电平响应

    发送40bit数据包

    数据格式:湿度整数(8b)+湿度小数(8b)+温度整数(8b)+温度小数(8b)+校验和(8b)

    数据校验与解析

    MCU

    DHT11


    二、驱动代码深度解析(dht11.c)

    2.1 GPIO模式切换

    // 设置为推挽输出模式
    void DHT11_IO_OUT(void) {
        GPIO_InitTypeDef GPIO_InitStruct;
        GPIO_InitStruct.GPIO_Pin = DHT11_IO;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;  // 推挽输出
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // 高速模式
        GPIO_Init(DHT11PORT, &GPIO_InitStruct);
    }
    
    // 设置为上拉输入模式
    void DHT11_IO_IN(void) {
        GPIO_InitTypeDef GPIO_InitStruct;
        GPIO_InitStruct.GPIO_Pin = DHT11_IO;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;     // 上拉输入
        GPIO_Init(DHT11PORT, &GPIO_InitStruct);
    }
    

    设计要点

  • 输出模式用于主机控制总线电平
  • 输入模式配合上拉电阻保证总线稳定
  • 50MHz速度满足单总线时序要求
  • 2.2 起始信号生成

    void DHT11_RST(void) {
        DHT11_IO_OUT();                 // 切换输出模式
        GPIO_ResetBits(DHT11PORT, DHT11_IO); // 拉低总线
        delay_ms(20);                   // 保持低电平20ms(手册要求≥18ms)
        GPIO_SetBits(DHT11PORT, DHT11_IO);   // 释放总线
        delay_us(30);                   // 等待20-40us
    }
    

    时序控制

  • 20ms低电平:确保满足最小18ms要求
  • 30us高电平:预留足够响应时间
  • 2.3 单bit数据读取

    u8 Dht11_ReadBit(void) {
        u8 retry = 0;
        // 等待50us低电平起始信号
        while(GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO) && retry<100) {
            retry++;
            delay_us(1);
        }
        
        retry = 0;
        // 等待高电平到来
        while(!GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO) && retry<100) {
            retry++;
            delay_us(1);
        }
        
        delay_us(40); // 关键采样点
        return GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO) ? 1 : 0;
    }
    

    解码原理

  • 26-28μs高电平:数据0
  • 70μs高电平:数据1
  • 40μs延迟采样:准确区分高低电平
  • 2.4 单字节数据读取

    u8 Dht11_ReadByte(void) {
        u8 i, dat = 0;
        for(i=0; i<8; i++) {
            dat <<= 1;        // 高位先出
            dat |= Dht11_ReadBit();
        }
        return dat;
    }
    

    位操作逻辑

    1. 左移操作保留高位
    2. 按位或操作累积数据位
    3. 循环8次组成完整字节

    2.5 完整数据读取流程

    u8 DHT11_ReadData(u8 *h) {
        u8 buf[5];
        DHT11_RST(); // 发送起始信号
        
        if(Dht11_Check() == 0) {        // 检测传感器响应
            for(int i=0; i<5; i++) {    // 读取5字节数据
                buf[i] = Dht11_ReadByte();
            }
            
            // 校验和验证
            if((buf[0]+buf[1]+buf[2]+buf[3]) == buf[4]) {
                h[0] = buf[0]; // 湿度整数部分
                h[1] = buf[2]; // 温度整数部分
                return 0;      // 成功标志
            }
        }
        return 1; // 失败标志
    }
    

    数据格式解析

    字节 数据内容 数值范围
    0 湿度整数 20-90%RH
    1 湿度小数 固定为0
    2 温度整数 0-50℃
    3 温度小数 固定为0
    4 校验和 前四字节和

    三、关键优化策略

    3.1 时序精度提升

    // 使用硬件定时器替代delay_us
    void Delay_us(uint16_t us) {
        TIM2->CNT = 0;
        while(TIM2->CNT < us);
    }
    

    3.2 错误重试机制

    u8 DHT11_ReadData(u8 *h) {
        u8 retry = 3;
        while(retry--) {
            // ...读取逻辑...
            if(校验成功) return 0;
            delay_ms(100); // 重试间隔
        }
        return 1;
    }
    

    3.3 数据滤波处理

    #define FILTER_SIZE 5
    u8 filter_buf[FILTER_SIZE][2];
    
    void DHT11_Filter(u8 *h) {
        static u8 index = 0;
        // 存储当前值
        filter_buf[index][0] = h[0];
        filter_buf[index][1] = h[1];
        index = (index+1) % FILTER_SIZE;
        
        // 排序取中值
        // ...实现排序算法...
    }
    

    四、典型应用场景

    上电初始化

    OLED显示标题

    DHT11初始化成功?

    显示温湿度模板

    显示错误信息

    循环读取数据

    读取成功?

    更新显示数据

    显示读取错误


    五、开发注意事项

    1. 电源稳定性:建议并联100nF陶瓷电容
    2. 信号线长度:超过20米需增加屏蔽措施
    3. 采样间隔:严格≥1秒(手册要求)
    4. 环境适应
    5. 避免冷凝环境
    6. 远离发热元件
    7. 防止化学污染

    六、相关资源

    [1] 洋桃电子B站课程-STM32入门100步
    [2] STM32官方文档手册
    [3] STM32F103固件函数库用户手册(中文)
    [4] DHT11说明书(中文)
    [5] DHT11温湿度显示程序


    💬 技术讨论(请在评论区留言~)


    📌 下期预告:下一期将探讨加速度传感器,欢迎持续关注!

    点击查阅🔍往期【STM32专栏】文章

    版权声明:本文采用[CC BY-NC-SA 4.0]协议,转载请注明来源
    实测开发版:洋桃1号开发版(基于STM32F103C8T6)
    更新日志

  • v1.0 初始版本(2025-03-30)
  • 作者:触角01010001

    物联沃分享整理
    物联沃-IOTWORD物联网 » DHT11数字温湿度传感器驱动开发详解(进阶篇)| STM32零基础开发第88步实践解析

    发表回复