一、I2C协议概述:从历史到物理层

各位同学,咱们今天正式开讲I2C。这个协议在嵌入式世界里太常见了——传感器、EEPROM、ADC、触摸屏,几乎每个板子上都能找到它的影子。我最早接触I2C是在做一款工业采集卡的时候,当时被一根线上挂8个从机折腾得够呛。从那以后,我对这个协议就多了几分敬畏。

1.1 I2C总线历史:飞利浦的“小发明”

I2C全称是Inter-Integrated Circuit,字面意思就是“集成电路之间的总线”。1982年,飞利浦半导体(现在的NXP)为了简化电视机的内部通信,搞出了这个东西。你想想看,那时候的电路板走线密密麻麻,能省两根线都是天大的好事。

发展历程其实很简单:

  • 1982年:飞利浦推出I2C总线,最初只用在自家产品里
  • 1992年:发布第一版标准化规范,支持100kHz标准模式
  • 1998年:加入400kHz快速模式
  • 2007年:NXP推出1MHz快速模式+(Fm+)
  • 2012年:高速模式达到3.4MHz,超快速模式达到5MHz

我个人习惯把I2C比作“串行通信里的瑞士军刀”——功能多、体积小、够用。虽然现在SPI、UART各有拥趸,但I2C在低引脚数、多从机场景下依然无可替代。

核心认知:I2C不是最快的,也不是最远的,但它是最“省线”的。两根线搞定所有通信,这在板级设计中是巨大的优势。

1.2 物理层特性:SDA和SCL的故事

I2C总线只有两根线:

  • SDA(Serial Data Line):数据线,双向传输
  • SCL(Serial Clock Line):时钟线,由主机驱动

这两根线都是开漏输出结构。什么叫开漏?说白了,就是芯片只能把线拉低,不能主动拉高。拉高的工作交给外部的上拉电阻完成。

为什么这么设计?我举个例子你就明白了。假设总线上挂了3个设备,如果每个设备都能主动拉高,那一个设备输出高、另一个输出低,直接就短路了。开漏结构配合“线与”逻辑,任何设备拉低总线,整条线就是低电平——这才是多主机通信的基础。

避坑指南:我曾经在一个项目里把SDA和SCL接反了,结果调了两天才发现。嗯,别笑,很多人犯过这个错。上电前用万用表量一下,确认SDA接SDA、SCL接SCL,这是最基本的检查。

1.3 电气特性与上拉电阻:选对阻值很重要

上拉电阻是I2C总线里最容易忽视、也最容易出问题的地方。阻值选大了,信号上升沿变缓,通信容易出错;选小了,功耗增加,驱动能力可能不够。

标准I2C规范里,上拉电阻的推荐值如下:

模式 最大频率 推荐上拉电阻(5V) 推荐上拉电阻(3.3V)
标准模式(Sm) 100 kHz 4.7 kΩ 4.7 kΩ
快速模式(Fm) 400 kHz 2.2 kΩ 1.8 kΩ
快速模式+(Fm+) 1 MHz 1.0 kΩ 680 Ω
高速模式(Hs) 3.4 MHz 200 Ω 200 Ω

实际选型时,我一般按这个公式估算:

R_min = Vcc / I_ol_max
R_max = t_r / (0.8473 × C_bus)

其中:

  • Vcc:总线电压
  • I_ol_max:器件最大灌电流(通常3-20 mA)
  • t_r:允许的最大上升时间(标准模式1000 ns,快速模式300 ns)
  • C_bus:总线总电容(包括引脚、走线、过孔)

重要提醒:总线电容是上拉电阻选型的最大变量。每增加一个从设备,总线电容大约增加5-10 pF。如果总线上挂了8个从机,再加上PCB走线,电容很容易超过100 pF。这时候还用4.7 kΩ上拉,上升沿会变得很慢,通信必然失败。

我做过一个项目,板子上挂了6个传感器,总线上拉用了10 kΩ。结果400kHz模式下数据经常出错,用示波器一看,SCL的上升沿都快赶上半个时钟周期了。换成2.2 kΩ后,问题立刻解决。所以,上拉电阻不是随便焊一个就能用的。

1.4 电气参数速查表

下面这几个参数,做驱动开发时经常要用到:

参数 标准模式 快速模式 说明
SCL时钟频率 100 kHz 400 kHz 主机控制
SCL低电平时间 ≥ 4.7 μs ≥ 1.3 μs 时钟低电平保持
SCL高电平时间 ≥ 4.0 μs ≥ 0.6 μs 时钟高电平保持
数据建立时间 ≥ 250 ns ≥ 100 ns SDA在SCL上升沿前稳定
数据保持时间 ≥ 0 ns ≥ 0 ns SDA在SCL下降沿后保持
总线电容 ≤ 400 pF ≤ 400 pF 包括所有负载

这些时序参数在写驱动时,尤其是做软件模拟I2C时,必须严格遵守。我见过有人用GPIO模拟I2C,延时随便写个几微秒,结果某些器件就是死活不响应——时序不对,协议层再对也没用。

1.5 I2C总线结构图

下面这张图展示了I2C总线的典型结构。主机和多个从机通过SDA和SCL连接,每个从机有唯一的地址。上拉电阻挂在总线上,保证空闲时总线为高电平。

I2C总线结构图 I2C总线典型结构 Rₚ Rₚ VCC VCC SDA SCL 主机 Master 从机1 地址: 0x50 从机2 地址: 0x51 说明: • SDA和SCL均为开漏输出,需外接上拉电阻 • 所有从机共享同一总线,通过地址区分 • 总线空闲时,SDA和SCL均为高电平

这张图里,主机负责产生时钟、发起通信;从机监听地址、响应数据。上拉电阻Rₚ挂在VCC和总线之间,保证空闲时总线电平为高。每个从机都有唯一地址,主机通过地址来选择要通信的对象。

个人经验:画PCB时,SDA和SCL走线尽量等长、平行,远离时钟信号和电源开关管脚。我吃过一次亏——I2C走线紧挨着一路DC-DC的电感,结果通信时断时续,查了三天才发现是电磁干扰。后来加了一根地线隔离,世界清净了。

1.6 本章小结

这一章我们聊了I2C的来龙去脉、物理层原理和电气参数。记住几个关键点:

  • I2C是两根线的串行总线,SDA传数据,SCL传时钟
  • 开漏输出 + 上拉电阻是I2C的核心结构
  • 上拉电阻选型要看总线电容和工作频率
  • 时序参数是驱动开发的硬约束,不能马虎