一、I2C协议基础认知
I2C(Inter-Integrated Circuit)是Philips公司开发的两线式串行通信协议,广泛应用于微控制器与外设间的短距离通信。其核心优势在于仅需SDA(数据线)和SCL(时钟线)即可实现多设备组网。
1.1 物理层特性
-
拓扑结构:支持多主多从架构,通过地址寻址
-
传输速率:
-
标准模式:100Kbps
-
快速模式:400Kbps
-
高速模式:3.4Mbps
-
-
电平规范:采用开漏输出,需外接上拉电阻(典型值4.7KΩ)
二、I2C协议时序深度解析
2.1 通信时序三要素
-
起始条件(START)
SCL高电平时SDA出现下降沿 -
停止条件(STOP)
SCL高电平时SDA出现上升沿 -
数据有效性
数据在SCL高电平期间必须保持稳定
// 软件模拟时序示例
void I2C_Start(void) {
SDA_HIGH();
SCL_HIGH();
Delay_us(5);
SDA_LOW(); // 产生下降沿
Delay_us(5);
SCL_LOW();
}
void I2C_Stop(void) {
SDA_LOW();
SCL_HIGH();
Delay_us(5);
SDA_HIGH(); // 产生上升沿
Delay_us(5);
}
2.2 完整数据传输流程
-
主机发送START
-
发送7位从机地址 + R/W位
-
接收从机ACK
-
传输数据字节(8bit)
-
接收ACK/NACK
-
循环步骤4-5直至传输完成
-
发送STOP
三、STM32硬件I2C配置实战
3.1 CubeMX配置步骤
-
选择I2C接口(如I2C1)
-
配置模式:
-
主机模式
-
时钟速度(100/400KHz)
-
Duty Cycle(标准模式无需配置)
-
-
设置GPIO模式为复用开漏
-
生成工程代码
3.2 HAL库关键函数解析
// 阻塞式发送函数
HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
uint8_t *pData, uint16_t Size, uint32_t Timeout);
// 带中断的接收函数
HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
// 内存地址读取(适用于EEPROM)
HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
uint16_t MemAddress, uint16_t MemAddSize,
uint8_t *pData, uint16_t Size, uint32_t Timeout);
四、AT24C02 EEPROM驱动实例
4.1 硬件连接
STM32引脚 | AT24C02引脚 |
---|---|
PB6(SCL) | SCL |
PB7(SDA) | SDA |
GND | A0-A2 |
3.3V | VCC |
4.2 读写函数实现
#define EEPROM_ADDR 0xA0 // 1010 000 + R/W
// 写入单字节数据
void EEPROM_WriteByte(uint16_t addr, uint8_t data) {
uint8_t buffer[2] = {addr >> 8, addr & 0xFF};
buffer[1] = data;
HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDR, buffer, 2, 100);
HAL_Delay(5); // 等待写入完成
}
// 读取单字节数据
uint8_t EEPROM_ReadByte(uint16_t addr) {
uint8_t data;
HAL_I2C_Mem_Read(&hi2c1, EEPROM_ADDR, addr,
I2C_MEMADD_SIZE_8BIT, &data, 1, 100);
return data;
}
五、常见问题排查指南
5.1 通信失败常见原因
-
无ACK响应
-
检查从机地址是否正确(含R/W位)
-
确认从机供电正常
-
测量SCL/SDA电压是否达标
-
-
数据错位
-
调整I2C时钟频率(降低速率测试)
-
检查上拉电阻阻值(建议2.2K-10KΩ)
-
-
HAL库卡死
-
添加超时处理机制
-
启用I2C中断/DMA
-
// 错误处理回调函数示例
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) {
if(hi2c->ErrorCode & HAL_I2C_ERROR_AF) {
printf("ACK Failure Detected!\r\n");
}
// 其他错误处理...
}
六、进阶应用技巧
-
多主机仲裁:利用线与特性实现总线竞争
-
时钟延展:从设备控制SCL电平实现速率同步
-
10位地址扩展:支持1024个从机地址
-
SMBus协议:在I2C基础上增加超时、CRC校验等特性
通过本文的深度解析和实例演示,开发者可以快速掌握STM32的I2C通信技术要点。实际应用中需结合示波器分析波形,灵活运用HAL库函数,确保通信稳定可靠。