手把手教你玩转SHT11温湿度传感器

张开发
2026/4/11 17:00:07 15 分钟阅读

分享文章

手把手教你玩转SHT11温湿度传感器
1. SHT11传感器初探从拆箱到上电第一次拿到SHT11温湿度传感器时我注意到这个火柴盒大小的器件竟然集成了温度、湿度两种检测功能。作为Sensirion公司的经典产品它采用电容式湿度检测和带隙温度检测技术测量范围覆盖-40℃~123.8℃的温度和0~100%RH的湿度完全能满足日常环境监测需求。拆开静电袋后你会看到5个引脚VDD电源、GND地线、DATA数据线、SCK时钟线和NC空脚。这里有个新手容易踩的坑——虽然标称工作电压是2.4V~5.5V但实测发现用3.3V供电时稳定性最好。建议在VDD和GND之间并联一个100nF的陶瓷电容和100μF的电解电容这个组合能有效滤除电源干扰。记得我第一次调试时没加电容数据跳变幅度超过5%加上后立即稳定到1%以内。2. 硬件连接实战电路设计与避坑指南2.1 最小系统搭建准备以下材料STM32开发板或其他MCU10KΩ上拉电阻100nF100μF电容组合杜邦线若干接线示意图VDD → 3.3V GND → GND DATA → PB7(需接10K上拉) SCK → PB6 NC → 悬空注意DATA线必须接上拉电阻我曾因为忘记接上拉导致通信始终失败排查了整整两小时。2.2 通信协议解析SHT11使用二线制串行接口时序要求严格。这里分享一个实测可用的初始化函数基于STM32 HAL库void SHT11_Init(void) { GPIO_InitTypeDef GPIO_InitStruct {0}; // 配置SCK为推挽输出 GPIO_InitStruct.Pin GPIO_PIN_6; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull GPIO_NOPULL; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOB, GPIO_InitStruct); // 配置DATA为开漏输出带外部上拉 GPIO_InitStruct.Pin GPIO_PIN_7; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_OD; HAL_GPIO_Init(GPIOB, GPIO_InitStruct); // 初始状态 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET); }3. 通信协议深度解析从启动时序到数据校验3.1 启动传输的奥秘启动序列是通信的关键第一步必须严格遵循这个时序SCK高电平时DATA从高→低SCK产生一个下降沿SCK高电平时DATA从低→高SCK再产生一个下降沿用示波器抓取的理想波形应该像这样SCK: _|‾|_|‾|________ DATA: ‾|___|‾|______对应的代码实现void SHT11_Start(void) { // 步骤1 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET); Delay_us(2); // 步骤2 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET); Delay_us(2); // 步骤3 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); Delay_us(2); // 步骤4 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET); Delay_us(2); // 步骤5 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET); Delay_us(2); // 步骤6 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); Delay_us(2); }3.2 数据读写实战发送命令时要注意每个字节从MSB开始发送在SCK上升沿数据必须稳定命令发送后要检测应答信号这里给出完整的温湿度读取函数float SHT11_ReadTempHumidity(float *humidity) { uint16_t rawTemp, rawHum; uint8_t checksum; // 启动湿度测量 SHT11_Start(); SHT11_WriteByte(0x05); // 湿度测量命令 // 等待测量完成约80ms while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) GPIO_PIN_SET); // 读取湿度数据 rawHum SHT11_ReadByte(1) 8; rawHum | SHT11_ReadByte(1); checksum SHT11_ReadByte(0); // 启动温度测量用于补偿 SHT11_Start(); SHT11_WriteByte(0x03); while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) GPIO_PIN_SET); // 读取温度数据 rawTemp SHT11_ReadByte(1) 8; rawTemp | SHT11_ReadByte(1); SHT11_ReadByte(0); // 数据转换 float temp -40.1 0.01 * rawTemp; // 12bit精度公式 *humidity -2.0468 0.0367 * rawHum - 1.5955e-6 * rawHum * rawHum; *humidity (temp - 25) * (0.01 0.00008 * rawHum); return temp; }4. 高级应用与性能优化4.1 分辨率切换技巧通过状态寄存器可以调整测量分辨率// 设置为高精度模式14bit温度12bit湿度 void SHT11_SetHighResolution(void) { SHT11_Start(); SHT11_WriteByte(0x06); // 写寄存器命令 SHT11_WriteByte(0x00); // 默认分辨率 } // 设置为快速模式12bit温度8bit湿度 void SHT11_SetFastMode(void) { SHT11_Start(); SHT11_WriteByte(0x06); SHT11_WriteByte(0x01); // 修改bit0为1 }实测发现不同模式下的响应时间模式温度测量时间湿度测量时间功耗高精度320ms80ms0.55mA快速80ms20ms0.65mA4.2 温度补偿的玄机湿度测量必须进行温度补偿这里有个优化算法float Calc_Compensated_Humidity(float rawHum, float temp) { // 二次多项式补偿 float hum rawHum * (0.01 0.00008 * rawHum); hum - 2.0468; // 温度补偿 if(temp 25){ hum (temp - 25) * (0.01 0.00008 * rawHum); } return (hum 100) ? 100 : (hum 0.1) ? 0.1 : hum; }在恒温恒湿箱中测试发现经过补偿后的湿度误差从±3%RH降低到±1.8%RH。有个小技巧先测温度再测湿度用前次温度值补偿可以节省一次测量时间。

更多文章