4、I2C协议核心概念:主设备与从设备、地址(7位/10位)、读写方向位、起始条件、停止条件、重复起始条件
I2C(Inter-Integrated Circuit)总线之所以能在嵌入式系统中成为事实上的板级通信标准,其根本原因在于它用极少的引脚(SCL时钟线、SDA数据线)实现了多设备间的可靠通信。然而,这种简洁性背后隐藏着一套严谨的时序与寻址规则。本章将深入剖析I2C协议中最核心的六个概念:主从设备角色、设备地址(7位与10位)、读写方向位、起始条件、停止条件以及重复起始条件。理解这些概念是进行I2C设备驱动开发、硬件调试和协议分析的基础,也是从“会用”到“精通”的关键跨越。
上图展示了I2C总线通信的核心要素及其相互关系。主设备通过SCL线产生时钟,并通过SDA线发送地址帧和数据帧。从设备则被动监听总线,识别到自身地址后响应。地址帧由7位地址和1位读写方向位组成,而起始、停止和重复起始条件则定义了通信的边界和切换逻辑。接下来,我们将逐一深入剖析这些概念。
4.1 主设备与从设备:角色与职责划分
核心原理:I2C总线是一种多主多从的通信架构,但在任何时刻,总线上只能有一个主设备(Master)控制总线。主设备负责产生串行时钟信号(SCL)、发起通信、发送起始/停止条件,并决定通信的节奏。从设备(Slave)则被动地监听总线,当检测到与自己地址匹配的地址帧时,才会参与通信。从设备无法主动发起数据传输,只能响应主设备的请求。
判断方法:在硬件设计上,主设备通常是MCU、SoC或FPGA,其SCL引脚配置为推挽输出或开漏输出(需上拉)。从设备则通常是传感器、EEPROM、RTC、ADC/DAC等外围芯片。在软件层面,主设备通过控制寄存器来产生时钟和收发数据,而从设备则通过中断或轮询方式检测地址匹配。
| 特性 | 主设备 (Master) | 从设备 (Slave) |
|---|---|---|
| 时钟控制 | 产生SCL时钟 | 只能接收SCL时钟 |
| 通信发起 | 主动发起起始条件 | 被动等待被寻址 |
| 地址发送 | 发送从设备地址 | 接收并匹配自身地址 |
| 数据方向 | 决定读/写方向 | 根据方向位收发数据 |
| 总线仲裁 | 支持多主仲裁 | 不参与仲裁 |
4.2 设备地址:7位与10位寻址
核心原理:I2C协议定义了两种地址模式:7位地址和10位地址。7位地址是最常用的模式,理论上允许总线上挂载最多112个设备(保留16个地址)。10位地址模式用于扩展寻址空间,允许更多设备接入,但通信开销稍大。地址帧的第一个字节由7位地址(或10位地址的前7位)和1位读写方向位(R/W)组成。
判断方法:在7位地址模式下,从设备地址由硬件引脚(如A0、A1、A2)和芯片固定地址共同决定。例如,常见的EEPROM AT24C02,其地址格式为 1010 A2 A1 A0。在10位地址模式下,第一个字节的前7位固定为 11110XX,其中XX是10位地址的最高两位,第二个字节则发送剩余的8位地址。
// 7位地址示例:AT24C02 EEPROM
// 硬件连接:A2=0, A1=1, A0=0
// 设备地址 = 1010 010 (二进制) = 0x52 (7位)
// 写操作地址字节 = (0x52 << 1) | 0 = 0xA4
// 读操作地址字节 = (0x52 << 1) | 1 = 0xA5
4.3 读写方向位(R/W)
核心原理:地址帧的最低有效位(LSB)是读写方向位。当该位为0时,表示主设备将向从设备写入数据;当该位为1时,表示主设备将从从设备读取数据。方向位在地址帧发送后立即生效,从设备通过ACK应答确认已收到地址和方向。
操作流程:主设备发送起始条件后,先发送地址字节(7位地址+方向位)。从设备在接收到地址字节后,如果地址匹配,会在第9个时钟周期拉低SDA作为ACK应答。如果方向位为写,主设备随后发送数据字节;如果为读,从设备开始发送数据字节。
4.4 起始条件、停止条件与重复起始条件
核心原理:起始条件(S)定义为:在SCL为高电平期间,SDA线从高电平跳变到低电平。停止条件(P)定义为:在SCL为高电平期间,SDA线从低电平跳变到高电平。重复起始条件(Sr)则是在不发送停止条件的情况下,再次发送起始条件。这三个条件构成了I2C通信的“标点符号”,定义了数据传输的边界。
判断方法:在逻辑分析仪或示波器上,起始条件表现为SDA在SCL高电平期间的下跳沿,停止条件表现为上跳沿。重复起始条件与起始条件波形相同,但出现在一次传输的中间,而不是总线空闲时。
| 条件 | SCL状态 | SDA跳变 | 总线状态 | 典型用途 |
|---|---|---|---|---|
| 起始 (S) | 高 | 高→低 | 空闲→忙 | 开始一次传输 |
| 停止 (P) | 高 | 低→高 | 忙→空闲 | 结束一次传输 |
| 重复起始 (Sr) | 高 | 高→低 | 忙→忙 | 改变方向/切换从设备 |
4.5 案例拆解:EEPROM跨页读写中的地址与方向控制
背景与约束:某嵌入式产品使用AT24C256(32KB EEPROM)存储配置参数。该芯片采用7位地址,硬件地址引脚A2/A1/A0均接地,因此7位地址为0x50。系统要求实现跨页(每页64字节)连续写入128字节数据。初始现象是:写入前64字节正常,但写入后64字节时数据错乱。
分析判断过程:通过逻辑分析仪抓取波形发现,在写入第64字节后,主设备发送了停止条件,然后重新发送起始条件和地址。但AT24C256的页写操作限制为单次最多写入64字节,超过页边界会导致数据回卷覆盖。此外,重新起始时地址和方向位正确,但未利用重复起始条件保持总线连续性。
实际操作步骤:
- 将写入策略改为:先发送起始条件+写地址(0xA0),写入目标页起始地址(如0x0000)。
- 连续发送64字节数据,直到页边界。
- 发送停止条件,等待EEPROM内部写周期完成(tWR,典型5ms)。
- 再次发送起始条件+写地址,写入下一页地址(0x0040),继续发送剩余64字节。
- 发送停止条件结束传输。
结果对比:修改后,数据正确写入连续地址。关键改进在于:尊重从设备的页写限制,并在两次写操作之间插入必要的停止条件,确保EEPROM完成内部编程。
复盘经验:I2C通信不仅要关注协议时序,还要深入理解从设备的具体规格。地址和方向位只是“敲门砖”,真正的数据传输细节(如页大小、写周期时间)决定了通信的可靠性。
4.6 总结复盘与常见误区
本章节的核心知识点可以归纳为:主设备控制时钟和通信节奏,从设备通过地址匹配响应;7位地址适用于大多数场景,10位地址用于扩展;读写方向位决定数据流向;起始/停止/重复起始条件定义了通信的边界。在实际开发中,以下误区需要特别警惕:
- 地址位混淆:未区分7位地址和8位地址(含方向位),导致寻址错误。
- 缺少重复起始条件:在“先写后读”操作中,未使用重复起始条件,而是错误地发送停止条件。
- 忽略从设备时序:未考虑EEPROM的写周期时间,连续写入导致数据丢失。
- 总线死锁:从设备未释放SDA线(如ACK未拉低),导致总线一直为低,主设备无法发送起始条件。