前言
上一篇帖子中,完成了 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),只需一根数据线即可通信

1.2 接线方案
DHT22 与 FRDM-MCXW71 的连接非常简单,只需要 3 根线:
DHT22 引脚连接到说明
| VCC(+) | 3.3V | 板载 3.3V 供电或5V |
| DATA(out) | A0(PTD1) | 单总线数据线 |
| GND(-) | GND | 接地 |

1.3 为什么选择单总线而不是 I2C?
DHT22 是单总线协议的传感器,与 I2C 不同,它只需要一根数据线,时序由主机(MCU)发起。Zephyr 内置了 dht 驱动(),可以自动处理复杂的时序协议,只需配置设备树即可使用。
二、软件实现
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
# 基础配置 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 秒刷新一次,温湿度值变化符合预期。用手捂住传感器可以看到温度和湿度同步上升,松开后逐渐回落。
本篇完成了 DHT22 温湿度传感器的完整驱动开发流程:
我要赚赏金
