1. I2C协议基础:物理层特性、总线拓扑、开漏输出与上拉电阻

各位同学,咱们今天正式开始啃I2C协议。说实话,I2C这玩意儿看着简单,但实际调起来坑不少。我最早接触I2C是在一个温湿度传感器项目上,本以为半天搞定,结果折腾了两天才把波形调干净。嗯,咱们从最底层的物理层开始聊。

1.1 物理层特性

I2C总线只用两根线:SCL(时钟线)和SDA(数据线)。所有设备都挂在这两根线上,通过唯一地址区分。你想想看,两根线就能挂几十个设备,这在PCB布局紧张时简直是救命稻草。

参数 标准模式 快速模式 高速模式
最大时钟频率 100 kHz 400 kHz 3.4 MHz
最大总线电容 400 pF 400 pF 100 pF
最大从机数量 127(7位地址) 127 127
电压范围 3.3V / 5V 3.3V / 5V 1.8V ~ 5V

关键点:总线电容直接影响通信距离和速率。我见过有人用1米长的杜邦线跑400kHz,结果波形完全畸变。总线电容超过400pF,上升沿会变得很缓,逻辑电平判断出错。

1.2 总线拓扑结构

I2C是多主多从总线结构。什么意思?就是总线上可以有多个主机,谁先拉低总线谁就获得控制权。但实际项目中,90%的场景都是单主机——一个MCU带着一堆传感器。

我个人习惯把I2C总线画成一条主干线,所有设备并联上去。每个设备都有一个开漏输出接口,加上一个7位或10位地址。地址冲突是我踩过最多的坑——两个设备地址一样,总线直接瘫痪。

I2C 总线拓扑结构图 Rp Rp VDD (3.3V / 5V) SDA SCL 主机 (Master) MCU / 处理器 从机 1 地址 0x48 从机 2 地址 0x50 拓扑要点: • 所有设备的 SDA 和 SCL 引脚并联到总线上 • 每个从机必须有唯一地址(7位或10位) • 总线两端各接一个上拉电阻 Rp

我的经验:画PCB时,I2C走线尽量短而直,不要绕大圈。如果必须跨区域,加个总线缓冲器(如PCA9517)更稳妥。我曾经在一个四层板上把SDA走了15cm,结果400kHz死活不通,降到100kHz才勉强工作。

1.3 开漏输出

I2C为什么用开漏输出?说白了,就是为了实现线与功能。开漏输出只能拉低电平,不能主动拉高。高电平靠上拉电阻实现。这样多个设备可以同时拉低总线,谁先拉低谁就赢了。

你想想看,如果I2C用推挽输出,两个设备同时输出相反电平,那直接短路烧芯片。开漏输出完美解决了这个问题——多个设备可以安全地共享总线。

注意:开漏输出意味着I2C引脚不能输出高电平。如果你用GPIO模拟I2C,必须把引脚配置为开漏模式,或者用OD模式。我见过有人把引脚配成推挽输出,结果通信时好时坏,查了两天才发现是引脚模式错了。

1.4 上拉电阻选择

上拉电阻是I2C总线最容易被忽视的环节。电阻选大了,上升沿太缓;选小了,功耗大且可能拉不动。我一般按这个公式估算:

Rp_min = (VDD - VOL_max) / IOL_max
Rp_max = Tr / (0.8473 × Cbus)

其中:
VDD = 总线电压(如3.3V)
VOL_max = 低电平最大电压(0.4V)
IOL_max = 灌电流能力(3mA)
Tr = 最大允许上升时间(标准模式1000ns,快速模式300ns)
Cbus = 总线总电容(包括引脚电容+走线电容)
总线电压 标准模式 (100kHz) 快速模式 (400kHz)
5.0V 4.7kΩ ~ 10kΩ 1.5kΩ ~ 4.7kΩ
3.3V 4.7kΩ ~ 10kΩ 1.5kΩ ~ 4.7kΩ
1.8V 2.2kΩ ~ 4.7kΩ 1.0kΩ ~ 2.2kΩ

实战建议:如果你不确定选多大,先焊4.7kΩ。这是最通用的值,标准模式和快速模式都能用。然后用示波器看上升沿——如果上升沿超过300ns(快速模式),换小一点的电阻,比如2.2kΩ。如果波形振铃严重,换大一点的电阻。

1.5 电平转换问题

实际项目中经常遇到3.3V的MCU和5V的传感器通信。这时候需要电平转换。I2C的电平转换比SPI简单——因为开漏结构天然支持双向电平转换。

我常用的方案有两种:

  1. 分立MOS管方案:用N沟道MOS管(如BSS138)搭转换电路,成本低,适合少量信号。
  2. 专用I2C电平转换芯片:如PCA9306、TXS0102,集成度高,适合多路或高速场景。

避坑指南:我曾经在一个项目里直接用电阻分压做电平转换,结果SDA线在5V侧拉不低,因为分压后的高电平不够高。记住,I2C电平转换必须用开漏结构,不能简单分压。

1.6 本章小结

I2C物理层看似简单,但上拉电阻、总线电容、电平转换这三个点,是80%通信故障的根源。我的习惯是:

  • 先确认上拉电阻值是否合适
  • 再用示波器看SCL和SDA的上升沿
  • 最后检查电平是否匹配