2. I2C 物理层详解:总线拓扑、SDA/SCL、上拉电阻与电平标准

搞懂 I2C 通信,第一道坎就是物理层。很多人一上来就啃协议帧格式、读时序、写时序,结果板子调不通,逻辑分析仪抓出来的波形全是乱码。说白了,就是物理层没打好底。

这节我就带你仔细捋一遍 I2C 的物理层。哪些线该怎么接,电阻选多大,3.3V 和 5V 怎么混接。这些都是我早期反复踩过的坑。

2.1 I2C 总线拓扑结构:主从与多主机

I2C 总线就两根线:SDA(数据线)和 SCL(时钟线)。所有设备都挂在这两条线上。结构非常简单,你用逻辑分析仪抓出来,一看就懂。

核心特点: 这是多主从总线。理论上,任何设备都能当主机发时钟。但实际项目中,几乎都是单片机和 SoC 当主机,传感器和存储器从机。

我习惯用下面这张图来记录总线的基本组成,你拿去用。

I2C 物理层核心知识体系 I2C 物理层基础 总线拓扑 主从 / 多主机 线或逻辑 (Wired-AND) SDA / SCL 线 漏极开路 (OD) 双向传输 上拉电阻计算 Rp(min) vs Rp(max) 上升时间约束 电平标准 3.3V / 5V 电平转换 关键公式 Rp(max) = tr / (0.8473 × Cb) 常见逻辑电平 VIL / VIH 物理层配置不当 → 协议无法正常工作 每个 I2C 设计都绕不开这四块内容 上拉电阻选错,总线直接瘫痪

总线拓扑上有个关键点:所有设备的 SDA 和 SCL 都是漏极开路(Open-Drain)输出。这意味着什么?意味着没有任何设备能主动把总线拉高。只有主机或者从机主动拉低,把总线拉到 GND。总线高电平全靠上拉电阻提供。

这就是 I2C 的“线与”逻辑。任何设备拉低总线,整条线就变成低电平。冲突检测就是靠这个原理。我记得刚开始做 I2C 时,想当然地以为设备输出高电平时总线就是高电平,结果逻辑分析仪抓到的全是高阻态,查了很久才明白问题出在漏极开路上。

2.2 SDA 与 SCL 信号线详解

这两根线看着简单,但细节很多。我按重要程度给你拆开讲。

SCL:时钟线

  • 由主机产生。标准模式 100kHz,快速模式 400kHz,高速模式 3.4MHz。
  • 时钟同步和仲裁都在 SCL 上做。多主机竞争时,谁先把 SCL 拉低谁就赢得时钟控制权。

SDA:数据线

  • 双向数据线。主机发送地址和写数据,从机回复应答和发送读数据。
  • 数据传输发生在 SCL 高电平时。SCL 低电平时才能改变 SDA 电平。
  • 起始条件:SCL 高电平时,SDA 从高到低跳变。
    停止条件:SCL 高电平时,SDA 从低到高跳变。

避坑提醒:曾经我调试一块板子,单片机一直检测不到从机 ACK。花了一整天,最后发现 SDA 线上有个 1μF 的电容没去掉。电容太大,SDA 电平翻转太慢,从机根本识别不了起始条件。

SDA 和 SCL 的走线必须尽量短,负载电容加起来不能超过 400pF(标准模式)。

2.3 上拉电阻计算:很关键

这是 I2C 物理层最容易被忽视的地方。电阻选小了,总线拉低电流过大。电阻选大了,上升沿太慢,协议跑飞。

我习惯用 I2C 规范中的标准来计算。咱们一步步来。

最小上拉电阻 Rp(min)

限制因素是:设备拉低总线时的最大灌电流(Iol)。

  • Vcc:供电电压
  • Vol(max):输出低电平最大值(一般 0.4V)
  • Iol(max):灌电流(标准模式 3mA,快速模式 20mA)

公式很简单:

Rp(min) = (Vcc - Vol(max)) / Iol(max)
例如:Vcc=3.3V,Vol=0.4V,Iol=3mA
Rp(min) = (3.3-0.4) / 0.003 ≈ 967Ω

所以无论如何不能比这个值小。否则设备没能力把总线拉到 0.4V 以下。

最大上拉电阻 Rp(max)

限制因素是:总线电容(Cb)和要求的上升时间(tr)。

  • tr:SCL 上升时间(标准模式 1μs,快速模式 300ns)
  • Cb:总线总电容(走线 + 设备管脚电容)

公式:

Rp(max) = tr / (0.8473 × Cb)
例如:标准模式 tr=1μs,Cb=200pF
Rp(max) = 1μs / (0.8473 × 200pF) ≈ 5.9kΩ

你实际选电阻时,就选 Rp(min) 和 Rp(max) 之间的标准阻值。我建议选 4.7kΩ 或 10kΩ,这两个值在很多 I2C 设计里都够用。

供电电压 (Vcc) 标准模式 (100kHz) 快速模式 (400kHz)
5.0V 4.7kΩ ~ 10kΩ 2.2kΩ ~ 4.7kΩ
3.3V 3.3kΩ ~ 10kΩ 1.5kΩ ~ 4.7kΩ
1.8V 2.2kΩ ~ 10kΩ 1.0kΩ ~ 4.7kΩ

实战经验:我用逻辑分析仪测过,总线电容 50pF 的情况下,用 10kΩ 上拉电阻,标准模式完全没问题。但电容到 200pF,10kΩ 就不够快了,上升沿变成了 1.7μs,超过标准模式要求。这时候我换成了 4.7kΩ。

2.4 电平标准:3.3V 与 5V 的混接

现在大部分传感器都是 3.3V,但很多传统的 EEPROM 还跑 5V。混接时你一定要注意电平是否兼容。

标准逻辑电平阈值

  • TTL 电平(5V 系统):VIL=0.8V,VIH=2.0V
  • CMOS 电平(3.3V 系统):VIL=0.8V,VIH=2.0V(有些 3.3V 器件 VIH 要求更高,达到 0.7×Vcc)

一般来说,3.3V 器件输出的高电平是 3.3V,能被 5V 器件识别为高电平。反过来,5V 器件输出的高电平是 5V,灌进 3.3V 器件可能会烧毁。你可以用两种方式处理:

  1. 电平转换芯片:如 PCA9306。可靠性最高。
  2. 外部分压:在 SDA/SCL 线上串联电阻分压,把 5V 降成 3.3V。但不推荐,因为会拉低驱动能力。

千万注意:不能直接把 5V 设备的输出直接接到 3.3V 设备的输入引脚上。我吃过这个亏,一个 5V 的 I2C 温度传感器直接接 3.3V 单片机,结果单片机的 I/O 引脚被击穿,内部 ESD 结构烧毁。