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数据线

常见问题排查:

  1. 电源反接 :模块冒烟有焦味(别问我怎么知道的)
  2. I2C无应答 :检查上拉电阻是否接好,用万用表测量SCL/SDA电压应为3.3V
  3. 数据不稳定 :缩短接线长度,在VCC与GND间并联100nF电容

2. 开发环境搭建与工程配置

2.1 工具链安装

推荐使用以下开发工具组合:

  • Keil MDK-ARM (社区版即可)
  • STM32CubeMX (配置硬件外设)
  • 串口调试助手 (如SSCOM、Putty)

安装步骤:

  1. 从官网下载Keil并安装STM32F1支持包
  2. 使用CubeMX生成基础工程代码
  3. 配置项目时勾选 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至关重要:

  1. 发送软复位命令(0x30A2)
  2. 等待15ms初始化时间
  3. 清除状态寄存器(0x3041)
  4. 设置测量模式(单次/周期)

示例初始化代码:

#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校验确保数据可靠性。完整的数据读取流程:

  1. 发送测量命令(如0x2400表示单次高精度模式)
  2. 等待测量完成(典型时间4ms)
  3. 读取6字节数据(温度高/低字节,CRC,湿度高/低字节,CRC)
  4. 分别校验温度和湿度数据的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本地显示作为冗余输出

调试这个项目最大的收获是:嵌入式开发中,数据手册只是起点,真正的知识藏在示波器的波形里和串口输出的错误信息中。当第一次看到稳定的温湿度数据从串口输出时,那种成就感至今难忘。建议每个步骤都做好记录,特别是遇到问题时采取的解决措施——这些笔记会成为你最宝贵的经验积累。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐