基于STM32F411的AM2320温湿度传感器
一、硬件连接配置
// 硬件连接定义(根据实际引脚调整)
#define AM2320_I2C_ADDR 0x5C << 1 // 7位地址左移1位(0xB8写/0xB9读)
#define AM2320_SDA_PIN GPIO_PIN_9
#define AM2320_SCL_PIN GPIO_PIN_8
#define AM2320_PORT GPIOB
// 上拉电阻配置(需外接5.1KΩ电阻)
void AM2320_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
// SDA配置为开漏输出
GPIO_InitStruct.Pin = AM2320_SDA_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(AM2320_PORT, &GPIO_InitStruct);
// SCL配置为推挽输出
GPIO_InitStruct.Pin = AM2320_SCL_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(AM2320_PORT, &GPIO_InitStruct);
}
二、I2C通信协议实现
// 基本I2C操作函数
void AM2320_I2C_Start(void) {
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SDA_PIN, GPIO_PIN_SET);
HAL_Delay(2);
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SCL_PIN, GPIO_PIN_SET);
HAL_Delay(4);
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SDA_PIN, GPIO_PIN_RESET);
HAL_Delay(3);
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SCL_PIN, GPIO_PIN_RESET);
}
void AM2320_I2C_Stop(void) {
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SDA_PIN, GPIO_PIN_RESET);
HAL_Delay(3);
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SCL_PIN, GPIO_PIN_SET);
HAL_Delay(4);
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SDA_PIN, GPIO_PIN_SET);
HAL_Delay(5);
}
uint8_t AM2320_I2C_WriteByte(uint8_t data) {
uint8_t ack;
for (int i=0; i<8; i++) {
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SDA_PIN,
(data & 0x80) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_Delay(4);
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SCL_PIN, GPIO_PIN_SET);
HAL_Delay(4);
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SCL_PIN, GPIO_PIN_RESET);
data <<= 1;
}
// 接收ACK
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SDA_PIN, GPIO_PIN_IN);
HAL_Delay(4);
ack = HAL_GPIO_ReadPin(AM2320_PORT, AM2320_SDA_PIN);
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SDA_PIN, GPIO_PIN_OUT);
HAL_Delay(4);
return ack;
}
uint8_t AM2320_I2C_ReadByte(uint8_t ack) {
uint8_t data=0;
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SDA_PIN, GPIO_PIN_IN);
for (int i=0; i<8; i++) {
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SCL_PIN, GPIO_PIN_SET);
HAL_Delay(4);
data <<= 1;
data |= HAL_GPIO_ReadPin(AM2320_PORT, AM2320_SDA_PIN);
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SCL_PIN, GPIO_PIN_RESET);
HAL_Delay(4);
}
HAL_GPIO_WritePin(AM2320_PORT, AM2320_SDA_PIN, ack ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_Delay(4);
return data;
}
三、传感器数据采集流程
#define AM2320_REG_HUMI_HIGH 0x00
#define AM2320_REG_TEMP_HIGH 0x02
float Read_Humidity(void) {
uint8_t data[4] = {0};
// 唤醒传感器
AM2320_I2C_Start();
AM2320_I2C_WriteByte(AM2320_I2C_ADDR); // 发送设备地址
HAL_Delay(1000); // 等待唤醒
// 发送读取指令
AM2320_I2C_Start();
AM2320_I2C_WriteByte(AM2320_I2C_ADDR | 0x01); // 读模式
data[0] = AM2320_I2C_ReadByte(1); // 湿度高字节
data[1] = AM2320_I2C_ReadByte(1); // 湿度低字节
data[2] = AM2320_I2C_ReadByte(1); // 温度高字节
data[3] = AM2320_I2C_ReadByte(0); // CRC校验
AM2320_I2C_Stop();
// CRC校验
if (CRC16_Check(data, 4, data[4]) != 0) {
return -999; // 错误值
}
return (data[0] << 8 | data[1]) / 10.0f;
}
float Read_Temperature(void) {
// 类似湿度读取流程,修改寄存器地址为0x02
// 省略重复代码...
}
// CRC16校验算法
uint16_t CRC16_Check(uint8_t *buf, uint8_t len, uint8_t crc_buf) {
uint16_t crc = 0xFFFF;
for (int i=0; i<len; i++) {
crc ^= (uint16_t)buf[i] << 8;
for (int j=0; j<8; j++) {
if (crc & 0x8000) crc = (crc << 1) ^ 0x1021;
else crc <<= 1;
}
}
return crc ^ crc_buf;
}
四、完整工程配置
- STM32CubeMX配置:
- 时钟配置:HSE 8MHz → PLL 168MHz
- GPIO配置:PB8/PB9设为GPIO_Output(开漏模式)
- 禁用HAL库默认I2C驱动
- 系统初始化:
int main(void) {
HAL_Init();
SystemClock_Config();
AM2320_GPIO_Init();
while (1) {
float hum = Read_Humidity();
float temp = Read_Temperature();
printf("Temp: %.1fC, Hum: %.1f%%\r\n", temp, hum);
HAL_Delay(2000);
}
}
参考代码 AM2320的温度湿度采集的STM32F411程序 www.3dddown.com/cna/51683.html
五、关键参数说明
| 参数 | 数值 | 说明 |
|---|---|---|
| 工作电压 | 3.3V-5V | 推荐3.3V供电 |
| 测量范围 | -40℃~80℃ | 温度精度±0.5℃ |
| 0-99.9%RH | 湿度精度±3%RH | |
| 通信方式 | I2C | 默认地址0x5C(7位) |
| 数据更新周期 | 2秒 | 连续读取需间隔>2秒 |
六、调试技巧
-
逻辑分析仪捕获:
- 捕获I2C波形验证时序(起始/停止条件)
- 检查数据帧格式是否符合规范
-
错误处理:
if (hum < -40 || hum > 80) { // 触发错误处理 } -
低功耗优化:
// 进入睡眠模式前关闭GPIO HAL_GPIO_DeInit(AM2320_PORT, AM2320_SDA_PIN | AM2320_SCL_PIN);
七、扩展功能实现
1.数据存储:
#define EEPROM_ADDR 0x50
void Save_Calibration(uint16_t offset) {
HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDR, 0x00, I2C_MEMADD_SIZE_8BIT,
(uint8_t*)&offset, 2, 100);
}
2.OLED显示:
void Display_Data(float temp, float hum) {
OLED_Clear();
OLED_ShowString(0,0,"Temp:");
OLED_ShowNum(0,4,temp,1,16);
OLED_ShowString(0,6,"C ");
OLED_ShowString(1,0,"Hum:");
OLED_ShowNum(1,4,hum,1,16);
OLED_ShowString(1,6,"%");
}
该方案通过标准I2C协议实现AM2320数据采集,实际应用中需注意:
- 确保SCL/SDA上拉电阻(建议4.7KΩ)
- 首次读取前需等待传感器唤醒(>200ms)
- 连续读取需间隔>2秒避免数据冲突
- 建议添加软件滤波算法处理异常数据

浙公网安备 33010602011771号