基于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);
  }
}

六、注意事项

  1. 电源稳定性:建议使用LDO稳压芯片提供3.3V电源
  2. PCB布局:SCL/SDA走线长度应小于20mm,避免直角转弯
  3. 固件升级:可通过SWD接口更新CRC校验算法版本
  4. 环境干扰:在工业现场建议添加金属屏蔽罩