3. I2C总线协议基础
I2C(Inter-Integrated Circuit)总线是嵌入式系统中应用最广泛的板级通信协议之一,也是RK Sensor驱动与物理传感器芯片之间最核心的数据通道。本章从物理层到协议层,系统讲解I2C总线的完整工作机制,为后续分析RK平台I2C控制器驱动与Sensor设备驱动奠定基础。
3.1 I2C物理层:双线结构与电气特性
I2C总线仅使用两条双向信号线完成所有通信:
- SCL(Serial Clock Line):串行时钟线,由主设备驱动,用于同步数据传输。
- SDA(Serial Data Line):串行数据线,用于双向传输地址和数据。
两条线均通过上拉电阻连接到电源电压(通常为1.8V、3.3V或5V)。总线空闲时,SCL和SDA均为高电平。
关键电气特性:
- 开漏输出(Open-Drain):设备只能将总线拉低,释放后由上拉电阻恢复高电平。
- 线与逻辑(Wired-AND):多个设备可同时挂接在同一总线上,任一设备拉低则总线为低。
- 最大电容负载:标准模式400pF,快速模式550pF,限制总线上设备数量与走线长度。
下图展示了I2C总线物理连接结构:
3.2 起始条件与停止条件
I2C总线上所有通信由主设备发起,通过SCL和SDA的特定电平变化定义传输的起始与结束:
| 条件 | SDA电平变化 | SCL电平 | 时序要求 |
|---|---|---|---|
| 起始条件(S) | 高电平 → 低电平 | 高电平 | SCL高电平期间SDA下降沿 |
| 停止条件(P) | 低电平 → 高电平 | 高电平 | SCL高电平期间SDA上升沿 |
驱动开发要点:在RK平台I2C控制器驱动中,起始和停止条件由硬件自动生成,驱动开发者只需配置寄存器中的START和STOP位。但在GPIO模拟I2C时,必须严格按时序手动控制GPIO电平翻转。
下图展示了起始与停止条件的时序波形:
3.3 数据帧格式与字节传输
I2C总线以字节(8位)为基本传输单位,每个字节后跟随一个应答位(ACK/NACK)。数据传输遵循高位先行(MSB First)原则。
3.3.1 单字节写操作帧格式
| 起始条件 | 7位从机地址 | R/W=0 | ACK | 寄存器地址 | ACK | 数据字节 | ACK | 停止条件 |
| S | A6...A0 | 0 | A | RA7..RA0 | A | D7...D0 | A | P |
3.3.2 多字节读操作帧格式
| S | 从机地址 | W=0 | A | 寄存器地址 | A | Sr | 从机地址 | R=1 | A | 数据1 | A | 数据2 | NA | P |
应答机制:
- ACK(应答):接收方在第9个SCL周期将SDA拉低,表示成功接收字节。
- NACK(非应答):接收方在第9个SCL周期保持SDA高电平,表示传输结束或错误。
- 主设备在读取最后一个字节后发送NACK,通知从设备停止发送。
下图展示了I2C完整的数据帧传输流程:
3.4 7位地址与10位地址
I2C总线支持两种从机地址格式,RK平台Sensor驱动中绝大多数使用7位地址:
| 地址模式 | 地址位宽 | 最大设备数 | 地址范围 | 保留地址 | RK Sensor使用情况 |
|---|---|---|---|---|---|
| 7位地址 | 7 bit | 112(128-16保留) | 0x08 ~ 0x77 | 0x00~0x07, 0x78~0x7F | 绝大多数Sensor使用 |
| 10位地址 | 10 bit | 1008(1024-16保留) | 0x000 ~ 0x3FF | 0x00~0x0F保留 | 极少使用 |
3.4.1 7位地址传输格式
主设备发送的第一个字节高7位为从机地址,最低位为读写方向位:
第一个字节:| A6 | A5 | A4 | A3 | A2 | A1 | A0 | R/W |
MSB LSB
3.4.2 10位地址传输格式
10位地址使用两个字节传输,第一个字节的前5位固定为11110,后2位为地址高2位:
第一个字节:| 1 | 1 | 1 | 1 | 0 | A9 | A8 | R/W |
第二个字节:| A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 |
驱动开发常见错误:在RK平台设备树中配置Sensor I2C地址时,必须使用7位原始地址(如0x48),而不是左移1位后的8位地址。左移操作由I2C控制器驱动在发送时自动完成。错误配置会导致地址不匹配,通信失败。
3.5 时钟同步与仲裁
时钟同步和总线仲裁是I2C总线实现多主设备共存的关键机制,在RK Sensor驱动中虽不常用,但理解其原理有助于排查总线异常。
3.5.1 时钟同步
当多个主设备同时驱动SCL时,通过线与逻辑实现时钟同步:
- 每个主设备内部产生自己的SCL时钟。
- SCL实际电平是所有主设备输出电平的线与结果。
- 如果某个主设备拉低SCL,所有主设备必须等待其释放后才能继续。
- 最终所有主设备的时钟被同步到最慢的那个设备。
3.5.2 总线仲裁
当多个主设备同时尝试控制总线时,通过SDA线的仲裁决定哪个主设备获得总线控制权:
| 仲裁阶段 | 仲裁机制 | 判定结果 |
|---|---|---|
| 地址阶段 | 多个主设备同时发送地址,SDA线与后比较 | 发送低电平的主设备获胜 |
| 数据阶段 | 多个主设备同时发送数据,SDA线与后比较 | 发送低电平的主设备获胜 |
| 丢失仲裁 | 主设备检测到SDA电平与自己发送的不一致 | 立即释放总线,转为从模式 |
下图展示了时钟同步与仲裁的协同工作过程:
3.6 I2C总线速率模式
I2C总线定义了多种速率模式,RK平台Sensor驱动通常使用标准模式或快速模式:
| 模式 | 最大速率 | SCL高电平最小时间 | SCL低电平最小时间 | RK平台支持 |
|---|---|---|---|---|
| 标准模式(Sm) | 100 kbit/s | 4.0 μs | 4.7 μs | 全系列支持 |
| 快速模式(Fm) | 400 kbit/s | 0.6 μs | 1.3 μs | 全系列支持 |
| 快速模式+(Fm+) | 1 Mbit/s | 0.26 μs | 0.5 μs | RK3588等高端型号 |
| 高速模式(Hs) | 3.4 Mbit/s | 0.16 μs | 0.32 μs | 部分型号支持 |
驱动配置建议:在RK平台设备树中,通过
clock-frequency 属性配置I2C总线速率。对于大多数Sensor(如加速度计、陀螺仪、磁力计),推荐使用400kHz快速模式,兼顾传输速度与兼容性。若Sensor数据手册指定最大速率低于400kHz,则必须降级配置。
3.7 I2C与RK Sensor驱动的关联
在RK Sensor驱动框架中,I2C通信是数据采集的底层基础。驱动开发者需要理解以下对应关系:
- 设备树配置:在设备树中指定Sensor挂接的I2C总线编号、从机地址、速率。
- I2C适配器:RK平台I2C控制器在Linux内核中注册为
struct i2c_adapter,提供数据传输接口。 - I2C客户端:每个Sensor设备对应一个
struct i2c_client,包含地址、适配器指针等信息。 - 数据传输接口:驱动通过
i2c_smbus_read_byte_data()、i2c_smbus