1. I2C 总线概述
I2C(Inter-Integrated Circuit)总线是由 Philips(现 NXP)公司在 1980 年代初期开发的一种同步、多主从、串行通信总线。它最初用于连接电视、音响等消费电子产品中的微控制器与外设芯片,凭借其引脚少、结构简单、易于扩展的特点,迅速成为嵌入式系统中最广泛使用的板级总线之一。在 Linux 内核中,I2C 子系统是驱动开发者必须掌握的核心模块,几乎所有传感器、EEPROM、RTC、音频编解码器、电源管理芯片都通过 I2C 与主控通信。
核心要点:I2C 总线仅需两根线(SDA 数据线 + SCL 时钟线)即可连接多个设备,支持标准模式(100 kbit/s)、快速模式(400 kbit/s)和高速模式(3.4 Mbit/s),是嵌入式系统中最经济的板级通信方案。
1.1 I2C 总线历史与演进
| 年份 | 版本 / 里程碑 | 主要特性 |
|---|---|---|
| 1982 | I2C 总线发明 | 100 kbit/s,7 位地址,简单主从通信 |
| 1992 | I2C 规范 1.0 | 标准化时序,增加快速模式(400 kbit/s) |
| 1998 | I2C 规范 2.0 | 引入 10 位地址,扩展地址空间 |
| 2007 | I2C 规范 3.0 | 增加高速模式(3.4 Mbit/s),超快速模式(5 Mbit/s) |
| 2012 | I2C 规范 4.0 | 增加超快速模式(5 Mbit/s),改进电气特性 |
| 2014 | I2C 规范 5.0 | 增加 FM+ 模式(1 Mbit/s),增强驱动能力 |
| 2021 | I2C 规范 7.0 | 增加 I3C 基础规范,向后兼容 I2C |
驱动开发提示:Linux 内核 I2C 子系统支持所有上述模式,驱动开发者只需在设备树中配置
clock-frequency 属性即可选择总线速率。标准模式为 100000,快速模式为 400000,高速模式为 3400000。
1.2 物理层特性:SDA / SCL 线与上拉电阻
I2C 总线物理层极其简洁,只有两条双向信号线:
- SDA(Serial Data Line):串行数据线,用于传输地址和数据。
- SCL(Serial Clock Line):串行时钟线,由主设备产生时钟信号。
两条线都是 开漏(Open-Drain) 结构,即设备只能将线拉低(输出 0),不能主动拉高(输出 1)。高电平由外部上拉电阻提供。这种设计使得多个设备可以安全地共享总线,不会发生短路。
常见错误:上拉电阻阻值选择不当是 I2C 通信故障的首要原因。阻值过大导致上升沿变缓,信号完整性下降;阻值过小导致功耗增加,驱动能力不足。典型推荐值:5V 系统 4.7kΩ,3.3V 系统 2.2kΩ,1.8V 系统 1.0kΩ。
1.3 I2C 协议核心特点
1.3.1 主从架构(Master-Slave)
I2C 总线采用严格的主从通信模型:
- 主设备(Master):负责产生 SCL 时钟信号、发起 START 条件、发送从设备地址和读写位、控制数据传输方向。
- 从设备(Slave):被动响应主设备的寻址,根据地址匹配结果决定是否参与通信。
在任意时刻,总线上只能有一个主设备控制时钟和数据传输。通信结束后,主设备发送 STOP 条件释放总线。
1.3.2 多主机支持(Multi-Master)
I2C 规范允许总线上存在多个主设备。当两个或多个主设备同时尝试发起通信时,通过 总线仲裁(Arbitration) 机制解决冲突:
- 每个主设备在发送数据的同时监控 SDA 线电平。
- 如果某个主设备试图拉高 SDA(发送 1),但检测到 SDA 被其他设备拉低(实际为 0),则该主设备失去仲裁,立即停止发送。
- 仲裁过程不会破坏数据,也不会丢失时钟同步。
驱动开发要点:Linux I2C 核心层自动处理多主机仲裁,驱动开发者无需在从设备驱动中实现仲裁逻辑。但主设备驱动(通常由 SoC 厂商提供)必须正确实现仲裁检测和重试机制。
1.3.3 地址:7 位与 10 位
I2C 总线使用地址来唯一标识从设备。地址在 START 条件之后、读写位之前由主设备发送:
| 地址类型 | 地址范围 | 最大设备数 | 地址格式 | 兼容性 |
|---|---|---|---|---|
| 7 位地址 | 0x00 ~ 0x7F | 112(保留 16 个) | 高 7 位为地址,第 8 位为 R/W | 所有设备都支持 |
| 10 位地址 | 0x000 ~ 0x3FF | 1024 | 前 5 位为 11110,后跟高 2 位 + 低 8 位 | 需要主从设备都支持 |
7 位地址格式:
START | 7-bit Address | R/W (1 bit) | ACK | ... Data ... | STOP
10 位地址格式(第一帧):
START | 11110 | Addr[9:8] | R/W | ACK | Addr[7:0] | ACK | ... Data ... | STOP
实际开发建议:绝大多数 I2C 传感器和芯片使用 7 位地址。在 Linux 设备树中,
reg 属性直接填写 7 位地址值(如 reg = <0x48>)。10 位地址需要额外配置 reg = <0x1A0> 并设置 reg-names = "10-bit"。
1.4 I2C 协议特点总结
| 特性 | 描述 | 驱动开发影响 |
|---|---|---|
| 同步串行 | 由 SCL 时钟同步数据传输 | 无需波特率配置,时序由硬件控制 |
| 主从架构 | 主设备控制时钟和通信方向 | 从设备驱动只需响应中断和寄存器读写 |
| 多主机仲裁 | 多个主设备通过 SDA 电平仲裁 | Linux 核心层处理,驱动无需干预 |
| 7/10 位地址 | 支持 112 或 1024 个从设备 | 设备树中指定地址类型,驱动匹配地址 |
| 开漏输出 | 设备只能拉低,高电平由上拉电阻提供 | 确保总线电平兼容不同电压域 |
| 时钟拉伸 | 从设备可拉低 SCL 延长时钟周期 | 主设备必须支持时钟拉伸,否则通信失败 |
| 应答机制 | 每字节后接收方必须发送 ACK/NACK | 驱动需处理 NACK 重试或错误恢复 |
本章小结:I2C 总线以其简洁的物理层(2 线 + 上拉电阻)、灵活的主从架构、成熟的多主机仲裁和可扩展的地址空间,成为嵌入式 Linux 驱动开发中最基础的板级通信协议。理解 SDA/SCL 的开漏特性、7 位/10 位地址格式以及 START/STOP/ACK 时序,是后续编写 I2C 设备驱动的前提。下一章将深入 I2C 协议的数据传输时序和 Linux I2C 子系统架构。