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

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

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

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

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

点击领取更多详细资料

一、DHT11 温湿度传感器概述

DHT11 是一款常用的数字式温湿度传感器,由电阻式感湿元件和 NTC 测温元件组成。它能够将环境中的温度和湿度转换为数字信号输出,具有成本低、使用方便等优点,广泛应用于智能家居、气象监测等领域。

1. 主要特性

  • 单总线通信:采用单总线协议与微控制器进行通信,仅需一根数据线即可完成数据传输。
  • 测量范围:湿度测量范围为 20 - 90%RH,温度测量范围为 0 - 50°C。
  • 精度:湿度测量精度为 ±5%RH,温度测量精度为 ±2°C。
  • 数据输出:输出 40 位数据,其中包括 8 位湿度整数部分、8 位湿度小数部分、8 位温度整数部分、8 位温度小数部分和 8 位校验和。

2. 引脚说明

  • VCC:电源引脚,接 3 - 5.5V 电源。
  • DATA:数据引脚,用于与微控制器进行数据通信。
  • GND:接地引脚。

二、STM32 与 DHT11 的硬件连接

将 DHT11 与 STM32 进行连接时,需要注意以下几点:

  • 电源连接:将 DHT11 的 VCC 引脚连接到 STM32 的 3.3V 或 5V 电源引脚,GND 引脚连接到 STM32 的地引脚。
  • 数据连接:将 DHT11 的 DATA 引脚连接到 STM32 的一个 GPIO 引脚,这里假设连接到 PA0 引脚。
  • 上拉电阻:在 DATA 引脚和 VCC 引脚之间连接一个 4.7K - 10K 的上拉电阻,确保数据传输的稳定性。

三、DHT11 通信协议

DHT11 采用单总线通信协议,通信过程分为以下几个步骤:

1. 起始信号

STM32 向 DHT11 发送一个至少 18ms 的低电平信号,然后拉高 20 - 40μs,通知 DHT11 准备发送数据。

2. 响应信号

DHT11 接收到起始信号后,会拉低总线 80μs 作为响应信号,然后拉高 80μs 表示准备发送数据。

3. 数据传输

DHT11 依次发送 40 位数据,每位数据以 50μs 的低电平开始,高电平的持续时间决定了数据是 0 还是 1。如果高电平持续时间为 26 - 28μs,则表示数据 0;如果高电平持续时间为 70μs,则表示数据 1。

4. 校验和

最后 8 位为校验和,用于验证数据的准确性。校验和等于湿度整数部分、湿度小数部分、温度整数部分和温度小数部分的和的低 8 位。

四、STM32 代码实现

1. 初始化 GPIO 引脚

#include "stm32f10x.h"

// 初始化 PA0 引脚
void DHT11_GPIO_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

2. 发送起始信号

// 发送起始信号
void DHT11_Start(void) {
    GPIO_SetBits(GPIOA, GPIO_Pin_0);
    Delay_ms(20);  // 确保 DHT11 处于稳定状态
    GPIO_ResetBits(GPIOA, GPIO_Pin_0);
    Delay_ms(20);  // 至少 18ms 低电平
    GPIO_SetBits(GPIOA, GPIO_Pin_0);
    Delay_us(30);  // 20 - 40μs 高电平
}

3. 等待响应信号

// 等待 DHT11 响应信号
uint8_t DHT11_Wait_Response(void) {
    uint8_t retry = 0;

    // 等待 DHT11 拉低总线
    while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) && retry < 100) {
        retry++;
        Delay_us(1);
    }
    if (retry >= 100) return 1;  // 响应超时
    else retry = 0;

    // 等待 DHT11 拉高总线
    while (!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) && retry < 100) {
        retry++;
        Delay_us(1);
    }
    if (retry >= 100) return 1;  // 响应超时

    return 0;
}

4. 读取一位数据

// 读取一位数据
uint8_t DHT11_Read_Bit(void) {
    uint8_t retry = 0;

    // 等待低电平结束
    while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) && retry < 100) {
        retry++;
        Delay_us(1);
    }
    retry = 0;

    // 等待高电平
    while (!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) && retry < 100) {
        retry++;
        Delay_us(1);
    }
    Delay_us(40);  // 等待 40μs 判断数据位

    if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)) return 1;
    else return 0;
}

5. 读取一个字节数据

// 读取一个字节数据
uint8_t DHT11_Read_Byte(void) {
    uint8_t i, dat = 0;
    for (i = 0; i < 8; i++) {
        dat <<= 1;
        dat |= DHT11_Read_Bit();
    }
    return dat;
}

6. 读取温湿度数据

// 读取温湿度数据
uint8_t DHT11_Read_Data(uint8_t *humi_int, uint8_t *humi_dec, uint8_t *temp_int, uint8_t *temp_dec) {
    uint8_t buf[5];
    uint8_t i;

    DHT11_Start();
    if (DHT11_Wait_Response()) return 1;  // 响应失败

    for (i = 0; i < 5; i++) {
        buf[i] = DHT11_Read_Byte();
    }

    // 校验和验证
    if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]) {
        *humi_int = buf[0];
        *humi_dec = buf[1];
        *temp_int = buf[2];
        *temp_dec = buf[3];
        return 0;  // 读取成功
    } else {
        return 1;  // 校验和错误
    }
}

7. 主函数

int main(void) {
    uint8_t humi_int, humi_dec, temp_int, temp_dec;
    DHT11_GPIO_Init();

    while (1) {
        if (!DHT11_Read_Data(&humi_int, &humi_dec, &temp_int, &temp_dec)) {
            // 数据读取成功,可进行后续处理
            // 例如通过串口打印数据
            printf("Humidity: %d.%d%%, Temperature: %d.%d°C\n", humi_int, humi_dec, temp_int, temp_dec);
        }
        Delay_ms(2000);  // 每 2 秒读取一次数据
    }
}

注意事项

  • 由于 DHT11 的数据传输对时序要求较高,因此在编写代码时需要确保延时函数的准确性。
  • 为了避免干扰,建议在读取数据时关闭中断。
  • DHT11 不适合频繁读取数据,建议读取间隔不小于 2 秒。

通过以上步骤,我们可以实现 STM32 与 DHT11 温湿度传感器的通信,获取环境的温度和湿度数据。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐