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

共1条 1/1 1 跳转至

【e起DIY】低功耗蓝牙温湿度计:温湿度传感器DHT22驱动

工程师
2026-06-06 19:27:40     打赏

一、硬件介绍

       我选用的板卡型号是FRDM-MCXN947,温湿度传感器型号是DHT22,实物如下图

image.png

image.png

FRDM-MCXN947板卡参数如下

内核:有两个ARM Cortex-M33内核,每个内核的主频均为150MHz

加速器:神经处理单元、PowerQuad、Smart DMA等

连接:

以太网PHY和连接器

HS USB Type-C连接器

SPI/I2C/UART连接器(PMOD/mikroBUS、DNP)

CAN-FD收发器

调试:带有CMSIS-DAP的板载MCU-Link调试器,JTAG/SWD连接器

传感器:P3T1755 I3C/I2C温度传感器,触摸板

扩展选项:Arduino接头(带FRDM扩展行)、FRDM接头、FlexIO/LCD接头、SmartDMA摄像头接头


DHT22产品参数:

供电电压:3.3V到5V

温度范围:-40到80℃,分辨率0.1℃,误差±0.5℃

湿度范围:0到100%RH,分辨率0.1%RH,误差±2%RH

接口线序:VCC,GND,digital

模块尺寸:38×20mm

二、接线方式

       DHT22的引脚图如下

image.png

       总共有三根引脚,分别是GND、VCC和S(数据引脚)。接线方式如下

image.png

三、流程图

image.png

四、驱动程序

        DHT22的数据引脚输出的是数字信号,需要通过引脚实现启动信号和数据接收等功能。具体的源码如下

#include "dht22.h"
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/printk.h>

#define DHT22_GPIO_PIN    12

static const struct device *dht_gpio_dev;

static inline void delay_us(uint32_t us)
{
    k_busy_wait(us);
}

int dht22_init(void)
{
    dht_gpio_dev = DEVICE_DT_GET(DT_NODELABEL(gpio0));

    if (!device_is_ready(dht_gpio_dev)) {
        printk("DHT22 GPIO 未就绪!\n");
        return -ENODEV;
    }

    gpio_pin_configure(dht_gpio_dev, DHT22_GPIO_PIN, GPIO_OUTPUT_HIGH);
    printk("DHT22 初始化成功\n");
    k_msleep(100);
    return 0;
}

static void dht22_set_output(int value)
{
    gpio_pin_configure(dht_gpio_dev, DHT22_GPIO_PIN, GPIO_OUTPUT);
    gpio_pin_set(dht_gpio_dev, DHT22_GPIO_PIN, value);
}

static void dht22_set_input(void)
{
    gpio_pin_configure(dht_gpio_dev, DHT22_GPIO_PIN, GPIO_INPUT);
}

static uint8_t dht22_read_byte(void)
{
    uint8_t byte = 0;
    for (int i = 0; i < 8; i++) {
        while (!gpio_pin_get(dht_gpio_dev, DHT22_GPIO_PIN));
        delay_us(40);

        byte <<= 1;
        if (gpio_pin_get(dht_gpio_dev, DHT22_GPIO_PIN)) {
            byte |= 1;
        }
        while (gpio_pin_get(dht_gpio_dev, DHT22_GPIO_PIN));
    }
    return byte;
}

int dht22_read(struct dht22_data *data)
{
    uint8_t buf[5] = {0};

    // 启动信号
    dht22_set_output(0);
    k_msleep(18);
    dht22_set_output(1);
    delay_us(20);
    dht22_set_input();
    delay_us(30);

    // 响应
    if (gpio_pin_get(dht_gpio_dev, DHT22_GPIO_PIN)) return -EIO;
    while (!gpio_pin_get(dht_gpio_dev, DHT22_GPIO_PIN));
    while (gpio_pin_get(dht_gpio_dev, DHT22_GPIO_PIN));

    // 读5字节
    for (int i = 0; i < 5; i++) {
        buf[i] = dht22_read_byte();
    }

    printk("[原始数据] %02x %02x %02x %02x %02x\n",
           buf[0], buf[1], buf[2], buf[3], buf[4]);

    // ====================== 校验和======================
    uint16_t check = buf[0] + buf[1] + buf[2] + buf[3];
    if ((uint8_t)check != buf[4]) {
        printk("[校验错误]\n");
        return -EINVAL;
    }

    // 转换数据
    data->humidity = (buf[0] << 8 | buf[1]) / 10.0f;
    data->temperature = ((buf[2] & 0x7F) << 8 | buf[3]) / 10.0f;
    if (buf[2] & 0x80) data->temperature = -data->temperature;

    return 0;
}

       其中gpio0和DHT22_GPIO_PIN对应DHT22的数据引脚端口。

五、效果展示

        程序编译成功后下载到板卡上,通过串口软件打开就可以看到获取的温湿度数据值

image.png

六、问题总结

       程序编写完成后串口一直没有打印,刚开始通过仿真发现传感器一直没有响应。通过AI定位要求数据端口有上拉电阻才行。而板卡的端口并不是为这个传感器而设定的,但是考虑到传感器应该会在数据端口加上拉电阻的,所以特地的查看了下传感器手册,发现在数据端口处有上拉电阻

image.png

       后来发现在端口初始化时需要配置成默认高电平才可以。

       之后也遇到温湿度数据获取完成后校验一直失败的问题,通过串口打印获取的原始数据和逻辑分析仪获取的数据对比,发现没有问题。自己计算这些数据值也是没有问题。所以只能是程序的校验方式有问题。最后是修改校验变量的数据类型才解决的。

七、相关文件

工程文件:MCXN947+DHT22.zip




关键词: 温湿度传感器DHT22    

共1条 1/1 1 跳转至

回复

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