基于STM32F103的DHT11温湿度采集与I2C OLED显示系统搭建指南


啦啦啦♻️
原创
发布时间: 2025-12-31 14:44:06 | 阅读数 0收藏数 0评论数 0
封面
本教程将手把手带你从零开始,使用 STM32F103 系列单片机驱动 DHT11 传感器采集温湿度数据,并通过 I2C 接口的 OLED 屏幕实时显示。内容讲解细致、原理清晰,无需深入复杂的寄存器操作,非常适合 STM32 初学者入门实践,也可作为环境监测类项目的基础开发模板。
1

准备材料

在开始项目前,请确保准备好以下硬件组件:

  1. STM32F103 最小系统板(1 块)
  2. 推荐使用 STM32F103C8T6 核心板,资源足够、价格实惠,是初学者的理想选择。
  3. DHT11 温湿度传感器模块(1 个)
  4. 采用单总线数字输出。建议选用已集成上拉电阻的版本,可省去外接电阻,简化电路连接。
  5. I2C 接口 OLED 显示屏(1 块)
  6. 建议选用常见的 0.96 英寸、分辨率为 128×64 的 OLED 屏,支持 I2C 通信,接线简单。
  7. ST-Link V2 下载器(1 个)
  8. 用于向 STM32 烧录程序,同时可为开发板提供电源(但供电能力有限,复杂场景建议外接电源)。
  9. 杜邦线若干(公对母 / 公对公)
  10. 用于连接各模块之间的信号线与电源线。
  11. 10kΩ 电阻(可选,1 个)
  12. 若所用 DHT11 模块未内置下拉电阻,可在 DATA 引脚添加一个 10kΩ 下拉电阻以增强信号稳定性(多数成品模块已包含,通常无需额外添加)。
  13. 外部直流电源(可选,5V 或 3.3V)
  14. 当系统功耗较高或 ST-Link 供电不足时,建议使用独立电源为系统稳定供电。

请提前安装并配置好以下软件工具:

  1. Keil MDK-ARM(v5 及以上)
  2. 作为主流的 ARM 开发环境,用于编写、调试和编译 STM32 工程,并生成可烧录的 .hex 或 .bin 文件。
  3. ST-Link 驱动程序(最新版)
  4. 安装后,电脑可正确识别 ST-Link 下载器,实现程序下载与在线调试功能。
  5. OLED 驱动代码(教程内提供)
  6. 本教程将包含适配 I2C 接口 OLED 的完整驱动代码,无需额外寻找第三方库,开箱即用。
2

硬件接线

DHT11:简单可靠的温湿度感知

  1. 一句话理解:一个能直接输出数字温湿度值的小模块,接一根数据线就能用。
  2. 关键参数
  3. 温度:0~50℃(±2℃误差)
  4. 湿度:20%~90% RH(±5% 误差)
  5. 供电:3.3V 或 5V 都行,但 STM32 系统建议统一用 3.3V
  6. 通信特点:单总线协议,对时序敏感——软件需精准控制拉低/释放时间。
  7. 注意
  8. 小数位恒为 0,实际只需读两个整数。
  9. DATA 引脚若无上拉电阻(看模块是否带),必须外接 10kΩ 到 3.3V,否则通信不稳定。

I2C OLED:两根线搞定显示

  1. 一句话理解:自发光小屏,对比度高,接 SDA/SCL 就能显示文字图形。
  2. 关键点
  3. 分辨率:128×64
  4. 接口:I2C(常用地址 0x3C / 0x78)
  5. 供电只能是 3.3V! 多数屏幕不耐 5V,一接就可能报废。
  6. 接线极简:VCC、GND、SDA、SCL —— 四根线全搞定。

推荐接线(STM32F103C8T6)


模块

接到STM32的引脚

说明

DHT11 VCC

3.3V

别用 5V,保持系统电平一致

DHT11 GND

GND

所有 GND 必须连在一起

DHT11 DATA

PA1

可换其他 GPIO,代码同步改即可

OLED VCC

3.3V

⚠️ 再强调:不要接 5V!

OLED GND

GND

共地是通信基础

OLED SDA

PB7

对应 I2C1_SDA

OLED SCL

PB6

对应 I2C1_SCL

ST-Link

PA13 (SWDIO)、PA14 (SWCLK)、GND、3.3V

最少四线,烧录+供电

实操提醒(避坑指南)

  1. 共地是底线:哪怕只有一处没接地,DHT11 读数乱跳、OLED 不亮都很常见。
  2. OLED 怕高电压:标“兼容 5V”的也别冒险,3.3V 最安全。
  3. DHT11 要“拉一把”:没有上拉电阻 = 信号飘忽 = 读数失败。不确定?加个 10kΩ 更稳。
  4. 杜邦线别虚插:看似插进去了,其实接触不良——这是“偶尔成功、经常失败”的头号原因。


3

编写代码

// DHT11驱动代码(dht11.h+dht11.c)
/**
* @brief 从 DHT11 传感器读取一次温湿度数据
* @note DHT11 实际测量范围:温度 0~50°C,湿度 20~90% RH(非凝结)
* 小数部分恒为 0,仅返回整数。
* @param temp: 指向存储温度值(单位:°C)的变量指针
* @param humi: 指向存储湿度值(单位:%RH)的变量指针
* @retval 0: 读取成功
* @retval 1: 通信失败(无响应、校验错误等)
*/
uint8_t dht11_read_data(uint8_t *temp, uint8_t *humi)
{
uint8_t buf[5];
dht11_reset();
if (dht11_check() != 0) {
return 1; // 未收到传感器应答
}

for (uint8_t i = 0; i < 5; i++) {
buf[i] = dht11_read_byte();
}

// 校验:前4字节之和的低8位应等于第5字节
if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]) {
*humi = buf[0]; // 湿度整数部分
*temp = buf[2]; // 温度整数部分
return 0;
}
return 1; // 校验失败
}

/**
* @brief 初始化 DHT11 的 GPIO 并检测传感器是否存在
* @note 通过发送复位信号并检查传感器是否返回应答脉冲
* @param 无
* @retval 0: 传感器存在且响应正常
* @retval 1: 无响应,可能未连接或损坏
*/
uint8_t dht11_init(void)
{
dht11_gpio_init();
dht11_reset();
return dht11_check(); // 0 = 正常,1 = 无应答
}

/**
* @brief 带重试机制的 DHT11 初始化,提高启动可靠性
* @note 最多重试 10 次,每次间隔 200ms(DHT11 建议读取间隔 ≥1s,此处仅用于初始化检测)
* @param 无
* @retval 0: 初始化成功(传感器已就绪)
* @retval 1: 多次尝试后仍无法检测到传感器
*/
uint8_t dht11_init_check(void)
{
uint8_t retries = 10;
while (retries-- > 0) {
if (dht11_init() == 0) {
return 0; // 成功检测到 DHT11
}
delay_ms(200);
}
return 1; // 超时,未检测到传感器
}

/**
****************************************************************************************************
* @file DHT11.h
* @author Embedded Engineer
* @version V1.0.0
* @date 2025-11-23
* @brief DHT11 温湿度传感器驱动头文件(适用于 STM32F103 系列)
****************************************************************************************************
* @attention
*
* - 本驱动基于单总线协议,使用 GPIO 模拟时序。
* - DHT11 测量范围:温度 0~50°C,湿度 20~90% RH(精度:±2°C / ±5% RH)。
* - 两次读取间隔建议 ≥1 秒,否则可能返回错误数据。
* - 实验平台:STM32F103C8T6(Blue Pill)
*
****************************************************************************************************
*/


#ifndef __DHT11_H
#define __DHT11_H

#include "main.h"

/* ==================== 用户配置区 ==================== */
/** @defgroup DHT11_GPIO_Config DHT11 引脚配置
* @{
*/
#define DHT11_DQ_GPIO_Port GPIOA
#define DHT11_DQ_Pin GPIO_PIN_1 /*!< 可根据实际接线修改 */
/** @} */

/* ==================== IO 操作宏 ==================== */
/** @brief 设置 DHT11 数据引脚为输出高/低电平 */
#define DHT11_DQ_OUT_HIGH() HAL_GPIO_WritePin(DHT11_DQ_GPIO_Port, DHT11_DQ_Pin, GPIO_PIN_SET)
#define DHT11_DQ_OUT_LOW() HAL_GPIO_WritePin(DHT11_DQ_GPIO_Port, DHT11_DQ_Pin, GPIO_PIN_RESET)

/** @brief 读取 DHT11 数据引脚电平(输入模式) */
#define DHT11_DQ_IN() HAL_GPIO_ReadPin(DHT11_DQ_GPIO_Port, DHT11_DQ_Pin)

/* ==================== 函数声明 ==================== */

/**
* @brief 带重试机制的 DHT11 初始化(最多尝试 10 次)
* @retval 0: 成功检测到传感器
* @retval 1: 初始化失败(超时或无响应)
*/
uint8_t dht11_init_check(void);

/**
* @brief 发送复位信号并检测 DHT11 是否应答
* @retval 0: 应答正常(存在 DHT11)
* @retval 1: 无应答(可能未连接或损坏)
*/
uint8_t dht11_check(void);

/**
* @brief 读取一次温湿度数据(整数部分)
* @param temp: 指向温度值(°C)的指针(范围 0~50)
* @param humi: 指向湿度值(%RH)的指针(范围 20~90)
* @retval 0: 读取成功
* @retval 1: 通信失败或校验错误
*/
uint8_t dht11_read_data(uint8_t *temp, uint8_t *humi);

#endif /* __DHT11_H */


4

显示效果

给系统上电(可通过 ST-Link 供电,或使用独立的 3.3V 电源),正常情况下 OLED 屏幕应显示如下内容:

温度: XX ℃
湿度: XX %

其中 XX 为 DHT11 实时读取的数值(例如:温度 25,湿度 50)。

测试方法

用手指轻轻握住 DHT11 传感器模块(注意不要让汗液直接滴落或污染电路),观察屏幕数据变化。

  1. 温度会因手部热量而明显上升;
  2. 湿度也可能缓慢升高,这是由于皮肤散发的水汽被传感器感知所致。
阅读记录0
点赞0
收藏0
禁止 本文未经作者允许授权,禁止转载
猜你喜欢
评论/提问(已发布 0 条)
评论 评论
收藏 收藏
分享 分享
pdf下载 下载
pdf下载 举报