stm32cubeide+dth11
时间: 2025-05-25 15:14:21 AIGC 浏览: 33
### 使用 STM32CubeIDE 配置和使用 DHT11 温湿度传感器
#### 一、硬件连接
DHT11 是一款数字温湿度传感器,其引脚定义如下:
- VCC:电源正极(通常为 3.3V 或 5V)
- GND:接地
- DATA:数据通信引脚
- NC:未连接
在 STM32 的项目中,需将 DHT11 的 `DATA` 引脚连接到 STM32 的任意 GPIO 引脚。例如,可以将其连接至 PA0。
---
#### 二、软件配置
以下是基于 STM32CubeIDE 的具体配置流程:
##### 1. 创建工程并初始化 GPIO 和时钟
通过 STM32CubeMX 初始化以下外设:
- **GPIO**:设置用于与 DHT11 数据交互的 GPIO 引脚(如 PA0),模式应为推挽输出/输入浮空。
- **SysTick** 或 **TIMx**:用于实现微秒级延迟功能,因为 DHT11 协议需要严格的定时控制。
完成初始化后生成代码,并导入 STM32CubeIDE 进行后续开发。
##### 2. 编写 DHT11 驱动函数
为了简化操作,可编写一组独立的驱动函数来处理 DHT11 的数据读取逻辑。以下是主要函数的功能描述及其代码示例:
###### (1) 延迟函数
由于 DHT11 的协议涉及微妙级别的信号宽度,因此需要实现高精度的延时函数。可以通过 SysTick 实现此功能:
```c
void delay_us(uint32_t us) {
uint32_t ticks = us * (SystemCoreClock / 1000000);
uint32_t start = __HAL_TIM_GET_COUNTER(&htimX); // 替换 htimX 为你使用的 TIM 外设句柄
while ((__HAL_TIM_GET_COUNTER(&htimX) - start) < ticks);
}
```
###### (2) 初始化 DHT11 并发送启动信号
向 DHT11 发送启动信号以请求数据传输:
```c
uint8_t DHT11_Start(GPIO_TypeDef* GPIOx, uint16_t Pin) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 设置为输出模式
GPIO_InitStruct.Pin = Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOx, Pin, GPIO_PIN_RESET); // 主机拉低至少 18ms
delay_us(18000);
HAL_GPIO_WritePin(GPIOx, Pin, GPIO_PIN_SET); // 上升沿触发 DHT11
delay_us(40);
// 切换回输入模式
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP; // 添加上拉电阻
HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
uint32_t timeout = 10000;
while(HAL_GPIO_ReadPin(GPIOx, Pin) && --timeout); // 等待下降沿
if(timeout == 0) return 1;
timeout = 10000;
while(!HAL_GPIO_ReadPin(GPIOx, Pin) && --timeout); // 等待上升沿
if(timeout == 0) return 1;
return 0;
}
```
###### (3) 接收数据
接收来自 DHT11 的 40bit 数据流:
```c
uint8_t DHT11_ReadData(uint8_t *dataBuf, GPIO_TypeDef* GPIOx, uint16_t Pin) {
for(int i=0;i<5;i++) {
dataBuf[i] = 0;
for(int j=0;j<8;j++) {
uint32_t timeout = 10000;
while(!HAL_GPIO_ReadPin(GPIOx, Pin) && --timeout); // 等待上升沿
if(timeout == 0) return 1;
delay_us(30); // 记录持续时间判断高低电平状态
if(HAL_GPIO_ReadPin(GPIOx, Pin)) {
dataBuf[i] |= (1 << (7-j));
}
timeout = 10000;
while(HAL_GPIO_ReadPin(GPIOx, Pin) && --timeout); // 等待下降沿
if(timeout == 0) return 1;
}
}
return 0;
}
```
---
#### 三、主循环中的调用
在主程序中定期调用上述函数获取温度和湿度数据,并打印结果:
```c
#include "main.h"
#define DHT11_DATA_PIN GPIO_PIN_0
#define DHT11_PORT GPIOA
#define DHT11_BUF_SIZE 5
uint8_t DHT11_BUF[DHT11_BUF_SIZE];
int main(void) {
HAL_Init();
SystemClock_Config(); // 配置系统时钟
MX_GPIO_Init(); // 初始化 GPIO
MX_TIMx_Init(); // 初始化计时器(替换为实际使用的 TIM)
while (1) {
if (!DHT11_Start(DHT11_PORT, DHT11_DATA_PIN)) {
if (!DHT11_ReadData(DHT11_BUF, DHT11_PORT, DHT11_DATA_PIN)) {
printf("湿度:%02d%% 温度:%02d℃\r\n", DHT11_BUF[0], DHT11_BUF[2]);
} else {
printf("数据读取失败\r\n");
}
} else {
printf("无法启动 DHT11\r\n");
}
HAL_Delay(2000); // 每隔两秒刷新一次数据
}
}
```
---
#### 四、注意事项
1. 确保供电电压稳定,推荐使用 3.3V 或者经过稳压后的 5V。
2. 如果环境噪声较大,建议增加去耦电容或者屏蔽措施[^1]。
3. 在调试阶段可通过串口工具观察返回的数据是否正常。
---
阅读全文
相关推荐




















