这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【e起DIY】低功耗蓝牙温湿度计—DHT11

共1条 1/1 1 跳转至

【e起DIY】低功耗蓝牙温湿度计—DHT11

菜鸟
2026-06-17 02:00:06     打赏
【e起DIY】低功耗蓝牙温湿度计 — DHT11

1. 概述

DHT11 是奥松电子(Aosong)推出的数字温湿度传感器,采用单总线(Single-Wire)协议通信,数据线仅需一根 GPIO + 一个上拉电阻。Zephyr RTOS 在 drivers/sensor/aosong/dht/ 中内置了完整驱动,兼容 DHT11 和 DHT22。

本次基于 NXP FRDM-MCXW71 开发板(SoC: MCXW716C, Cortex-M33F),将 Zephyr 原厂 DHT 驱动集成到 blinky 工程中,实现每 2 秒读取一次温湿度数据并通过串口打印。


2. 硬件接线

DHT11 引脚FRDM-MCXW71 引脚说明
VCC3.3V供电
DATAPTA19(GPIOA Pin 19)数据线,需 4.7kΩ~10kΩ 上拉至 VCC
GNDGND共地

⚠️ 注意:PTA19 在开发板默认配置中与 TPM0_CH2(PWM 输出)复用,必须通过 device tree overlay 禁用 TPM0,否则引脚无法工作在 GPIO 模式。


a5bac3ea18c0fddf0cdd6068a74a9ebd.jpg

3. Device Tree Overlay

文件路径:blinky/boards/frdm_mcxw71.overlay

/ {
   aliases {
       dht0 = &dht11;
   };

   dht11: dht11 {
       compatible = "aosong,dht";          /* 绑定到 DHT 驱动 */
       dio-gpios = <&gpioa 19 GPIO_ACTIVE_LOW>;
       status = "okay";
   };
};

&gpioa {
   status = "okay";                         /* 启用 GPIOA 端口 */
};

&tpm0 {
   status = "disabled";                     /* 释放 PTA19 的 PWM 复用 */
};

关键点:

  • compatible = "aosong,dht" — 匹配驱动中的 DT_DRV_COMPAT aosong_dht

  • GPIO_ACTIVE_LOW — DHT 驱动通过逻辑电平反相来适配单总线协议

  • 禁用 &tpm0 解决引脚复用冲突


4. Kconfig 配置

文件路径:blinky/prj.conf

CONFIG_GPIO=y         # GPIO 子系统
CONFIG_SENSOR=y       # Zephyr 传感器框架
CONFIG_DHT=y          # DHT 驱动(依赖 DT_HAS_AOSONG_DHT_ENABLED)
CONFIG_PRINTK=y       # 内核日志输出

驱动本身的 Kconfig 层级:

CONFIG_DHT (menuconfig)
 ├── depends on DT_HAS_AOSONG_DHT_ENABLED  ← 由 overlay 中的 compatible 自动满足
 ├── depends on GPIO
 └── CONFIG_DHT_LOCK_IRQS (可选)
       └── 读取时锁中断,提高成功率,但影响蓝牙等实时任务

5. 驱动分层架构

image.png


  • 应用层通过 Zephyr Sensor 框架统一接口访问,无需关心单总线协议细节

  • 驱动底层用 k_cycle_get_32() 硬件 Cycle 计数器实现微秒级脉冲测量


6. DHT11 单总线通信协议

DHT11 采用单总线协议,MCU 作为主机发起通信,传感器应答后返回 40 位数据。

image-20260617015344840.png

校验(Byte0+Byte1+Byte2+Byte3) & 0xFF == Byte4。DHT11 小数位恒为 0。


7. 核心流程详解

7.1 驱动初始化流程

image.png初始化仅做 GPIO 上电准备,不主动与传感器通信。真正的通信在 sensor_sample_fetch() 时按需触发。

7.2 数据采集流程 — dht_sample_fetch()

deepseek_mermaid_20260616_23f4df.png

自适应阈值:从 40 个脉冲中动态计算 (max_duration + min_duration) / 2,避免硬编码时序阈值,跨 MCU 兼容性好。



8. 应用层 main.c

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/sensor.h>

#define SLEEP_TIME_MS   2000

int main(void)
{
   /* 1. 获取 DHT11 设备句柄 */
   const struct device *const dht = DEVICE_DT_GET_OR_NULL(DT_ALIAS(dht0));

   if (!device_is_ready(dht)) {
       printk("DHT11: device not readyn");
       return 0;
   }

   while (1) {
       /* 2. 触发一次采样(阻塞,约 25ms) */
       int ret = sensor_sample_fetch(dht);
       if (ret != 0) {
           printk("DHT11: fetch failed: %dn", ret);
       } else {
           struct sensor_value temp, humidity;

           /* 3. 从驱动缓存读取解析后的值 */
           sensor_channel_get(dht, SENSOR_CHAN_AMBIENT_TEMP, &temp);
           sensor_channel_get(dht, SENSOR_CHAN_HUMIDITY, &humidity);

           printk("DHT11: Temperature: %d.%d C, Humidity: %d.%d %%RHn",
                  temp.val1, temp.val2 / 100000,
                  humidity.val1, humidity.val2 / 100000);
       }

       k_msleep(SLEEP_TIME_MS);   /* DHT11 要求 ≥1s 采样间隔 */
   }
   return 0;
}

应用层调用链路(非 RTIO 路径):

main() 
 → sensor_sample_fetch(dht)     // Zephyr sensor 框架
   → dht_sample_fetch()         // DHT 驱动实现,bit-bang 单总线通信
 → sensor_channel_get(dht, ...) // Zephyr sensor 框架  
   → dht_channel_get()          // 解析 sample[] 为 sensor_value

9. 结果展示image.png


10. 总结

Zephyr 的 DHT 驱动设计精巧:

  • 自适应阈值替代硬编码时序判断,跨 MCU 兼容性好

  • 单 GPIO + Cycle 计数器实现微秒级测量,无需专用定时器

  • Sensor 框架统一接口,应用层无需关心底层协议

  • Device Tree 与 Kconfig 解耦硬件描述与编译配置

集成到 FRDM-MCXW71 时,唯一需注意的硬件细节是 PTA19 引脚复用冲突(与 TPM0 PWM),通过 overlay 禁用 TPM0 即可解决。



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]