STM32和STM32CubeMX实现SHT30温湿度传感器 保姆级教程

发布时间:2026/6/30 5:21:24
STM32和STM32CubeMX实现SHT30温湿度传感器 保姆级教程 【背景】公司忽然说要知道产品的工作的环境情况要知道工作的温度和湿度。那我就在板子上做个温湿度传感器。温湿度传感器很多有名的DHT11什么的多得很我在淘宝上看了一下发现卖sht系列的比较多我就选了个sht30的。【硬件设计】硬件设计很简单就是i2c通信就行了。VDD3.3V【软件设计】也很简单。我开始在网上看了一下用模拟I2C的很多还有人把程序搞成付费的没有必要。这程序很简单用STM32的HAL库最简单了。几句就能搞定。我现在免费的完全公开给大家。sht30.h#ifndef __SHT30_H_ #define __SHT30_H_ #include main.h #include stdint.h #include sys/types.h #include uart.h #include delay.h #define SHT30_ADDRESS 0x44 // I2C address of the SHT30 sensor #define SHT30_ADDRESS_WRITE (SHT30_ADDRESS 1) // I2C write address #define SHT30_ADDRESS_READ (SHT30_ADDRESS 1) | 0x01 // I2C read address, HAL_I2C_Master_Receive()会自动处理读写位不需要手动处理但是手动处理也可以这个或上的读写位被库函数忽略了。 extern I2C_HandleTypeDef hi2c2; extern uint8_t sht30_data[6]; // Buffer to store the 6 bytes of data read from the SHT30 sensor void sht30_read(uint8_t *data, uint16_t len); uint8_t sht30_crc(const uint8_t *data, uint16_t len); void sht30_crc_test(void); #endif /* __SHT30_H_ */sht30.c#include sht30.h // 初始值 0xFF多项式 0x31 uint8_t sht30_crc(const uint8_t *data, uint16_t len) { uint8_t crc 0xFF; // 初始值为0xFF for (uint16_t i 0; i len; i) { crc ^ data[i]; // 将当前字节与CRC进行异或运算 for (uint8_t j 0; j 8; j) { if (crc 0x80) // 检查最高位是否为1 { crc (crc 1) ^ 0x31; // 左移一位并与多项式0x31进行异或 } else { crc 1; // 仅左移一位 } } } return crc; } void sht30_crc_test(void) { // Test implementation for CRC calculation uint8_t crc_test 0; uint8_t crc_in_data[2] {0xbe, 0xef}; crc_test sht30_crc(crc_in_data, 2); printf(SHT30 CRC 0x%02X\r\n, crc_test); delay_ms(1000); } void sht30_read(uint8_t *data, uint16_t len) { // 发送读取命令 uint8_t cmd[2] {0x2C, 0x06}; // 高精度测量命令 // uint8_t cmd[2] {0xE0, 0x00}; // 周期读测量命令 int status0; status HAL_I2C_Master_Transmit(hi2c2, SHT30_ADDRESS_WRITE, (uint8_t *)cmd, 2, 0xffff); // 发送命令到SHT30, 100ms if (status ! HAL_OK) { printf(SHT30 command transmit failed with status: %d\r\n, status); return; } // 等待测量完成SHT30的测量时间约为15ms delay_ms(20); // 接收数据 status HAL_I2C_Master_Receive(hi2c2, SHT30_ADDRESS_WRITE, data, len, 0xffff); // 接收数据 if (status ! HAL_OK) { printf(SHT30 data receive failed with status: %d\r\n, status); return; } if(sht30_crc(data, 2) ! data[2] || sht30_crc(data 3, 2) ! data[5]) { printf(SHT30 CRC check failed\r\n); return; } uint16_t rawTemp (data[0] 8) | data[1]; uint16_t rawHum (data[3] 8) | data[4]; float temperature -45 175 * ((float)rawTemp / 65535.0); float humidity 100 * ((float)rawHum / 65535.0); printf(SHT30 Temperature: %.2f Degree, Humidity: %.2f%%\r\n, temperature, humidity); }I2C使用的i2c2, 时钟是100khz的。main.cwhile(1)里放下列代码#if 1 sht30_crc_test(); sht30_read(sht30_data, 6); printf(SHT30 data read: ); for (int i 0; i 6; i) { printf(0x%02X , sht30_data[i]); } printf(\r\n); #endif【结果检验】打印出来的结果是这样。办公室的温度是26.64°湿度49.63%用示波器看看i2c的波形如下。放大点看是这样的。这就是i2c的波形并不是很好的方波。但是看起来信号还算比较完美的。好了大功告成亲个嘴儿。