STM32F103C8T6 + SHT31温湿度传感器:手把手教你从接线到串口打印完整数据(附避坑点)
·
STM32F103C8T6与SHT31温湿度传感器实战指南:从硬件搭建到数据可视化全流程解析
第一次拿到STM32开发板和SHT31传感器时,那种既兴奋又忐忑的心情记忆犹新。作为嵌入式开发的经典入门项目,温湿度监测看似简单,却暗藏不少新手容易踩的坑。本文将用最直白的语言,带你完整走通从硬件连接到数据可视化的全流程,特别针对那些官方文档没细说、论坛帖子讲不清的实操细节。
1. 硬件准备与电路连接
1.1 元器件清单与选型建议
开始前请确认手头有以下设备:
- STM32F103C8T6最小系统板 (Blue Pill开发板亦可)
- SHT31-DIS温湿度传感器模块 (注意区分I2C和SPI版本)
- 杜邦线若干 (建议使用不同颜色区分功能)
- USB转TTL串口模块 (如CH340、CP2102等)
- 4.7kΩ电阻一对 (用于I2C上拉,部分模块已内置)
注意:市场上SHT31模块质量参差不齐,建议选择带有板载稳压芯片(如AMS1117)和完整滤波电路的产品。我曾遇到过廉价模块因电源噪声导致数据跳变的问题。
1.2 硬件连接详解
正确的接线是项目成功的第一步。参考以下连接方式:
| STM32引脚 | SHT31引脚 | 功能说明 |
|---|---|---|
| 3.3V | VCC | 电源正极 |
| GND | GND | 电源地 |
| PB6 | SCL | I2C时钟线 |
| PB7 | SDA | I2C数据线 |
常见问题排查:
- 电源反接 :模块冒烟有焦味(别问我怎么知道的)
- I2C无应答 :检查上拉电阻是否接好,用万用表测量SCL/SDA电压应为3.3V
- 数据不稳定 :缩短接线长度,在VCC与GND间并联100nF电容
2. 开发环境搭建与工程配置
2.1 工具链安装
推荐使用以下开发工具组合:
- Keil MDK-ARM (社区版即可)
- STM32CubeMX (配置硬件外设)
- 串口调试助手 (如SSCOM、Putty)
安装步骤:
- 从官网下载Keil并安装STM32F1支持包
- 使用CubeMX生成基础工程代码
-
配置项目时勾选
I2C1和USART1外设
2.2 I2C外设关键配置
在CubeMX中需要特别注意的参数:
I2C Mode: I2C
Speed Mode: Standard Mode (100kHz)
Clock Stretching: Enabled
Primary Slave Address: 0x44 (SHT31默认地址)
提示:如果使用硬件I2C遇到通信问题,可以尝试切换到软件模拟I2C,虽然效率较低但稳定性更好。
3. SHT31驱动开发与调试
3.1 传感器初始化序列
正确的上电时序对SHT31至关重要:
- 发送软复位命令(0x30A2)
- 等待15ms初始化时间
- 清除状态寄存器(0x3041)
- 设置测量模式(单次/周期)
示例初始化代码:
#define SHT31_ADDR 0x44
void SHT31_Init(void) {
uint8_t cmd[2];
// 软复位
cmd[0] = 0x30;
cmd[1] = 0xA2;
HAL_I2C_Master_Transmit(&hi2c1, SHT31_ADDR, cmd, 2, 100);
HAL_Delay(20);
// 清除状态寄存器
cmd[0] = 0x30;
cmd[1] = 0x41;
HAL_I2C_Master_Transmit(&hi2c1, SHT31_ADDR, cmd, 2, 100);
}
3.2 数据读取与校验
SHT31采用CRC校验确保数据可靠性。完整的数据读取流程:
- 发送测量命令(如0x2400表示单次高精度模式)
- 等待测量完成(典型时间4ms)
- 读取6字节数据(温度高/低字节,CRC,湿度高/低字节,CRC)
- 分别校验温度和湿度数据的CRC
温度计算示例:
float SHT31_ReadTemperature(void) {
uint8_t data[6];
uint8_t cmd[2] = {0x24, 0x00};
HAL_I2C_Master_Transmit(&hi2c1, SHT31_ADDR, cmd, 2, 100);
HAL_Delay(5);
HAL_I2C_Master_Receive(&hi2c1, SHT31_ADDR, data, 6, 100);
uint16_t tempRaw = (data[0] << 8) | data[1];
return -45 + 175 * (tempRaw / 65535.0);
}
4. 数据输出与可视化
4.1 串口打印格式化输出
通过USART输出易读的数据格式:
printf("[SHT31] Temp: %.2fC, Humidity: %.2f%%\r\n", temp, humi);
推荐串口配置:
- 波特率:115200
- 数据位:8
- 停止位:1
- 无校验
4.2 上位机数据可视化方案
除了串口助手,还可以考虑:
- Python+Matplotlib实时绘图
- Node-RED仪表盘
- 手机APP通过蓝牙接收数据
一个简单的Python接收脚本示例:
import serial
import matplotlib.pyplot as plt
ser = serial.Serial('COM3', 115200)
temps, humis = [], []
while True:
line = ser.readline().decode().strip()
if 'SHT31' in line:
temp = float(line.split('Temp: ')[1].split('C')[0])
humi = float(line.split('Humidity: ')[1].split('%')[0])
temps.append(temp)
humis.append(humi)
plt.clf()
plt.plot(temps, label='Temperature')
plt.plot(humis, label='Humidity')
plt.legend()
plt.pause(0.1)
5. 进阶优化与性能提升
当基础功能实现后,可以考虑以下优化方向:
5.1 低功耗设计技巧
- 使用传感器单次测量模式替代连续模式
- 在两次测量间将MCU进入睡眠状态
- 降低I2C通信频率
5.2 数据滤波算法
// 简易移动平均滤波
#define FILTER_SIZE 5
float tempHistory[FILTER_SIZE];
float filteredTemp = 0;
void updateFilter(float newTemp) {
static uint8_t index = 0;
filteredTemp -= tempHistory[index] / FILTER_SIZE;
tempHistory[index] = newTemp;
filteredTemp += newTemp / FILTER_SIZE;
index = (index + 1) % FILTER_SIZE;
}
5.3 硬件优化建议
- 为传感器添加防尘防潮保护罩
- 在长距离传输时使用屏蔽线
- 考虑添加LCD本地显示作为冗余输出
调试这个项目最大的收获是:嵌入式开发中,数据手册只是起点,真正的知识藏在示波器的波形里和串口输出的错误信息中。当第一次看到稳定的温湿度数据从串口输出时,那种成就感至今难忘。建议每个步骤都做好记录,特别是遇到问题时采取的解决措施——这些笔记会成为你最宝贵的经验积累。
更多推荐
所有评论(0)