1. I2C通信基础与三种模式概览
I2C(Inter-Integrated Circuit)是嵌入式开发中最常用的串行通信协议之一,它只需要两根线(SCL时钟线和SDA数据线)就能实现主从设备之间的数据交换。在STM32开发中,我们通常使用STM32CubeIDE这个强大的集成开发环境来配置和编写I2C通信代码。
在实际项目中,I2C通信有三种主要的实现模式:轮询模式、中断模式和DMA模式。这三种模式各有特点,适用于不同的应用场景。轮询模式最简单直接,适合初学者入门;中断模式能提高CPU利用率,适合中等数据量的传输;DMA模式则能最大程度解放CPU,适合大数据量或高实时性要求的场景。
以AHT20温湿度传感器为例,这个常见的I2C设备工作地址通常是0x70,它需要先发送初始化命令(0xBE),然后发送触发测量命令(0xAC),最后读取6字节的测量数据。我们将通过这个具体案例,展示三种模式下的代码实现差异。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 轮询模式实现AHT20驱动
2.1 硬件配置与初始化
在STM32CubeIDE中配置I2C轮询模式非常简单。首先打开.ioc文件,在Pinout & Configuration选项卡中找到I2C外设,选择I2C1(根据实际硬件连接选择),将模式设置为"I2C",时钟速度通常设置为100kHz或400kHz。
这里有个实用技巧:即使硬件电路已经加了上拉电阻,我习惯在软件配置中也把SCL和SDA引脚设置为上拉输入模式,这样可以提高通信稳定性。具体操作是在GPIO设置中,将这两个引脚的模式设置为"GPIO_Input",上拉/下拉选择"Pull-up"。
配置完成后生成代码,STM32CubeIDE会自动生成I2C初始化代码。我们只需要在main.c中包含"i2c.h"头文件,就可以直接使用HAL库提供的I2C函数了。
2.2 编写AHT20驱动代码
轮询模式的核心是使用HAL_I2C_Master_Transmit和HAL_I2C_Master_Receive这两个阻塞式函数。下面是我在实际项目中使用的AHT20驱动代码:
c复制// aht20.h
#ifndef INC_AHT20_H_
#define INC_AHT20_H_
#include "i2c.h"
void AHT20_Init();
void AHT20_Read(float* Temperature, float* Humidity);
#endif /* INC_AHT20_H_ */
// aht20.c
#include "aht20.h"
#define AHT20_ADDRESS 0x70
void AHT20_Init() {
uint8_t readBuffer;
HAL_Delay(40); // 等待传感器上电稳定
// 读取状态
