这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 过程帖:DHT22温湿度传感器驱动开发

共1条 1/1 1 跳转至

过程帖:DHT22温湿度传感器驱动开发

菜鸟
2026-06-21 22:18:20     打赏

前言

上一篇帖子中,完成了 FRDM-MCXW71 的开箱和VScoede-Zephyr 开发环境的搭建,hello_world 程序可以正常烧录和串口输出。本篇进入核心环节——连接 DHT22 温湿度传感器,编写驱动程序,在串口终端打印实时温湿度数据。

一、硬件连接

1.1 DHT22 传感器简介

DHT22是一款常用的数字温湿度传感器模块:

  • 温度测量范围:-40°C ~ +80°C,精度 ±0.5°C

  • 湿度测量范围:0~100%RH,精度 ±2%RH

  • 供电电压:3.3V ~ 5.5V

  • 接口:单总线(1-Wire),只需一根数据线即可通信

b2c8cddbc94679938df62aa7fbbac9c3.jpg

1.2 接线方案

DHT22 与 FRDM-MCXW71 的连接非常简单,只需要 3 根线:

DHT22 引脚连接到说明

VCC(+)3.3V板载 3.3V 供电或5V
DATA(out)A0(PTD1)单总线数据线
GND(-)GND接地

728ceb61325a6762b4888f0ecd40e272.jpg

1.3 为什么选择单总线而不是 I2C?

DHT22 是单总线协议的传感器,与 I2C 不同,它只需要一根数据线,时序由主机(MCU)发起。Zephyr 内置了 dht 驱动(CONFIG_DHT=y),可以自动处理复杂的时序协议,只需配置设备树即可使用。


二、软件实现

2.1 设备树叠加层(.overlay)

设备树是 Zephyr 中描述硬件的核心机制。我们在 boards/frdm_mcxw71.overlay 中完成以下配置:

/ {
    dht22: dht22 {
        compatible = "aosong,dht";
        // 关键修改:改为 gpiod 的 pin 1 (PTD1)
        dio-gpios = <&gpiod 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
        dht22;
        status = "okay";
    };

    aliases {
        dht-dev = &dht22;
    };
};

// 确保 GPIOD 时钟已开启
&gpiod {
    status = "okay";
};

GPIO_ACTIVE_LOW:这个是必需的。因为DHT22协议规定,主机发起通信时需将总线拉低。将其设为逻辑“活跃”状态,才能正确产生低电平信号

2.3 Kconfig 配置(prj.conf)

# 基础配置
CONFIG_STDOUT_CONSOLE=y
CONFIG_PRINTK=y

# 日志系统
CONFIG_LOG=y

# 传感器子系统
CONFIG_SENSOR=y

# DHT22 驱动
CONFIG_DHT=y
CONFIG_DHT_CHIP_DHT22=y

# GPIO 支持
CONFIG_GPIO=y

# 禁用 RTIO(避免冲突)
CONFIG_RTIO=n

2.4 主程序代码(main.c 传感器部分)

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

LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);

void main(void)
{
    const struct device *dev;
    struct sensor_value temp, humidity;
    int ret;

    printk("\n========================================\n");
    printk("DHT22 温湿度传感器测试程序\n");
    printk("引脚: PTD1 (A0)\n");
    printk("========================================\n\n");

    // 通过设备树别名获取传感器设备
    dev = DEVICE_DT_GET(DT_ALIAS(dht_dev));
    
    if (!device_is_ready(dev)) {
        printk("错误: DHT22 设备未就绪!\n");
        printk("请检查:\n");
        return;
    }
    
    printk("DHT22 传感器初始化成功\n");
    printk("设备名称: %s\n\n", dev->name);

    while (1) {
        // 获取传感器数据
        ret = sensor_sample_fetch(dev);
        
        if (ret != 0) {
            // 打印详细错误码
            printk("采样失败! 错误码: %d\n", ret);
            
            // 根据常见错误码给出提示
            if (ret == -5) {
                printk("提示: 未检测到传感器 (NOT_PRESENT)\n");
            } else if (ret == -16) {
                printk("提示: 数据读取超时 (TIMEOUT)\n");
            } else if (ret == -115) {
                printk("提示: 读取间隔过短 (TOOQUICK)\n");
            }
            
            k_sleep(K_MSEC(2000));
            continue;
        }

        // 获取温度数据
        ret = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp);
        if (ret != 0) {
            printk("获取温度失败: %d\n", ret);
            k_sleep(K_MSEC(2000));
            continue;
        }

        // 获取湿度数据
        ret = sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY, &humidity);
        if (ret != 0) {
            printk("获取湿度失败: %d\n", ret);
            k_sleep(K_MSEC(2000));
            continue;
        }

        // sensor_value 中: val1 是整数部分, val2 是小数部分 (百万分之一)
        printk("Temperature: %d.%06d°C, Humidity: %d.%06d%%RH\n",
               temp.val1, temp.val2, humidity.val1, humidity.val2);

        // DHT22 建议读取间隔大于 2 秒,这里延时 2 秒
        k_sleep(K_MSEC(2000));
    }
}

格式化输出:按要求的格式打印 Temperature: 26.2000°C, Humidity: 92.4%RH

四、运行结果

烧录完成后,打开串口终端,波特率 115200,按下 RESET 键:

2.png

数据每 2 秒刷新一次,温湿度值变化符合预期。用手捂住传感器可以看到温度和湿度同步上升,松开后逐渐回落。

六、总结

本篇完成了 DHT22 温湿度传感器的完整驱动开发流程:

整个过程得益于 Zephyr 内置的 DHT 驱动,开发者无需手动处理复杂的单总线时序,只需做好设备树配置即可。


共1条 1/1 1 跳转至

回复

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