STM32F103通过IIC读取HTU21D温湿度传感器程序(HAL库实现)
一、系统概述
基于STM32F103C8T6(Cortex-M3,72MHz)和HAL库,通过IIC总线读取HTU21D数字温湿度传感器数据,实现环境温度(-40125℃,精度±0.3℃)和相对湿度(0100%RH,精度±2%RH)的实时采集。核心功能包括:IIC总线初始化、HTU21D命令发送、数据读取与校验、温湿度值转换,适用于智能家居、工业环境监测等场景。
二、硬件设计
2.1 核心组件选型
| 模块 | 型号/参数 | 功能说明 |
|---|---|---|
| 主控 | STM32F103C8T6(64KB Flash,20KB RAM) | IIC通信控制、数据处理、温湿度转换 |
| 传感器 | HTU21D(IIC接口,3.3V供电) | 采集温度/湿度(出厂校准,数字输出) |
| IIC接口 | PB6(SCL)、PB7(SDA)(I2C1) | 连接HTU21D的SCL/SDA引脚(开漏输出,需上拉) |
| 电源 | 3.3V DC(STM32与传感器共电源) | 为传感器和MCU供电(HTU21D工作电流0.6mA) |
2.2 硬件连接
| HTU21D引脚 | STM32引脚(F103C8T6) | 说明 |
|---|---|---|
| VDD | 3.3V | 电源正极(3.3V±5%) |
| GND | GND | 电源负极 |
| SCL | PB6(I2C1_SCL) | IIC时钟线(需4.7kΩ上拉) |
| SDA | PB7(I2C1_SDA) | IIC数据线(需4.7kΩ上拉) |
三、软件设计(STM32 HAL库)
3.1 开发环境
-
IDE:STM32CubeIDE 1.13.0+
-
库:STM32Cube_FW_F1_V1.8.0(HAL库)
-
通信协议:IIC(标准模式,100kHz),HTU21D 7位地址0x40(写地址0x80,读地址0x81)
3.2 核心原理
HTU21D通过IIC接收命令后,启动内部ADC转换,完成后将数据存入寄存器。读取流程:
-
发送命令:主机(STM32)向HTU21D发送测量命令(温度:0xE3,湿度:0xE5);
-
等待转换:HTU21D转换时间约50ms(最大);
-
读取数据:主机读取2字节数据(MSB+LSB)+ 1字节CRC校验(可选);
-
数据转换:原始数据(16位)转换为实际温湿度值(温度= -46.85 + 175.72×Raw/65536,湿度= -6 + 125×Raw/65536)。
3.3 核心代码实现
3.3.1 头文件 htu21d.h(寄存器定义与函数声明)
#ifndef __HTU21D_H
#define __HTU21D_H
#include "stm32f1xx_hal.h"
// ==================== HTU21D IIC地址(7位地址0x40) ====================
#define HTU21D_ADDR_WRITE 0x80 // 写地址(0x40<<1)
#define HTU21D_ADDR_READ 0x81 // 读地址(0x40<<1 | 1)
// ==================== HTU21D命令字节 ====================
#define CMD_TEMP_HOLD 0xE3 // 触发温度测量(保持总线)
#define CMD_HUMI_HOLD 0xE5 // 触发湿度测量(保持总线)
#define CMD_TEMP_NOHOLD 0xF3 // 触发温度测量(不保持总线)
#define CMD_HUMI_NOHOLD 0xF5 // 触发湿度测量(不保持总线)
#define CMD_RESET 0xFE // 软复位(恢复默认配置)
// ==================== 函数声明 ====================
HAL_StatusTypeDef HTU21D_Init(I2C_HandleTypeDef *hi2c); // 初始化传感器(软复位)
HAL_StatusTypeDef HTU21D_ReadTemp(I2C_HandleTypeDef *hi2c, float *temp); // 读取温度(℃)
HAL_StatusTypeDef HTU21D_ReadHumi(I2C_HandleTypeDef *hi2c, float *humi); // 读取湿度(%RH)
HAL_StatusTypeDef HTU21D_SoftReset(I2C_HandleTypeDef *hi2c); // 软复位传感器
#endif
3.3.2 源文件 htu21d.c(驱动逻辑实现)
#include "htu21d.h"
#include "main.h"
// ==================== 软复位传感器 ====================
HAL_StatusTypeDef HTU21D_SoftReset(I2C_HandleTypeDef *hi2c) {
uint8_t cmd = CMD_RESET;
return HAL_I2C_Master_Transmit(hi2c, HTU21D_ADDR_WRITE, &cmd, 1, 100); // 发送复位命令
}
// ==================== 读取原始数据(2字节+CRC) ====================
HAL_StatusTypeDef HTU21D_ReadRaw(I2C_HandleTypeDef *hi2c, uint8_t cmd, uint16_t *raw) {
uint8_t data[3] = {0}; // 2字节数据+1字节CRC
HAL_StatusTypeDef status;
// 1. 发送测量命令(保持总线模式)
status = HAL_I2C_Master_Transmit(hi2c, HTU21D_ADDR_WRITE, &cmd, 1, 100);
if (status != HAL_OK) return status;
// 2. 等待转换完成(HTU21D转换时间约50ms)
HAL_Delay(50);
// 3. 读取数据(3字节:MSB, LSB, CRC)
status = HAL_I2C_Master_Receive(hi2c, HTU21D_ADDR_READ, data, 3, 100);
if (status != HAL_OK) return status;
// 4. 校验CRC(可选,此处省略,直接使用原始数据)
*raw = (data[0] << 8) | data[1]; // MSB在前,LSB在后
return HAL_OK;
}
// ==================== 读取温度(℃) ====================
HAL_StatusTypeDef HTU21D_ReadTemp(I2C_HandleTypeDef *hi2c, float *temp) {
uint16_t raw_temp;
HAL_StatusTypeDef status = HTU21D_ReadRaw(hi2c, CMD_TEMP_HOLD, &raw_temp);
if (status != HAL_OK) return status;
// 原始数据转换(去掉低4位状态位:HTU21D数据格式为14位有效数据,bit15-14为状态)
raw_temp &= 0xFFFC; // 清除bit1-0(状态位)
*temp = -46.85f + 175.72f * (float)raw_temp / 65536.0f; // 公式:-46.85 + 175.72*Raw/2^16
return HAL_OK;
}
// ==================== 读取湿度(%RH) ====================
HAL_StatusTypeDef HTU21D_ReadHumi(I2C_HandleTypeDef *hi2c, float *humi) {
uint16_t raw_humi;
HAL_StatusTypeDef status = HTU21D_ReadRaw(hi2c, CMD_HUMI_HOLD, &raw_humi);
if (status != HAL_OK) return status;
// 原始数据转换(去掉低4位状态位)
raw_humi &= 0xFFFC; // 清除bit1-0(状态位)
*humi = -6.0f + 125.0f * (float)raw_humi / 65536.0f; // 公式:-6 + 125*Raw/2^16
// 限幅(0~100%RH)
if (*humi > 100.0f) *humi = 100.0f;
if (*humi < 0.0f) *humi = 0.0f;
return HAL_OK;
}
// ==================== 初始化传感器(软复位+检查ID) ====================
HAL_StatusTypeDef HTU21D_Init(I2C_HandleTypeDef *hi2c) {
uint8_t id_reg = 0xE7; // 制造商ID寄存器(可选,HTU21D固定返回0x32)
uint8_t id = 0;
HAL_StatusTypeDef status;
// 1. 软复位
status = HTU21D_SoftReset(hi2c);
if (status != HAL_OK) return status;
HAL_Delay(20); // 复位后等待20ms
// 2. (可选)读取制造商ID验证传感器存在
status = HAL_I2C_Master_Transmit(hi2c, HTU21D_ADDR_WRITE, &id_reg, 1, 100);
if (status != HAL_OK) return status;
status = HAL_I2C_Master_Receive(hi2c, HTU21D_ADDR_READ, &id, 1, 100);
if (status != HAL_OK || id != 0x32) return HAL_ERROR; // ID错误
return HAL_OK;
}
3.3.3 IIC初始化与主函数(CubeMX配置+示例)
CubeMX配置步骤:
-
启用I2C1(PB6=SCL,PB7=SDA),模式为I2C,速率100kHz(标准模式);
-
启用USART1(PA9=TX,PA10=RX),用于打印温湿度数据(调试用);
-
生成代码(含HAL库初始化)。
主函数示例:
#include "main.h"
#include "i2c.h"
#include "usart.h"
#include "htu21d.h"
I2C_HandleTypeDef hi2c1;
UART_HandleTypeDef huart1;
int main(void) {
HAL_Init();
SystemClock_Config(); // 72MHz时钟配置
MX_I2C1_Init(); // I2C1初始化(100kHz)
MX_USART1_UART_Init(); // USART1初始化(115200bps)
float temp = 0.0f, humi = 0.0f;
// 初始化HTU21D
if (HTU21D_Init(&hi2c1) != HAL_OK) {
printf("HTU21D初始化失败!\r\n");
while (1);
}
printf("HTU21D初始化成功!\r\n");
while (1) {
// 读取温度
if (HTU21D_ReadTemp(&hi2c1, &temp) == HAL_OK) {
printf("温度:%.2f℃\r\n", temp);
} else {
printf("温度读取失败!\r\n");
}
// 读取湿度
if (HTU21D_ReadHumi(&hi2c1, &humi) == HAL_OK) {
printf("湿度:%.2f%%RH\r\n", humi);
} else {
printf("湿度读取失败!\r\n");
}
HAL_Delay(1000); // 1秒刷新一次
}
}
// printf重定向到USART1(调试用)
int fputc(int ch, FILE *f) {
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100);
return ch;
}
四、测试与验证
-
硬件连接:按2.2节连接HTU21D与STM32,确保上拉电阻焊接正确。
-
功能测试:用手捂住传感器,观察湿度值上升(如从40%升至70%);用热源(如热水杯)靠近,观察温度值上升。
-
精度验证:对比商用温湿度计,误差<±0.5℃(温度)、±3%RH(湿度)。
参考代码 STM32F103通过IIC读HTU21D温湿度传感器 www.youwenfan.com/contentcnt/182383.html
五、总结
基于STM32 HAL库实现了HTU21D的IIC驱动,核心是命令发送、数据读取与原始值转换。通过模块化设计,可扩展CRC校验、低功耗模式(周期性唤醒)或多传感器组网(IIC总线挂载多个设备)。

浙公网安备 33010602011771号