1. I2C协议与STM32标准库概述
I2C(Inter-Integrated Circuit)是一种简单高效的双向二线制同步串行总线,只需要两根线(SDA和SCL)就能实现设备间的通信。在嵌入式开发中,I2C常用于连接各种传感器、EEPROM等外设。STM32的标准外设库(Standard Peripheral Library)提供了一套完整的I2C驱动函数,封装了底层寄存器操作,大大简化了开发流程。
我第一次使用STM32的I2C接口时,被它丰富的功能所震撼。标准库提供了从初始化配置到数据传输、从DMA控制到中断处理的全套函数,几乎涵盖了I2C通信的所有环节。不过在实际项目中,我也踩过不少坑,比如时钟配置不当导致通信失败,或者忘记处理NACK错误导致程序卡死。
与SPI、USART等其他通信接口相比,I2C有几个显著特点:它是多主从结构的,支持总线仲裁;采用地址寻址方式,同一总线上可以挂载多个设备;通信速率从标准模式(100kHz)到快速模式(400kHz)甚至高速模式(3.4MHz)不等。STM32的I2C外设完全兼容这些特性,还支持SMBus和PMBus协议。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. I2C初始化与基础配置
2.1 硬件初始化流程
在使用I2C前,必须正确配置硬件。首先需要开启相关GPIO和I2C外设的时钟。以I2C1为例,通常使用PB6(SCL)和PB7(SDA),需要将这两个引脚配置为复用开漏输出模式:
c复制RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 复用开漏
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
接下来是I2C外设本身的初始化。标准库提供了I2C_Init()函数,需要填充一个I2C_InitTypeDef结构体。这里有几个关键参数容易出错:
c复制I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; // 快速模式占空比
I2C_InitStructure.I2C_OwnAddress1 = 0xA0; // 主模式可设任意不冲突地址
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 400000; // 400kHz快速模式
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
