1. I2C 总线协议基础
1.1 I2C 总线历史
I2C(Inter-Integrated Circuit)总线由 Philips Semiconductors(现 NXP Semiconductors)于 1982 年发明。最初设计目的是为电视、录像机等消费电子产品提供一种简单、低成本、仅需两根线的芯片间通信方案。1992 年发布了第一个标准化版本(I2C-bus Specification Version 1.0),定义了 100 kHz 的标准模式(Standard-mode, Sm)。后续版本逐步扩展:1998 年增加 400 kHz 快速模式(Fast-mode, Fm),2007 年引入 1 MHz 快速模式+(Fast-mode Plus, Fm+)和 3.4 MHz 高速模式(High-speed mode, Hs-mode),2012 年发布超快速模式(Ultra Fast-mode, UFm,单向 5 MHz)。I2C 现已成为嵌入式系统中最广泛使用的板级总线之一,被 SMBus(System Management Bus)、PMBus(Power Management Bus)等衍生标准继承。
1.2 物理层特性:SDA/SCL 开漏结构
I2C 总线物理层仅使用两条信号线:串行数据线(SDA,Serial Data Line)和串行时钟线(SCL,Serial Clock Line)。两条线均采用开漏(Open-Drain)结构,配合外部上拉电阻连接到电源电压 VDD。开漏结构的关键特性:
- 线与(Wired-AND)逻辑:任何设备都可以将总线拉低(输出 0),但无法主动驱动总线为高(输出 1)。总线高电平由外部上拉电阻实现。当所有设备释放总线(输出高阻)时,上拉电阻将总线拉高。
- 多主控仲裁:多个主控设备可以同时尝试驱动时钟和数据线,开漏结构允许无冲突的仲裁——检测到总线被其他设备拉低的主控自动退出。
- 电平灵活性:上拉电阻连接到 VDD,因此总线高电平由 VDD 决定。不同电压域的设备(如 3.3V 和 5V)可通过选择合适的 VDD 和上拉电阻实现电平兼容。
- 双向性:SDA 和 SCL 均为双向线,主控设备驱动时钟,从设备可拉低 SCL 实现时钟拉伸(Clock Stretching)以进行流控。
1.3 I2C 与 SPI、UART 对比
I2C、SPI(Serial Peripheral Interface)和 UART(Universal Asynchronous Receiver-Transmitter)是嵌入式系统中最常用的三种串行通信协议。它们在信号线数量、通信模式、速度、拓扑结构等方面存在显著差异。下表从多个维度进行对比:
| 对比维度 | I2C | SPI | UART |
|---|---|---|---|
| 信号线数量 | 2 线(SDA + SCL) | 4 线(MOSI + MISO + SCLK + CS) | 2 线(TX + RX) |
| 通信模式 | 同步,主从或多主 | 同步,单主多从 | 异步,点对点 |
| 拓扑结构 | 总线型(多设备共享两根线) | 星型(每个从设备独立片选) | 点对点(仅两个设备) |
| 设备寻址 | 7 位或 10 位地址,软件寻址 | 硬件片选(CS 引脚) | 无寻址,直接连接 |
| 数据方向 | 半双工(分时读写) | 全双工(同时收发) | 全双工(同时收发) |
| 典型速度 | 100 kHz ~ 3.4 MHz | 10 MHz ~ 80 MHz | 9.6 kbps ~ 10 Mbps |
| 从设备数量 | 理论 127 个(7 位地址) | 受限于主控 CS 引脚数 | 仅 1 对 1 |
| 硬件复杂度 | 中等(需 I2C 控制器) | 低(GPIO 模拟即可) | 低(UART 外设常见) |
| 流控机制 | 时钟拉伸(从设备控制速率) | 无标准流控 | 硬件流控(RTS/CTS) |
| 错误检测 | ACK/NACK 应答 | 无标准错误检测 | 奇偶校验位 |
| 典型应用 | 传感器、EEPROM、RTC、ADC | 显示屏、SD 卡、ADC、Flash | GPS 模块、蓝牙模块、调试串口 |
1.4 I2C 总线协议基本时序
I2C 总线上的数据传输遵循严格的时序规范。每次传输以起始条件(START condition)开始,以停止条件(STOP condition)结束。数据在 SCL 高电平时采样,在 SCL 低电平时变化。基本时序要素包括:
- 起始条件(S):SCL 为高电平时,SDA 从高电平切换到低电平。
- 停止条件(P):SCL 为高电平时,SDA 从低电平切换到高电平。
- 数据有效性:SCL 高电平时 SDA 必须保持稳定,SCL 低电平时 SDA 允许变化。
- 字节格式:每个字节 8 位,MSB 先传,后跟一个应答位(ACK/NACK)。
- 应答(ACK):接收设备在第 9 个 SCL 周期将 SDA 拉低,表示成功接收。
- 非应答(NACK):接收设备在第 9 个 SCL 周期保持 SDA 为高,表示传输结束或错误。
clock-frequency、i2c-scl-rising-time-ns、i2c-scl-falling-time-ns 等属性。这些参数直接影响总线时序的合规性,尤其是在高速模式下,上升/下降时间不匹配会导致通信失败。