dht11温湿度传感器hal oled
时间: 2025-06-01 20:32:53 浏览: 31
### 开发环境概述
DHT11温湿度传感器可以通过STM32的HAL库实现数据读取,并将结果显示在OLED屏幕上。以下是详细的开发流程和示例代码。
---
### 硬件连接说明
#### STM32F103C8T6与DHT11的连接
- **GPIO配置**: 使用一个GPIO引脚来模拟单总线协议,用于与DHT11通信。
- 连接如下表所示:
| DHT11 Pin | 功能 | STM32 GPIO |
|-----------|--------------|------------|
| VCC | 电源 (3.3V) | 3.3V |
| DATA | 数据通信 | PA5 |
| GND | 接地 | GND |
#### STM32F103C8T6与OLED的连接
- OLED通常通过I2C接口与STM32通信。
- I2C引脚分配如下:
| OLED Pin | 功能 | STM32 GPIO |
|------------|---------------|------------|
| SDA | 数据线 | PB7 |
| SCL | 时钟线 | PB6 |
| VCC | 电源 (3.3V) | 3.3V |
| GND | 接地 | GND |
---
### 软件设计思路
#### 单总线协议解析
DHT11使用单总线协议传输数据,具体过程包括:
1. 主机发送启动信号给DHT11。
2. DHT11响应主机并准备发送数据。
3. 数据由40位组成,前8位为湿度整数部分,次8位为湿度小数部分,再8位为温度整数部分,接着8位为温度小数部分,最后8位为校验码[^1]。
#### HAL库功能调用
- 配置GPIO端口以支持输入/输出切换。
- 实现延时函数以满足单总线的时间要求。
- 利用`HAL_GPIO_WritePin()` 和 `HAL_GPIO_ReadPin()` 完成数据交互。
#### OLED显示驱动
- 使用SSD1306控制器驱动OLED屏幕。
- 初始化I2C外设并通过`HAL_I2C_Master_Transmit()` 发送命令和数据显示指令[^2]。
---
### 示例代码
以下是一个完整的示例代码框架,展示如何结合DHT11、HAL库和OLED显示屏完成温湿度监测系统的开发。
```c
#include "main.h"
#include "stm32f1xx_hal.h"
#define DHT11_PIN GPIO_PIN_5
#define DHT11_PORT GPIOA
// 延时函数
void delay_us(uint32_t us) {
__HAL_TIM_SET_COUNTER(&htim2, 0); // 设置TIM计数值为0
while (__HAL_TIM_GET_COUNTER(&htim2) < us);
}
// 初始化DHT11 GPIO
void DHT11_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_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);
}
// 读取DHT11数据
uint8_t DHT11_ReadData(float *humidity, float *temperature) {
uint8_t data[5];
uint8_t i, j;
// 将引脚设置为输出低电平持续至少18ms
HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_RESET);
HAL_Delay(20);
// 上拉引脚等待DHT11响应
HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_SET);
delay_us(40);
// 改变引脚为输入模式接收数据
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = DHT11_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStruct);
// 等待DHT11拉低总线
for(i = 0; i < 1000 && HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN); i++);
if(i >= 1000) return 1;
// 等待DHT11释放总线
for(i = 0; i < 1000 && !HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN); i++);
if(i >= 1000) return 1;
// 读取40位数据
for(j = 0; j < 5; j++) {
data[j] = 0;
for(i = 0; i < 8; i++) {
while(!HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN)); // 等待高电平开始
delay_us(40);
if(HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN)) {
data[j] |= (1 << (7 - i));
}
while(HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN)); // 等待高电平结束
}
}
// 校验数据有效性
if(data[4] != ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) return 1;
*humidity = data[0]; // 湿度整数部分
*temperature = data[2]; // 温度整数部分
return 0;
}
// SSD1306初始化
void OLED_Init() {
// 初始化I2C外设...
// 发送初始化序列至OLED...
}
// 显示字符串到OLED
void OLED_ShowString(char* str) {
// 编写字符显示逻辑...
}
int main(void) {
HAL_Init(); // 初始化HAL库
SystemClock_Config(); // 配置系统时钟
DHT11_Init(); // 初始化DHT11 GPIO
OLED_Init(); // 初始化OLED屏幕
float humidity, temperature;
char buffer[50];
while (1) {
if (!DHT11_ReadData(&humidity, &temperature)) {
sprintf(buffer, "Humidity:%.1f%%\nTemperature:%.1fC", humidity, temperature);
OLED_ShowString(buffer);
} else {
OLED_ShowString("Error reading sensor");
}
HAL_Delay(2000); // 每两秒刷新一次
}
}
```
---
###
阅读全文
相关推荐
















