I2C协议时序分析与中断处理波形故障定位实战 - 第1节

1.1 物理层特性:SDA/SCL 与上拉电阻

I2C 总线物理上就两根线:SDA(数据线)和 SCL(时钟线)。

这两根线都是开漏输出。什么叫开漏?说白了,芯片内部只能把线拉低到 GND,不能主动拉高。要拉高,全靠外部上拉电阻。

我刚开始做 I2C 时,总觉得开漏设计很麻烦。后来踩过几次坑才明白——开漏是 I2C 能支持多主设备、能实现时钟拉伸的根本原因。你想想看,如果每个设备都能主动推高电平,那多个设备同时驱动时,总线不就打架了吗?

核心要点:开漏 + 上拉电阻 = 线与逻辑。任何设备拉低总线,总线就是低电平;所有设备都释放,总线才回到高电平。

上拉电阻怎么选?

上拉电阻的取值直接影响通信质量和功耗。我一般遵循这个原则:

  • 标准模式(100 kHz):4.7 kΩ ~ 10 kΩ
  • 快速模式(400 kHz):1.5 kΩ ~ 4.7 kΩ
  • 高速模式(3.4 MHz):几百 Ω ~ 1 kΩ

电阻太小,灌电流太大,功耗高;电阻太大,上升沿变缓,信号质量差。我在一个项目中用过 100 kΩ 上拉,结果总线根本没法正常工作——上升沿慢得像蜗牛爬。

我的经验:如果总线上挂的设备多(超过 8 个),或者走线较长(超过 10 cm),适当减小上拉电阻。我习惯先按 4.7 kΩ 起步,再用示波器看上升沿,调到满意为止。

1.2 协议层概述:主从架构

I2C 是典型的主从架构。主设备产生时钟、发起通信;从设备响应地址、收发数据。

一个总线上可以挂多个主设备和多个从设备。但同一时刻,只能有一个主设备控制总线。为什么?因为总线是开漏的,多个主设备同时驱动就会产生冲突——这就是仲裁机制要解决的问题。

我记得有一次调试一个多主系统,两个主设备同时发起通信,结果数据全乱了。后来查了几天才发现,其中一个主设备的仲裁逻辑有 bug。嗯,从那以后我每次做多主设计,都会在逻辑分析仪上盯着仲裁过程看一遍。

7 位寻址 vs 10 位寻址

I2C 的地址分两种:7 位和 10 位。绝大多数器件用 7 位地址,够用。

特性 7 位寻址 10 位寻址
地址范围 0x00 ~ 0x7F(128 个) 0x000 ~ 0x3FF(1024 个)
保留地址 0x00(广播)、0x01~0x07 等 与 7 位兼容
可用地址数 约 112 个 约 1008 个
帧格式 1 字节(地址 + R/W) 2 字节(首字节 11110xx + 次字节)
常见场景 传感器、EEPROM、ADC/DAC 多路复用器、复杂 SoC

7 位地址的帧格式很简单:主设备先发一个起始条件,然后发 7 位地址 + 1 位读写标志(0 写、1 读),再等从设备的应答位。

10 位地址稍微复杂一点:首字节的前 5 位固定为 11110,后 2 位是地址的高 2 位,再加上 R/W 位;然后发第二个字节,包含地址的低 8 位。

注意:10 位地址的从设备,在应答机制上跟 7 位设备不太一样。我曾经遇到一个 10 位地址的传感器,手册上没写清楚应答时序,结果我按 7 位的逻辑去读,死活读不到数据。后来用示波器一帧一帧地抓,才发现它需要两个地址字节都应答完才能继续。

1.3 知识体系总览

下面这张图把 I2C 协议的基础框架串起来了。我建议你先看一遍,有个整体印象,再往下细抠每个模块。

I2C 协议基础 · 知识体系 物理层特性 协议层概述 寻址方式 SDA 开漏 SCL 开漏 上拉电阻选择 主设备 从设备 多主仲裁 7 位地址 10 位地址 保留地址 开漏 + 上拉电阻 → 线与逻辑 → 多设备共享总线 7 位地址够用就用 7 位,10 位地址只在设备数量超限时使用

1.4 常见误区与避坑指南

误区一:上拉电阻越大越好

我见过有人用 100 kΩ 上拉,觉得省电。结果总线上升沿超过 1 μs,400 kHz 模式下根本没法用。上拉电阻不是越大越好,要平衡功耗和信号完整性。

误区二:地址冲突只查一次就够了

同一个 I2C 总线上,两个从设备地址不能相同。但有些器件有多个可选地址引脚,焊接时容易搞错。我习惯在 PCB 打样回来后,先用 I2C 扫描程序扫一遍所有地址,确认没有冲突再开始调试。

误区三:开漏输出可以直接连 3.3V 和 5V 设备

理论上可以,但要注意上拉电阻接的电压。如果主设备是 3.3V,从设备是 5V,上拉电阻接 5V 的话,3.3V 设备可能承受不住 5V 的高电平。我一般用电平转换芯片,或者用 MOSFET 做双向电平转换。

1.5 小结

这一章我们聊了 I2C 的物理层和协议层基础。说白了,I2C 就两根线,开漏输出加上拉电阻,主从架构加 7 位或 10 位寻址。看起来简单,但每个细节都有坑。

我个人觉得,理解开漏和上拉电阻的物理原理,比死记硬背时序参数更重要。因为只有懂了底层,你才能在示波器上看出问题在哪,才能快速定位故障。