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);
}
}
注意事项
- 时序要求:DHT11对通信时序有严格的要求,确保按照协议发送起始信号和读取数据。
- 电源稳定性:确保DHT11的电源稳定,避免电压波动影响测量结果。
- 数据校验:每次读取数据后,进行数据校验以确保数据的准确性。
通过上述步骤,我们可以在STM32上成功驱动DHT11温湿度传感器,并实现温湿度数据的实时读取。这为开发需要环境监测的嵌入式系统提供了基础。
✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进
❤欢迎关注我的知乎:对error视而不见
代码获取、问题探讨及文章转载可私信。
☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。
标签:HAL,PIN,温湿度,STM32,GPIO,DATA,buf,DHT11 From: https://blog.csdn.net/weixin_66608063/article/details/143609059