用STM32CubeMX和HAL库,5分钟搞定DHT11温湿度传感器(附OLED显示项目)

张开发
2026/4/21 16:25:54 15 分钟阅读

分享文章

用STM32CubeMX和HAL库,5分钟搞定DHT11温湿度传感器(附OLED显示项目)
STM32CubeMX与HAL库实战5分钟构建DHT11温湿度监测系统OLED显示版1. 项目概述与环境搭建在物联网和智能硬件开发领域温湿度监测是最基础却最实用的功能之一。使用STM32CubeMX配合HAL库我们可以快速搭建一个完整的温湿度监测系统。这个项目将使用DHT11传感器采集环境数据并通过OLED屏幕实时显示整个过程仅需5分钟配置即可完成核心框架。硬件准备清单STM32F103C8T6开发板Blue PillDHT11温湿度传感器0.96寸OLED显示屏I2C接口杜邦线若干USB转TTL模块可选用于调试提示DHT11采用单总线协议仅需一个GPIO引脚OLED通常使用I2C接口需连接SCL和SDA两条线。2. STM32CubeMX工程配置2.1 时钟与系统配置打开STM32CubeMX新建工程选择对应型号在RCC配置中启用外部高速时钟HSE在SYS中配置调试接口为Serial Wire// 自动生成的时钟配置代码部分 SystemClock_Config(); HAL_Init();2.2 GPIO与通信接口配置外设配置项参数DHT11GPIO模式开漏输出I2C1速度模式标准模式(100kHz)OLEDI2C地址0x78(默认)关键配置步骤为DHT11选择一个GPIO如PB5配置为输出模式启用I2C1外设保持默认参数生成工程时勾选Generate peripheral initialization as a pair of .c/.h files3. DHT11驱动实现3.1 单总线协议解析DHT11的通信时序包含三个关键阶段主机启动信号至少18ms低电平传感器响应信号80us低电平80us高电平数据传输阶段每个bit以50us低电平开始// DHT11读取函数示例 uint8_t DHT11_Read(void) { uint8_t data 0; DHT11_GPIO_Init(OUTPUT); HAL_GPIO_WritePin(DHT11_GPIO_Port, DHT11_Pin, GPIO_PIN_RESET); HAL_Delay(20); // 保持低电平至少18ms HAL_GPIO_WritePin(DHT11_GPIO_Port, DHT11_Pin, GPIO_PIN_SET); DHT11_GPIO_Init(INPUT); // 等待传感器响应 while(HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin) GPIO_PIN_SET); while(HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin) GPIO_PIN_RESET); while(HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin) GPIO_PIN_SET); // 读取40位数据 for(int i0; i8; i) { while(HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin) GPIO_PIN_RESET); delay_us(40); if(HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin)) { data | (1 (7-i)); while(HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin) GPIO_PIN_SET); } } return data; }3.2 数据校验与处理DHT11传输的5字节数据格式湿度整数部分湿度小数部分DHT11固定为0温度整数部分温度小数部分DHT11固定为0校验和前4字节和注意实际项目中建议添加超时机制防止程序卡死在等待状态。4. OLED显示驱动4.1 I2C通信基础OLED显示通常采用SSD1306驱动芯片通过I2C接口通信。HAL库提供了简洁的API// OLED写命令函数 void OLED_WriteCmd(uint8_t cmd) { HAL_I2C_Mem_Write(hi2c1, 0x78, 0x00, I2C_MEMADD_SIZE_8BIT, cmd, 1, 100); } // OLED写数据函数 void OLED_WriteData(uint8_t data) { HAL_I2C_Mem_Write(hi2c1, 0x78, 0x40, I2C_MEMADD_SIZE_8BIT, data, 1, 100); }4.2 显示优化技巧页面寻址模式将屏幕分为8页每页8行像素双缓冲技术先写入内存再整体刷新避免闪烁自定义字体使用取模软件生成特定大小的字体// 显示字符串函数示例 void OLED_ShowString(uint8_t x, uint8_t y, char *str) { while(*str) { OLED_ShowChar(x, y, *str); x 8; if(x 120) { x 0; y 2; } } }5. 系统集成与优化5.1 主程序逻辑设计graph TD A[系统初始化] -- B[OLED初始化] B -- C[DHT11初始化] C -- D[读取温湿度] D -- E[数据格式化] E -- F[OLED显示] F -- D5.2 性能优化建议低功耗模式在两次采集间隔进入STOP模式数据滤波采用滑动平均算法处理传感器数据异常处理添加传感器断线检测机制// 主循环示例 while(1) { if(DHT11_ReadData(temp, humi) DHT11_OK) { sprintf(buffer, Temp:%dC, temp); OLED_ShowString(0, 0, buffer); sprintf(buffer, Humi:%d%%, humi); OLED_ShowString(0, 2, buffer); } HAL_Delay(2000); HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); }6. 常见问题解决问题1DHT11无响应检查接线是否正确VCC、DATA、GND确认上拉电阻4.7KΩ已连接测量电源电压3.3V-5V问题2OLED显示异常确认I2C地址0x78或0x7A检查I2C线序SCL、SDA尝试降低I2C时钟速度问题3数据跳动严重增加软件滤波算法检查电源稳定性避免传感器附近有强烈气流实际调试中发现DHT11对时序要求严格微秒级延时误差可能导致读取失败。建议使用定时器实现精确延时而非简单的循环延时。

更多文章