基于STM32与SHT31温湿度传感器实现方案
2025-12-16
基于STM32与SHT31温湿度传感器实现方案
一、硬件连接配置
1.1 引脚连接方案
SHT31 STM32F103C8T6
VCC 3.3V
GND GND
SCL PB6 (I2C1_SCL)
SDA PB7 (I2C1_SDA)
ADDR 悬空(地址0x44)
1.2 硬件设计要点
- 需添加4.7kΩ上拉电阻到SCL/SDA线
- 电源引脚建议添加0.1μF去耦电容
- 通信速率建议配置为400kHz
二、I2C通信协议实现
2.1 HAL库配置代码
// I2C初始化函数
void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 400000;
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;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
}
2.2 传感器指令集
#define SHT31_ADDR 0x44
#define SHT31_MEASURE_HIGH 0x2400
#define SHT31_MEASURE_LOW 0x2400
#define SHT31_READ 0xE000
#define SHT31_SOFT_RESET 0x30A2
// 发送命令函数
HAL_StatusTypeDef SHT31_SendCommand(uint16_t cmd)
{
uint8_t tx_data[2] = {cmd >> 8, cmd & 0xFF};
return HAL_I2C_Master_Transmit(&hi2c1, SHT31_ADDR << 1, tx_data, 2, 100);
}
三、数据采集与处理
3.1 测量流程实现
float temperature;
float humidity;
void SHT31_Read_Data()
{
uint8_t rx_data[6] = {0};
// 发送测量命令
SHT31_SendCommand(SHT31_MEASURE_HIGH);
HAL_Delay(20); // 等待测量完成
// 读取数据
HAL_I2C_Master_Receive(&hi2c1, SHT31_ADDR << 1, rx_data, 6, 100);
// CRC校验
if(CRC8_Check(rx_data, 2) != rx_data[2] ||
CRC8_Check(rx_data+3, 2) != rx_data[5])
{
Error_Handler(); // 数据校验失败
}
// 数据转换
uint16_t raw_temp = (rx_data[0] << 8) | rx_data[1];
uint16_t raw_humi = (rx_data[3] << 8) | rx_data[4];
temperature = -45 + 175 * (float)raw_temp / 65535.0;
humidity = 100 * (float)raw_humi / 65535.0;
}
3.2 CRC校验算法
uint8_t CRC8_Check(uint8_t *data, uint8_t len)
{
const uint8_t polynomial = 0x31;
uint8_t crc = 0xFF;
for(uint8_t i=0; i<len; i++)
{
crc ^= data[i];
for(uint8_t j=0; j<8; j++)
{
if(crc & 0x80)
crc = (crc << 1) ^ polynomial;
else
crc <<= 1;
}
}
return crc;
}
四、完整工程框架
4.1 主程序流程
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_I2C1_Init();
while(1)
{
SHT31_Read_Data();
// 显示数据(通过USART或LCD)
printf("T:%.2fC H:%.2fRH\r\n", temperature, humidity);
HAL_Delay(1000);
}
}
4.2 系统初始化
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
}
参考代码 STM32+SHT31温湿度传感器程序 www.3dddown.com/csa/56446.html
五、完整代码结构
// main.c
#include "main.h"
#include "sht31.h"
float temperature, humidity;
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_I2C1_Init();
MX_USART1_UART_Init();
while(1)
{
SHT31_Read_Data();
Data_Filter();
Check_Alert();
printf("T:%.1fC H:%.1fRH\r\n", temperature, humidity);
Save_Data();
HAL_Delay(1000);
}
}
六、注意事项
- 电源稳定性:建议使用LDO稳压芯片提供3.3V电源
- PCB布局:SCL/SDA走线长度应小于20mm,避免直角转弯
- 固件升级:可通过SWD接口更新CRC校验算法版本
- 环境干扰:在工业现场建议添加金属屏蔽罩
