2. I2C协议详解:起始条件、停止条件、数据有效性、应答机制、7位与10位地址模式
I2C(Inter-Integrated Circuit)总线协议由Philips(现NXP)公司开发,是一种同步、多主从、串行通信总线。它仅需两根双向信号线——串行数据线(SDA)和串行时钟线(SCL)——即可实现设备间的数据交换。本章将深入剖析I2C协议的核心时序与机制,为后续驱动开发和设备树配置奠定基础。
2.1 起始条件(START Condition)与停止条件(STOP Condition)
I2C总线的空闲状态是SCL和SDA均为高电平。数据传输的起始和结束由主控制器通过特定的信号跳变来标志。
- 起始条件(S): 当SCL为高电平时,SDA从高电平切换到低电平。此信号表示一次新的数据传输开始,主控制器在发送起始条件后,会立即发送从设备地址。
- 停止条件(P): 当SCL为高电平时,SDA从低电平切换到高电平。此信号表示本次数据传输结束,总线恢复空闲状态。
起始和停止条件均由主控制器产生。在一次传输中,可以连续发送多个数据帧,但每个数据帧之间必须由起始和停止条件界定。
2.2 数据有效性(Data Validity)
I2C协议规定,在SCL时钟的高电平周期内,SDA上的数据必须保持稳定。只有在SCL为低电平时,SDA上的数据才允许发生变化。
- 数据采样: 接收方在SCL的上升沿或高电平期间对SDA进行采样。
- 数据变化: 发送方必须在SCL为低电平时更新SDA上的数据位。
- 字节格式: 每次传输的数据以字节(8位)为单位,高位(MSB)在前,低位(LSB)在后。
2.3 应答机制(ACK/NACK)
I2C协议要求每个字节传输完成后,接收方必须向发送方提供一个应答位(ACK)或非应答位(NACK),以确认数据是否成功接收。
- 应答位(ACK): 在第9个SCL时钟周期,接收方将SDA拉低,表示已成功接收上一个字节,并准备好接收下一个字节。
- 非应答位(NACK): 在第9个SCL时钟周期,接收方保持SDA为高电平,表示未成功接收或不再接收数据。
主控制器在发送完地址或数据后,必须释放SDA线,以便从设备拉低SDA产生ACK。如果主控制器未收到ACK,通常会发送停止条件终止传输。
| 场景 | 发送方 | 接收方 | SDA状态(第9时钟) | 后续操作 |
|---|---|---|---|---|
| 地址匹配成功 | 主控制器 | 从设备 | 低电平(ACK) | 继续传输数据 |
| 地址匹配失败 | 主控制器 | 从设备 | 高电平(NACK) | 主控制器发送停止条件 |
| 数据接收成功 | 发送方 | 接收方 | 低电平(ACK) | 发送下一个字节 |
| 数据接收失败/结束 | 发送方 | 接收方 | 高电平(NACK) | 发送方停止发送 |
2.4 7位地址模式
7位地址模式是I2C协议中最常用的寻址方式。主控制器在起始条件后发送的第一个字节包含7位从设备地址和1位读写标志位(R/W)。
- 地址字节格式: 高7位(D7-D1)为从设备地址,最低位(D0)为读写标志。0表示写操作,1表示读操作。
- 地址范围: 7位地址的有效范围是0x00到0x7F,但0x00和0x01通常保留用于特殊用途(如通用呼叫地址)。
- 设备树配置: 在设备树中,7位地址通常以16进制格式直接指定,例如
reg = <0x48>;。
2.5 10位地址模式
10位地址模式是为了扩展I2C总线上可挂载的设备数量而设计的。它兼容7位地址模式,通过保留的1111 0XX地址前缀来标识10位地址传输。
10位地址的传输分为两个阶段:
- 第一个字节: 高5位为11110,接着是10位地址的高2位(A9和A8),最后是读写标志位(R/W)。
- 第二个字节: 10位地址的低8位(A7-A0)。
| 特性 | 7位地址模式 | 10位地址模式 |
|---|---|---|
| 地址字节数 | 1字节(地址+读写位) | 2字节(首字节+次字节) |
| 最大设备数 | 112(0x08-0x77可用) | 1024 |
| 首字节特征 | 地址高7位 + R/W | 11110 + A9/A8 + R/W |
| 兼容性 | 所有I2C设备支持 | 需要主从设备均支持 |
| 驱动复杂度 | 低 | 中(需处理两次地址发送) |
reg 属性指定地址时,如果地址值大于0x7F,内核会自动识别为10位地址。但并非所有I2C控制器驱动都完美支持10位地址,使用前需确认。
2.6 完整数据传输流程
结合上述所有机制,一次完整的I2C写操作流程如下:
- 起始条件: 主控制器在SCL高电平时将SDA拉低。
- 发送地址: 主控制器发送7位或10位从设备地址,后跟写标志位(0)。
- 等待应答: 主控制器释放SDA,从设备在第9个时钟周期拉低SDA作为ACK。
- 发送数据: 主控制器发送一个字节的数据(8位,MSB先发)。
- 等待应答: 从设备再次发送ACK。
- 重复步骤4-5: 直到所有数据发送完毕。
- 停止条件: 主控制器在SCL高电平时将SDA拉高,结束传输。
2.7 总结
I2C协议通过简洁的时序和灵活的地址机制,实现了高效的板级通信。起始条件和停止条件定义了传输的边界,数据有效性规则保证了数据的正确采样,应答机制提供了可靠的流控,而7位/10位地址模式则满足了不同规模的设备寻址需求。掌握这些基础协议要素,是后续编写I2C设备驱动、配置设备树以及调试通信问题的前提。