I2C 协议由飞利浦(Philips,现 NXP)在 1982 年发布,经过多次修订,目前最新的版本是 Rev. 6 (2014)。了解标准有助于我们理解硬件限制和驱动配置。
1. 历史版本
- 1982: 原始版本,仅支持 100 kbit/s。
- 1992 (Rev 1): 引入 Fast-mode (400 kbit/s) 和 10-bit 寻址。
- 1998 (Rev 2): 引入 High-speed mode (3.4 Mbit/s)。
- 2007 (Rev 3): 引入 Fast-mode Plus (1 Mbit/s) 和设备 ID 机制。
- 2012 (Rev 4): 引入 Ultra Fast-mode (5 Mbit/s)。
- 2014 (Rev 6): 修正了一些电气特性描述。
2. 术语定义
- Transmitter (发送器): 发送数据到总线的设备。
- Receiver (接收器): 从总线接收数据的设备。
- Master (主设备): 初始化传输、产生时钟信号和终止传输的设备。
- Slave (从设备): 被主设备寻址的设备。
- Multi-master (多主): 多个主设备尝试控制总线,且不破坏数据的能力。
- Arbitration (仲裁): 当多个主设备同时尝试控制总线时,决定谁获得控制权的机制。
- Synchronization (同步): 同步两个或多个设备时钟信号的机制。
3. 电气特性
3.1 逻辑电平
I2C 依赖于具体的 VDD 电压(通常是 5V, 3.3V 或 1.8V)。
- VIL (低电平输入): 最大 0.3 VDD
- VIH (高电平输入): 最小 0.7 VDD
3.2 上拉电阻
由于是开漏输出,上拉电阻
- 阻值过小: 功耗大,甚至超过 IO 口的灌电流能力(通常 max 3mA)。
- 阻值过大: 信号上升时间(Rise Time)变长,导致波形畸变,无法达到高速率。
计算公式通常涉及总线电容
4. 传输协议细节
4.1 起始和停止条件
- Start: SCL 高,SDA 下降沿。
- Stop: SCL 高,SDA 上升沿。
- Repeated Start (Sr): 在不发送 Stop 的情况下再次发送 Start,用于改变读写方向或寻址另一个设备,且不释放总线控制权。
4.2 数据有效性
SDA 线上的数据必须在 SCL 的高电平期间保持稳定。数据的改变只能在 SCL 的低电平期间进行。
4.3 字节格式
发送到 SDA 线上的每个字节必须是 8 位。每次传输的字节数不受限制。每个字节后必须跟一个响应位 (ACK/NACK)。首先传输最高有效位 (MSB)。
4.4 响应 (ACK) 和 非响应 (NACK)
- ACK: 接收器在第 9 个时钟周期将 SDA 拉低。
- NACK: 接收器在第 9 个时钟周期释放 SDA(保持高电平)。
产生 NACK 的情况:
- 接收器正在执行某些实时操作,无法与主设备通信(如正在写入 EEPROM)。
- 接收器无法理解传输的数据或命令。
- 接收器无法接收更多的数据字节。
- 主设备作为接收器(读取数据),在读取最后一个字节后发送 NACK,告知从设备释放 SDA,以便主设备发送 Stop。
5. 常见误区
- I2C vs SMBus: 虽然它们很像,但在时序、电压电平和超时机制上有细微差别。大多数 I2C 控制器可以兼容 SMBus。
- 地址位移: 7-bit 地址
0x50在发送时左移一位变成0xA0(Write) 或0xA1(Read)。在 Linux dts 和驱动中,始终使用 7-bit 地址 (0x50),内核会自动处理位移。 - 时钟延展: 不是所有主设备都支持时钟延展(Clock Stretching)。如果从设备依赖此功能而主设备不支持,会导致通信错误。