1. STM32硬件I2C外设深度解析
STM32系列单片机内部集成了硬件I2C控制器,这个外设模块的设计充分考虑了嵌入式系统中对通信效率和可靠性的需求。硬件I2C最大的优势在于它能够自动处理通信协议中的底层细节,让开发者可以更专注于业务逻辑的实现。
1.1 I2C控制器架构设计
STM32的I2C控制器采用多级缓冲设计,核心包含三个关键部件:数据寄存器(DR)、移位寄存器和控制逻辑单元。数据寄存器用于暂存待发送或已接收的完整字节数据;移位寄存器负责将数据逐位移出到SDA线上,或从SDA线逐位移入;控制逻辑单元则自动处理起始条件、停止条件、时钟同步和应答位等协议要素。
在实际项目中,我经常使用STM32F103系列的I2C1和I2C2资源。这两个接口的引脚复用情况需要特别注意:
- I2C1默认映射到PB6(SCL)和PB7(SDA),支持重映射到PB8和PB9
- I2C2固定映射到PB10(SCL)和PB11(SDA)
重要提示:使用硬件I2C时,必须正确配置GPIO的复用功能模式,并开启对应的GPIO时钟和I2C外设时钟。我曾遇到过因时钟未开启导致的I2C无法工作的问题,排查了整整一天。
1.2 通信模式与速度配置
STM32硬件I2C支持三种工作模式:
- 标准模式(100kHz)
- 快速模式(400kHz)
- 高速模式(可达3.4MHz,但需要特定型号支持)
在CubeMX中配置时,时钟频率的计算公式为:
code复制I2C频率 = APB1时钟 / (SCLL + SCLH + 3)
其中SCLL和SCLH分别对应SCL低电平和高电平的时钟周期数。我在实际项目中发现,当APB1时钟为36MHz时,设置SCLL=0x4E、SCLH=0x4F可以得到接近100kHz的标准模式时钟。
1.3 中断与DMA机制
硬件I2C的中断系统非常完善,包含以下关键事件中断:
- 起始条件已发送(SB)
- 地址已发送(ADDR)
- 字节传输完成(BTF)
- 接收寄存器非空(RXNE)
- 发送寄存器空(TXE)
在数据量较大的应用中,建议启用DMA传输。以MPU6050传感器为例,当需要连续读取6轴数据时,可以配置DMA自动将接收到的数据存入指定数组,极大减轻CPU负担。配置DMA时需要注意:
- 设置正确的数据宽度(通常为8位)
- 配置存储器地址自增模式
- 启用DMA传输完成中断
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 硬件I2C通信流程详解
2.1 主机发送流程
一个完整的主机发送流程包含以下阶段:
-
起始条件生成:
通过设置CR1寄存器的START位为1,硬件会自动生成起始条件。在代码实现上,HAL库提供了HAL_I2C_Master_Transmit()函数封装了这一过程。 -
地址传输阶段:
发送7位从机地址+读写位(0表示写)。此时硬件会监测总线冲突和应答信号,如果从机无应答,硬件会设置AF(应答失败)
