手把手教你用STM32的HAL库驱动SHT30温湿度传感器(附完整代码)

张开发
2026/4/5 13:41:45 15 分钟阅读

分享文章

手把手教你用STM32的HAL库驱动SHT30温湿度传感器(附完整代码)
手把手教你用STM32的HAL库驱动SHT30温湿度传感器附完整代码在嵌入式开发中温湿度传感器是环境监测系统的核心组件之一。SHT30作为一款高精度、低功耗的数字温湿度传感器凭借其I2C接口和出色的性能成为STM32开发者的热门选择。本文将带你从零开始使用STM32CubeMX和HAL库实现SHT30的完整驱动解决实际开发中的常见问题并提供可直接移植的代码模块。1. 环境准备与硬件连接1.1 硬件配置要点SHT30传感器与STM32的连接非常简单只需要4根线VCC接3.3V电源GND接地SCL接STM32的I2C时钟线SDA接STM32的I2C数据线注意SHT30的ADDR引脚决定了设备地址。接GND时地址为0x44接VCC时为0x45。本文默认使用0x44地址。1.2 STM32CubeMX配置打开STM32CubeMX选择你的STM32型号在Pinout Configuration选项卡中启用I2C外设配置I2C参数模式I2C速度标准模式(100kHz)或快速模式(400kHz)其他参数保持默认// 生成的I2C初始化代码示例HAL库 hi2c1.Instance I2C1; hi2c1.Init.ClockSpeed 100000; hi2c1.Init.DutyCycle I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 0; hi2c1.Init.AddressingMode I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 0; hi2c1.Init.GeneralCallMode I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode I2C_NOSTRETCH_DISABLE;2. SHT30驱动实现2.1 传感器初始化SHT30支持单次测量和周期性测量两种模式。以下是周期性测量模式的初始化代码#define SHT30_ADDR 0x44 1 // 左移1位HAL库要求 void SHT30_Init(I2C_HandleTypeDef *hi2c) { uint8_t cmd[2]; // 周期性测量模式1次/秒高重复性 cmd[0] 0x21; cmd[1] 0x30; HAL_I2C_Master_Transmit(hi2c, SHT30_ADDR, cmd, 2, HAL_MAX_DELAY); HAL_Delay(150); // 等待传感器初始化完成 }2.2 数据读取与处理SHT30返回的原始数据需要按照公式转换为实际温湿度值int SHT30_ReadData(I2C_HandleTypeDef *hi2c, float *temp, float *hum) { uint8_t cmd[2] {0xE0, 0x00}; uint8_t data[6]; uint16_t rawTemp, rawHum; // 发送读取命令 if(HAL_I2C_Master_Transmit(hi2c, SHT30_ADDR, cmd, 2, 100) ! HAL_OK) return -1; // 读取6字节数据温度CRC湿度CRC if(HAL_I2C_Master_Receive(hi2c, SHT30_ADDR, data, 6, 100) ! HAL_OK) return -1; // 组合原始数据忽略CRC校验 rawTemp (data[0] 8) | data[1]; rawHum (data[3] 8) | data[4]; // 转换为实际值 *temp -45 175 * (float)rawTemp / 65535.0f; *hum 100 * (float)rawHum / 65535.0f; return 0; }3. 常见问题与优化3.1 I2C通信超时处理HAL库的I2C通信可能会因各种原因超时。以下是几种解决方案增加超时时间#define I2C_TIMEOUT 1000 // 1秒超时 HAL_I2C_Master_Transmit(hi2c, addr, data, size, I2C_TIMEOUT);错误重试机制int retry 3; while(retry--) { if(HAL_I2C_Master_Transmit(hi2c, addr, data, size, timeout) HAL_OK) break; HAL_Delay(10); }硬件检查确认上拉电阻通常4.7kΩ已正确连接检查电源稳定性确保时钟配置正确3.2 提高测量精度SHT30在不同模式下有不同的精度表现模式重复性典型精度(温度)典型精度(湿度)电流消耗高高±0.2°C±2%RH1.2mA中中±0.3°C±3%RH0.8mA低低±0.4°C±4%RH0.5mA可以通过修改初始化命令选择不同精度模式// 高精度模式 cmd[0] 0x21; cmd[1] 0x30; // 中精度模式 cmd[0] 0x21; cmd[1] 0x24; // 低精度模式 cmd[0] 0x21; cmd[1] 0x1B;4. 完整示例与应用4.1 主程序示例#include main.h #include sht30.h I2C_HandleTypeDef hi2c1; UART_HandleTypeDef huart2; int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init(); MX_USART2_UART_Init(); float temp, hum; char buf[64]; SHT30_Init(hi2c1); while(1) { if(SHT30_ReadData(hi2c1, temp, hum) 0) { sprintf(buf, Temp: %.2f°C, Hum: %.2f%%\r\n, temp, hum); HAL_UART_Transmit(huart2, (uint8_t*)buf, strlen(buf), HAL_MAX_DELAY); } else { HAL_UART_Transmit(huart2, (uint8_t*)Read failed!\r\n, 13, HAL_MAX_DELAY); } HAL_Delay(1000); } }4.2 进阶应用数据滤波传感器数据可能会有微小波动可以通过简单的移动平均滤波提高稳定性#define FILTER_SIZE 5 typedef struct { float buffer[FILTER_SIZE]; uint8_t index; } Filter_t; float Filter_AddValue(Filter_t *f, float newValue) { f-buffer[f-index] newValue; f-index (f-index 1) % FILTER_SIZE; float sum 0; for(int i 0; i FILTER_SIZE; i) { sum f-buffer[i]; } return sum / FILTER_SIZE; } // 使用示例 Filter_t tempFilter {0}; Filter_t humFilter {0}; float filteredTemp Filter_AddValue(tempFilter, temp); float filteredHum Filter_AddValue(humFilter, hum);

更多文章