1. I2C协议基础:从一根线上看世界

大家好,我是老张。做嵌入式这些年,我调试过最多的协议就是I2C。说实话,这协议看着简单,但坑是真不少。今天咱们就从最底层开始,把I2C的物理层掰开了揉碎了讲清楚。

1.1 I2C总线的起源

I2C是飞利浦(现在的NXP)在1982年搞出来的。当时他们想解决一个很实际的问题:板子上芯片越来越多,每个芯片都要连一堆控制线,布线都快疯了。

于是他们想了个办法——只用两根线,把所有外设都挂上去。一根时钟线(SCL),一根数据线(SDA)。这就是I2C的雏形。

我个人觉得,I2C能活到现在,核心原因就两个:

  • 引脚少——就两根线,省GPIO
  • 设备多——一条总线上能挂上百个芯片

你想想看,一个MCU只有十几个GPIO,要是每个传感器都单独接,那得用多少引脚?I2C这种共享总线的思路,说白了就是「少花钱多办事」。

1.2 物理层特性:SDA和SCL

这两根线,咱们得好好聊聊。

SDA(Serial Data Line)——数据线,负责传数据。
SCL(Serial Clock Line)——时钟线,负责同步。

这里有个关键点:这两根线都是开漏输出。什么叫开漏?就是芯片只能把线拉低,不能主动拉高。拉高的工作,交给上拉电阻来做。

核心概念:I2C总线是「线与」结构。任何设备都可以拉低总线,但只有上拉电阻能拉高。谁先拉低,谁就控制了总线。

我在项目中遇到过一件事:有个同事把SDA和SCL接反了,结果怎么调都通不了。后来用逻辑分析仪一看,时钟线上全是数据,数据线上全是时钟。嗯,这种低级错误,犯过一次就记住了。

1.3 上拉电阻的选择

上拉电阻这事,看着简单,其实学问很大。

电阻选大了,信号上升沿变慢,波形像老太太爬坡——慢悠悠的。
电阻选小了,功耗变大,而且可能拉不动总线。

我一般这么选:

总线速率 推荐上拉电阻 总线电容
标准模式(100kHz) 4.7kΩ ~ 10kΩ < 200pF
快速模式(400kHz) 2.2kΩ ~ 4.7kΩ < 100pF
高速模式(3.4MHz) 1kΩ ~ 2.2kΩ < 50pF

这个表怎么用?举个例子:

  • 如果你跑100kHz,总线不长,用10kΩ没问题
  • 如果跑400kHz,总线有点长,建议用2.2kΩ
  • 如果跑3.4MHz,那得上1kΩ,而且布线要非常小心

我的经验:不确定的时候,先用4.7kΩ。然后用示波器看上升沿。如果上升沿太缓(超过时钟周期的10%),就换小一点的电阻。我一般留20%~30%的余量。

1.4 总线电容与速率的关系

这个问题,很多新手会忽略。但恰恰是它,坑了无数人。

总线电容怎么来的?

  • PCB走线本身有电容(约1pF/cm)
  • 每个芯片的引脚有输入电容(约5~10pF)
  • 连接器、过孔也会贡献电容

把这些加起来,就是总线的总电容。I2C规范里规定:

  • 标准模式:最大总线电容400pF
  • 快速模式:最大总线电容200pF
  • 高速模式:最大总线电容100pF

为什么会这样?因为电容越大,信号上升沿越慢。上升沿太慢,数据就可能采错。

我曾经在一个项目里,挂了8个传感器在一条I2C总线上。结果400kHz死活跑不通,降到100kHz就正常。后来一算,总线电容已经超过300pF了。嗯,这就是典型的「电容超标」。

避坑指南:我曾经吃过一次大亏——在一条I2C总线上挂了12个设备,结果通信时好时坏。查了两天才发现,总线电容已经超过500pF。后来分成两条总线,问题解决。

所以我的建议是:一条I2C总线,挂3~5个设备最稳妥。超过8个,最好加I2C总线缓冲器(如PCA9517)。

1.5 实际调试中的小技巧

说了这么多理论,来点实际的。

怎么判断上拉电阻是否合适?

用示波器看SCL的上升沿。如果上升沿是平滑的指数曲线,说明电阻合适。如果上升沿有台阶或者震荡,说明电阻太小或者布线有问题。

怎么判断总线电容是否超标?

看SCL的上升时间。标准模式下,上升时间不能超过1μs。快速模式下,不能超过300ns。如果超了,要么降速,要么加缓冲器。

我个人的调试流程:

  1. 先用逻辑分析仪抓波形,看有没有起始条件
  2. 看SCL频率对不对
  3. 看SDA数据有没有毛刺
  4. 看ACK信号有没有拉低
  5. 如果都不行,换示波器看上升沿

你想想看,I2C就两根线,问题出在哪?要么是时序不对,要么是电平不对,要么是地址不对。按这个思路排查,大部分问题都能解决。

好了,这一章的内容就到这。下一章咱们聊I2C的时序——起始条件、停止条件、数据有效性,这些才是真正容易出Bug的地方。