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

发布于:2025-03-31 ⋅ 阅读:(20) ⋅ 点赞:(0)
主题 内容 教学目的/扩展视频
DHT11芯片 电路连接,手册分析。驱动程序,读出数据。 能读出温湿度值即可。

师从洋桃电子,杜洋老师



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


一、DHT11驱动程序设计概述

1.1 传感器工作原理

DHT11采用单总线通信协议,通过精确的时序控制实现数据交换。传感器内部集成8位单片机,完成温湿度信号的采集、校准和数字转换。驱动程序设计需严格遵循其通信时序规范—— 点击查阅🔍DHT11说明书(中文)

1.2 驱动程序功能模块

模块名称 功能描述
端口控制 GPIO输入/输出模式切换
通信时序控制 起始信号生成与响应检测
数据解析 二进制数据转换温湿度值
数据校验 校验和验证数据完整性

二、驱动程序架构分析

2.1 程序文件结构

DHT11驱动
├── dht11.h    // 函数声明与宏定义
├── dht11.c    // 驱动功能实现
└── main.c     // 应用层逻辑

2.2 核心功能流程图

主程序初始化
DHT11初始化
初始化成功?
启动温湿度读取
显示错误信息
数据校验
显示温湿度值

三、关键功能实现解析

3.1 初始化流程设计

  1. 硬件准备:使能GPIO时钟
  2. 端口复位:发送起始信号(拉低≥18ms)
  3. 响应检测:等待传感器80μs低电平响应
  4. 状态确认:返回初始化结果(0成功/1失败)

3.2 数据读取机制

步骤 操作描述 时间要求
1 主机发送起始信号 ≥18ms低电平
2 传感器返回响应信号 80μs低电平
3 传输40bit数据(高位优先) 每bit 50-70μs
4 校验数据完整性 校验和比对

四、DHT11驱动代码深度解析

4.1 头文件设计(dht11.h)

4.1.1 硬件接口定义
#define DHT11PORT GPIOA       // 使用GPIOA端口
#define DHT11_IO  GPIO_Pin_15 // 使用PA15引脚
  • 设计意图:集中管理硬件接口,提升代码可移植性
  • 扩展建议:通过宏定义支持多传感器实例
#define DHT11_1_PORT GPIOA
#define DHT11_1_PIN  GPIO_Pin_15
#define DHT11_2_PORT GPIOB
#define DHT11_2_PIN  GPIO_Pin_5
4.1.2 函数声明结构
// 端口模式控制
void DHT11_IO_OUT(void);  // 配置为输出模式
void DHT11_IO_IN(void);   // 配置为输入模式

// 通信控制
void DHT11_RST(void);     // 发送复位信号
u8 Dht11_Check(void);     // 检测传感器响应

// 数据读取
u8 Dht11_ReadBit(void);   // 读取单bit数据
u8 Dht11_ReadByte(void);  // 读取单字节数据

// 核心接口
u8 DHT11_Init(void);      // 初始化传感器
u8 DHT11_ReadData(u8 *h); // 读取温湿度数据

4.2 驱动实现分析(dht11.c)

4.2.1 端口模式切换函数
void DHT11_IO_OUT(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = DHT11_IO;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  // 推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 高速模式
    GPIO_Init(DHT11PORT, &GPIO_InitStructure);
}

void DHT11_IO_IN(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = DHT11_IO;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;     // 上拉输入
    GPIO_Init(DHT11PORT, &GPIO_InitStructure);
}
  • 技术要点
    • 推挽输出:确保驱动能力,准确控制电平
    • 上拉输入:避免总线浮空,提高抗干扰能力
    • 50MHz速度:满足单总线通信时序要求
4.2.2 复位信号生成
void DHT11_RST(void) {
    DHT11_IO_OUT();                 // 切换输出模式
    GPIO_ResetBits(DHT11PORT, DHT11_IO); // 拉低总线
    delay_ms(20);                   // 保持18ms以上(手册要求)
    GPIO_SetBits(DHT11PORT, DHT11_IO);   // 释放总线
    delay_us(30);                   // 20-40us等待
}
  • 时序控制
    • 拉低时间:严格≥18ms(实际20ms留余量)
    • 释放等待:30us满足20-40us规范
  • 误差处理:使用delay_ms/delay_us需校准系统时钟
4.2.3 响应检测函数
u8 Dht11_Check(void) {
    u8 retry = 0;
    DHT11_IO_IN(); // 切换输入模式
    
    // 等待80us低电平响应
    while(GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO) && retry<100) {
        retry++;
        delay_us(1);
    }
    if(retry>=100) return 1; // 超时返回错误
    
    retry = 0;
    // 等待80us高电平准备
    while(!GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO) && retry<100) {
        retry++;
        delay_us(1);
    }
    return (retry>=100) ? 1 : 0; // 超时判断
}
  • 关键技术
    • 双重等待机制:先检测低电平响应,再检测高电平准备
    • 超时保护:100次尝试(100us)防止死循环
    • 精确时序:1us级检测间隔保障可靠性
4.2.4 数据位读取
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;
}
  • 解码原理
    • 50us低电平起始信号
    • 26-28us高电平表示’0’
    • 70us高电平表示’1’
  • 采样策略:在40us时间点采样,准确区分高低电平
4.2.5 数据读取主函数
u8 DHT11_ReadData(u8 *h) {
    u8 buf[5];
    DHT11_RST(); // 发送起始信号
    
    if(Dht11_Check() == 0) {
        for(int i=0; i<5; i++) {
            buf[i] = Dht11_ReadByte(); // 读取5字节
        }
        
        // 校验和验证
        if((buf[0]+buf[1]+buf[2]+buf[3]) == buf[4]) {
            h[0] = buf[0]; // 湿度整数
            h[1] = buf[2]; // 温度整数
            return 0;
        }
    }
    return 1; // 失败返回
}
  • 数据格式
    • buf[0]: 湿度整数(20-90)
    • buf[1]: 湿度小数(固定0)
    • buf[2]: 温度整数(0-50)
    • buf[3]: 温度小数(固定0)
    • buf[4]: 校验和
  • 错误处理
    • 数据校验失败返回错误
    • 响应超时立即终止

五、驱动程序优化方向

5.1 时序精度提升

  • 采用硬件定时器替代软件延时
  • 增加信号边沿中断检测
  • 实现μs级精准时序控制

5.2 扩展功能设计

多传感器管理系统
├── 动态地址分配
├── 时分复用通信
└── 数据融合处理

5.3 可靠性增强

  • 增加重试计数器(默认3次)
  • 引入滑动窗口滤波算法
  • 实现自动校准功能

六、关键参数配置参考

6.1 硬件连接规范

参数 推荐值 说明
上拉电阻 4.7KΩ 确保信号线稳定
供电电容 100nF 电源去耦
信号线长度 <20m 超过需加屏蔽处理

6.2 软件配置要点

配置项 设定值 作用
采样间隔 ≥1000ms 满足传感器恢复时间
超时检测 100次尝试 防止死循环
校验方式 累加和校验 验证数据完整性

七、相关资源

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


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

📌 下期预告:下一期将探讨DHT11驱动程序分析2,欢迎持续关注!

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

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

  • v1.0 初始版本(2025-03-26)