基于STM32F411的AM2320温湿度采集程序

基于STM32F411的AM2320温湿度采集程序。AM2320是一款常用的数字温湿度复合传感器,它支持I2C单总线两种通信方式。由于其出厂已校准并能直接输出补偿后的数字信息,因此使用起来比较方便。

硬件连接 (AM2320 与 STM32F411)

首先,正确连接硬件是成功读取数据的第一步。AM2320通常采用4引脚封装(VDD、SDA、GND、SCL),但其通信方式可以配置。

AM2320 引脚 STM32F411 引脚 说明
VDD 3.3V 电源正极
GND GND 电源地
SDA 可选 PB7 或 PB9 串行数据线
SCL 可选 PB6 或 PB8 串行时钟线 (I2C模式)

注意

  • I2C 模式:需要连接 SDASCL 两条线,并且通常都需要连接上拉电阻(例如4.7KΩ)到3.3V。
  • 单总线模式:只需连接 SDA 线,SCL引脚需要接地。SDA线上同样需要上拉电阻。

软件编程

I2C 通信模式示例

以下是基于HAL库的STM32F411程序示例,采用I2C通信方式读取AM2320。

1. I2C 初始化

首先需要初始化I2C外设。

#include "stm32f4xx_hal.h"

I2C_HandleTypeDef hi2c1;

void MX_I2C1_Init(void) {
    hi2c1.Instance = I2C1;
    hi2c1.Init.ClockSpeed = 100000; // AM2320建议I2C时钟频率在100kHz以内
    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. AM2320 读取函数

AM2320的读取过程通常分为三步:唤醒传感器发送读取指令读取数据

// 函数声明
uint8_t AM2320_Read_Temp_Hum(I2C_HandleTypeDef *hi2c, float *Temperature, float *Humidity);

// 读取AM2320的温湿度数据
// 返回值: 0-成功, 其他-错误
uint8_t AM2320_Read_Temp_Hum(I2C_HandleTypeDef *hi2c, float *Temperature, float *Humidity) {
    uint8_t buf[8];
    uint16_t hum, temp;
    
    // 1. 唤醒传感器(这个步骤有时可以省略,但为了保证稳定性最好加上)
    // 发送设备地址(写操作) 
    HAL_I2C_Master_Transmit(hi2c, 0xB8, 0x00, 0, HAL_MAX_DELAY);
    HAL_Delay(1); // 等待至少800us
    
    // 2. 发送读取指令
    buf[0] = 0x03; // 功能码:读取寄存器
    buf[1] = 0x00; // 起始地址高字节
    buf[2] = 0x04; // 起始地址低字节(这里是从湿度寄存器开始读)
    buf[3] = 0x02; // 读取的寄存器数量(温湿度共两个寄存器)
    
    if (HAL_I2C_Master_Transmit(hi2c, 0xB8, buf, 4, HAL_MAX_DELAY) != HAL_OK) {
        return 1; // 发送指令失败
    }
    HAL_Delay(2); // 等待传感器准备数据
    
    // 3. 读取数据(6个字节:2字节湿度 + 2字节温度 + 2字节CRC)
    if (HAL_I2C_Master_Receive(hi2c, 0xB9, buf, 6, HAL_MAX_DELAY) != HAL_OK) {
        return 2; // 读取数据失败
    }
    
    // 4. 校验CRC(此处简化处理,实际应用建议添加CRC校验)
    // 可参考AM2320数据手册中的CRC校验方法
    
    // 5. 数据转换
    hum = (buf[0] << 8) | buf[1];   // 组合湿度值
    temp = (buf[2] << 8) | buf[3];  // 组合温度值
    
    *Humidity = hum / 10.0;    // 湿度转换为百分比
    *Temperature = temp / 10.0; // 温度转换为摄氏度
    
    return 0; // 读取成功
}

3. 主循环中的调用

int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_I2C1_Init();
    
    float temperature, humidity;
    
    while (1) {
        if (AM2320_Read_Temp_Hum(&hi2c1, &temperature, &humidity) == 0) {
            // 读取成功,在这里处理温湿度数据
            // 例如:通过串口打印,或者显示到OLED上
            printf("Temperature: %.1f C, Humidity: %.1f %%\n", temperature, humidity);
        } else {
            printf("Failed to read from AM2320 sensor!\n");
        }
        
        HAL_Delay(2000); // 每2秒读取一次
    }
}

单总线通信模式要点

如果你选择使用单总线模式,需要注意以下几点:

  1. 接线:只连接SDA线,并将SCL引脚接地。SDA需要上拉电阻。
  2. 时序要求:单总线通信对时序要求非常严格,需要精确的微秒级延时。
  3. 通信过程
    • 启动信号:主机(MCU)拉低总线至少800μs,然后释放。
    • 传感器响应:AM2320会拉低总线80μs左右作为应答,然后拉高80μs左右。
    • 数据传输:之后开始传输40位(5字节)数据(湿度高位、湿度低位、温度高位、温度低位、CRC校验码)。
  4. 信号表示:位信号“0”和“1”由高电平的持续时间区分(“0”通常为26~28μs,“1”通常为70μs)。

参考程序与资源

  1. Keil5平台上的AM2320单总线示例:这个资源提到在Keil5平台上有用单总线实现AM2320温湿度采集的STM32F411程序。
  2. 代码 AM2320的温度湿度采集的STM32F411程序 www.youwenfan.com/contentcng/51683.html
  3. STM32F103与AM2320的示例:虽然基于STM32F103,但其读取AM2320的逻辑(包括I2C和单总线)是相似的,具有很强的参考价值,尤其提供了CRC校验和数据处理细节。
  4. AM2320数据手册:始终是最权威的参考资料,包含了详细的电气特性、通信协议、时序图和CRC校验算法。
posted @ 2025-09-10 15:43  u95900090  阅读(43)  评论(0)    收藏  举报