自学内容网 自学内容网

STM32之DHT11温湿度传感器

DHT11是一款常用的单总线数字温湿度传感器,它能够提供相对湿度和温度的测量值。本文将详细介绍如何使用STM32微控制器读取DHT11传感器的数据。

DHT11传感器特点

  • 湿度测量范围:20%~90%RH
  • 温度测量范围:0~50℃
  • 单总线数字输出
  • 低功耗
  • 易于安装和使用

硬件连接

DHT11传感器通常有三个引脚,分别是VCC、DATA和GND。连接方式如下:

  • VCC:连接到STM32的3.3V或5V电源
  • DATA:连接到STM32的一个GPIO引脚(例如PA0)
  • GND:连接到STM32的地

软件编程

1. 初始化GPIO

首先,需要初始化与DHT11通信的GPIO引脚。

#include "stm32f1xx_hal.h"

#define DHT11_PORT GPIOA
#define DHT11_PIN GPIO_PIN_0
#define DHT11_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()

void DHT11_GPIO_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    DHT11_GPIO_CLK_ENABLE();
    GPIO_InitStruct.Pin = DHT11_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStruct);
}

2. DHT11通信协议

DHT11的通信协议包括发送起始信号、等待响应信号、接收数据和校验数据。以下是实现这些步骤的代码。

#include "delay.h"

#define DHT11_DATA_HIGH() HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_SET)
#define DHT11_DATA_LOW() HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_RESET)
#define DHT11_DATA_READ() HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN)

void DHT11_Start(void) {
    DHT11_DATA_LOW(); // 拉低至少18ms
    delay_ms(20);
    DHT11_DATA_HIGH(); // 拉高20~40us
    delay_us(30);
    HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_SET); // 设置为输入模式
}

uint8_t DHT11_CheckResponse(void) {
    uint8_t retry = 0;
    // 等待DHT11响应,响应信号为80us低电平
    while (DHT11_DATA_READ() && retry < 100) {
        delay_us(1);
        retry++;
    }
    // 检查是否收到响应
    if (retry >= 100) return 1;

    retry = 0;
    // 等待DHT11拉高40~80us
    while (!DHT11_DATA_READ() && retry < 100) {
        delay_us(1);
        retry++;
    }
    if (retry >= 100) return 1;
    return 0;
}

uint8_t DHT11_ReadByte(void) {
    uint8_t i, byte = 0;
    for (i = 0; i < 8; i++) {
        // 等待50us低电平
        while (!DHT11_DATA_READ());
        delay_us(40);
        if (DHT11_DATA_READ()) {
            byte |= (1 << (7 - i)); // 数据1
        } else {
            // 数据0
        }
        // 等待高电平结束
        while (DHT11_DATA_READ());
    }
    return byte;
}

void DHT11_ReadData(uint8_t *humidity, uint8_t *temperature) {
    uint8_t buf[5];
    DHT11_Start();
    if (!DHT11_CheckResponse()) {
        buf[0] = DHT11_ReadByte(); // 湿度整数
        buf[1] = DHT11_ReadByte(); // 湿度小数
        buf[2] = DHT11_ReadByte(); // 温度整数
        buf[3] = DHT11_ReadByte(); // 温度小数
        buf[4] = DHT11_ReadByte(); // 校验和
        if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]) {
            *humidity = buf[0];
            *temperature = buf[2];
        }
    }
}

3. 主函数

在主函数中,初始化DHT11传感器,并定期读取温湿度数据。

#include "usart.h"

int main(void) {
    HAL_Init();
    SystemClock_Config();
    DHT11_GPIO_Init();
    MX_USART2_UART_Init();

    uint8_t humidity, temperature;
    char buffer[64];

    while (1) {
        DHT11_ReadData(&humidity, &temperature);
        sprintf(buffer, "Humidity: %d%%\tTemperature: %dC\r\n", humidity, temperature);
        HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);
        HAL_Delay(1000);
    }
}

注意事项

  1. 时序要求:DHT11对通信时序有严格的要求,确保按照协议发送起始信号和读取数据。
  2. 电源稳定性:确保DHT11的电源稳定,避免电压波动影响测量结果。
  3. 数据校验:每次读取数据后,进行数据校验以确保数据的准确性。

通过上述步骤,我们可以在STM32上成功驱动DHT11温湿度传感器,并实现温湿度数据的实时读取。这为开发需要环境监测的嵌入式系统提供了基础。

✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进

❤欢迎关注我的知乎:对error视而不见

代码获取、问题探讨及文章转载可私信。

☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。

🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇

点击领取更多详细资料


原文地址:https://blog.csdn.net/weixin_66608063/article/details/143609059

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!