从串口到OLED基于STM32F103与DHT11的桌面级温湿度监测方案在嵌入式开发领域将传感器数据从串口调试升级到可视化显示是项目产品化的重要一步。本文将详细介绍如何利用STM32F103系列微控制器驱动DHT11温湿度传感器并通过OLED屏幕实现直观的数据展示打造一个完整的独立监测设备。1. 硬件架构设计与核心组件选型1.1 主控与传感器选择STM32F103C8T6作为本方案的核心控制器具备以下优势72MHz主频的Cortex-M3内核64KB Flash 20KB SRAM丰富的外设接口I2C、SPI、USART等低至2.0V的工作电压DHT11温湿度传感器的主要特性测量范围20-90%RH湿度0-50℃温度±5%RH湿度精度±2℃温度精度单总线通信协议超小体积15.5mm×12mm×5.5mm1.2 显示模块对比参数SSD1306 OLED (I2C)SSD1306 OLED (SPI)LCD1602接口类型I2CSPI并行分辨率128×64128×6416×2功耗低约20mA中约25mA高约50mA可视角度170°170°120°开发复杂度简单中等复杂提示对于桌面监测场景推荐使用I2C接口的SSD1306 OLED兼顾低功耗与易用性。2. 硬件电路设计与连接2.1 核心电路原理完整的系统包含三个主要部分STM32最小系统电路晶振、复位、电源DHT11传感器接口电路OLED显示模块电路2.2 具体接线方案// STM32F103C8T6 引脚定义 #define DHT11_PIN PB11 // 单总线数据引脚 #define OLED_SDA PB7 // I2C数据线 #define OLED_SCL PB6 // I2C时钟线 #define OLED_RST PB5 // 复位引脚(可选)实际物理连接建议DHT11 VCC → 3.3VDHT11 DATA → PB11需接4.7K上拉电阻DHT11 GND → GNDOLED VCC → 3.3VOLED SDA → PB7OLED SCL → PB6OLED GND → GND3. 软件实现与核心代码解析3.1 开发环境配置安装Keil MDK或STM32CubeIDE添加必要的库文件STM32标准外设库或HAL库SSD1306 OLED驱动库DHT11驱动代码# 示例使用STM32CubeMX生成基础工程 $ stm32cubemx -m STM32F103C8 -i SWD -p USART1,I2C1,GPIO3.2 DHT11驱动优化改进的DHT11数据读取函数typedef struct { uint8_t humi_int; uint8_t humi_deci; uint8_t temp_int; uint8_t temp_deci; uint8_t check_sum; } DHT11_Data; HAL_StatusTypeDef DHT11_Read(DHT11_Data *data) { uint8_t buf[5] {0}; // 发送开始信号 HAL_GPIO_WritePin(DHT11_GPIO, DHT11_PIN, GPIO_PIN_RESET); HAL_Delay(18); HAL_GPIO_WritePin(DHT11_GPIO, DHT11_PIN, GPIO_PIN_SET); delay_us(30); // 检测响应信号 if(!DHT11_Wait_State(GPIO_PIN_RESET)) return HAL_ERROR; if(!DHT11_Wait_State(GPIO_PIN_SET)) return HAL_ERROR; // 读取40位数据 for(int i0; i5; i) { for(int j0; j8; j) { while(HAL_GPIO_ReadPin(DHT11_GPIO, DHT11_PIN) GPIO_PIN_RESET); delay_us(30); buf[i] 1; if(HAL_GPIO_ReadPin(DHT11_GPIO, DHT11_PIN) GPIO_PIN_SET) { buf[i] | 1; while(HAL_GPIO_ReadPin(DHT11_GPIO, DHT11_PIN) GPIO_PIN_SET); } } } // 校验数据 if(buf[0] buf[1] buf[2] buf[3] ! buf[4]) return HAL_ERROR; >void Draw_Temperature_Icon(uint8_t x, uint8_t y, uint8_t size) { // 绘制温度计图标 SSD1306_DrawCircle(xsize/2, ysize/4, size/4, White); SSD1306_DrawLine(xsize/2, ysize/4size/4, xsize/2, ysize, White); SSD1306_DrawLine(xsize/4, y3*size/4, x3*size/4, y3*size/4, White); } void Display_Temperature(float temp) { char str[16]; sprintf(str, %.1f C, temp); // 清空显示区域 SSD1306_FillRect(64, 0, 64, 32, Black); // 绘制图标 Draw_Temperature_Icon(64, 0, 24); // 显示数值 SSD1306_SetCursor(90, 12); SSD1306_WriteString(str, Font_11x18, White); SSD1306_UpdateScreen(); }4. 系统优化与进阶功能4.1 低功耗设计策略工作模式优化采用间歇工作模式每10秒唤醒一次不显示时关闭OLED背光降低STM32主频至内部8MHz RC振荡器电源管理代码void Enter_Low_Power_Mode(void) { // 关闭外设时钟 __HAL_RCC_GPIOB_CLK_DISABLE(); __HAL_RCC_I2C1_CLK_DISABLE(); // 配置OLED进入睡眠模式 SSD1306_WriteCommand(0xAE); // 关闭显示 // 设置STM32进入STOP模式 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); // 唤醒后重新初始化 SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init(); SSD1306_Init(); }4.2 数据记录与趋势分析扩展功能实现方案添加SPI Flash存储历史数据实现简单的温度变化曲线显示设置阈值报警功能趋势显示代码片段void Draw_Trend_Graph(float *data, uint8_t count) { float max -100, min 100; // 找出最大值和最小值 for(int i0; icount; i) { if(data[i] max) max data[i]; if(data[i] min) min data[i]; } // 绘制坐标轴 SSD1306_DrawLine(10, 10, 10, 54, White); SSD1306_DrawLine(10, 54, 118, 54, White); // 绘制数据点 for(int i0; icount-1; i) { uint8_t x1 10 i*(108/count); uint8_t y1 54 - (uint8_t)((data[i]-min)*44/(max-min)); uint8_t x2 10 (i1)*(108/count); uint8_t y2 54 - (uint8_t)((data[i1]-min)*44/(max-min)); SSD1306_DrawLine(x1, y1, x2, y2, White); } }在实际项目中这种可视化升级不仅提升了用户体验也使设备具备了直接部署能力。通过合理优化代码结构系统响应速度可以控制在200ms以内完全满足实时监测需求。