Skip to content

LV001-I2C简介 ​

一、I2C 总线概述 ​

1. I2C 介绍 ​

I2C(Inter-Integrated Circuit,集成电路总线)是一种多主多从架构的串行通信总线,1982 年由 PHILIPS(飞利浦)公司开发,用于连接微控制器及其外围设备。它可以让主板、嵌入式系统或手机连接低速周边设备,如今在嵌入式领域非常常见。

它由数据线 SDA 和时钟线 SCL 两根信号线构成,可发送和接收数据,在 CPU 与被控 IC 之间、IC 与 IC 之间双向传送。标准 I2C 总线传输速率可达 100 kbit/s,快速模式可达 400 kbit/s。

主要用于近距离、低速的芯片之间的通信:SDA 用于收发数据、方向可变;SCL 由主机驱动,用于通信双方的时钟同步(从机只能把 SCL 拉低来延长低电平,不能自己产生时钟)。I2C 总线硬件结构简单,成本较低,因此在各个领域得到了广泛的应用。

I2C 总线连接示意图

每个接到 I2C 总线上的器件都有自己独立的地址(7 位,或 10 位扩展地址;另有部分地址段保留给特殊用途),主机与其他器件进行数据传输时,总线上发送数据的器件称为发送器,接收数据的器件称为接收器。

2. 典型应用场景 ​

I2C 主要用于近距离、低速的"配置与状态"类通信,常见场景及其所用速率大致如下(传输模式一览见本章第 4 节):

(1)传感器:温湿度(SHT3x、AHT20)、加速度计与陀螺仪(MPU6050)、气压(BMP280)、光照(BH1750)等。数据量小、采样率不高,标准模式 100 kbit/s 到快速模式 400 kbit/s 都很常见;

(2)存储与时钟:EEPROM(如本系列的 AT24C02)、RTC 实时时钟(DS3231)等。以字节为单位随机读写,100 kbit/s 就够用,多数器件也支持 400 kbit/s;

(3)配置通道:音频 codec、摄像头图像传感器的寄存器配置,PMIC 电源管理芯片,IO 扩展器(PCF8574)等。这类芯片的数据本身走高速接口(I2S、MIPI 等),I2C 只负责"调参数、读状态",100/400 kbit/s 足矣;

(4)人机交互:小尺寸 OLED(SSD1306)、触摸屏控制器(GT911)等。数据量相对大一些,一般跑快速模式 400 kbit/s。

至于 1 Mbit/s 的快速模式+和更高速的高速模式,实际支持程度不如 100/400 kbit/s 普遍,绝大多数 I2C 系统仍使用标准模式或快速模式。

3. 模拟 I2C 与硬件 I2C ​

因为I2C协议比较简单,常常用GPIO来模拟I2C时序,这种方法称为模拟I2C。如果使用MCU的I2C控制器,设置好I2C控制器,I2C控制器就自动实现协议时序,这种方式称为硬件I2C。两者本质区别只有一句话:硬件 I2C 把协议时序交给片上外设自动产生,CPU 只管发指令、收数据;软件模拟 I2C 让 CPU 用 GPIO 亲自翻转每一根线,由此派生出下面全部优缺点。

3.1 两种方式对比 ​

维度硬件 I2C软件模拟 I2C
时序产生外设自动完成起始、应答、移位,CCR 精确设定 SCL代码 + delay_us 逐位翻转,节奏全靠 CPU
时序可靠性精确稳定,不受中断延迟影响中断打断会拉长时序,延时依赖系统时钟,需留裕量
CPU 占用低:触发后可中断 / DMA 搬数据,传输期间能干别的高:全程忙等,一位一位陪跑
引脚只能在芯片指定或复用的 GPIO 中选择(如 I2C1 可映射到不同引脚组)任意 GPIO,布板最灵活
数量受外设个数限制(如 STM32F103ZET6 有 2 个)想要几路有几路
从模式 / DMA / 时钟拉伸通常由外设支持从模式、多主仲裁和时钟拉伸需自行实现且复杂,DMA 通常不便使用
移植性绑定芯片和库(HAL / 寄存器)改两个宏就能换平台
调试状态藏在寄存器标志位里(EV5/EV6…)时序就写在代码里,配合逻辑分析仪一目了然
速率外设支持时可到 400 kbit/s、1 Mbit/s,适合大块数据低速场景常用;能否达到 400 kbit/s 取决于 CPU 主频、代码和延时开销
典型坑STM32F1 硬件 I2C 的 errata:BUSY 标志卡死需复位外设GPIO 误配成推挽会破坏线与、烧总线

两种方式在本系列里都有实例:模拟路线见 LV010-I2C时序与软件模拟 的 GPIO 宏与位操作代码,硬件路线见外设篇 LV001-STM32的I2C 的外设框图与 HAL 库函数。

3.2 怎么选择 ​

(1)默认倾向硬件 I2C:引脚允许、外设空闲,尤其数据量大、接近器件速率上限、想用 DMA 的场景——把 CPU 空出来才是硬道理;

(2)这些情况选模拟 I2C:目标引脚被占用、外设不够用、跨平台移植优先,或者只是低速小块数据(读个温度、配几个寄存器)——几十行代码透明可控;

(3)调试期技巧:拿逻辑分析仪抓波形时,模拟 I2C 的"代码 ↔ 波形"对应关系直观得多,定位协议问题更快;

(4)工程常态:能用硬件就用硬件,踩到 errata(如 F1 的 BUSY 卡死)或引脚不合适再退模拟;也有不少产品干脆全程模拟求稳——低速场景下两者的可靠性差距,远小于学习成本差距;

(5)系统形态:跑 RTOS 的系统倾向硬件 + 中断/DMA,裸机低速外设倾向模拟。

4. 总线特点 ​

(1)I2C 总线是一种多主机总线,连接在 I2C 总线上的器件分为主机和从机两种,主机有权发起和结束一次通信,而从机只能被主机呼叫;当总线上有多个主机同时启用总线时, I2C 也具备冲突检测和仲裁的功能来决定由哪个设备占用总线,防止错误产生。

(2)总线上可以挂接多个主器件,它们甚至可以同时发起传输,但一次传输只能由赢得仲裁的主器件控制;普通从机则只能被寻址。增减器件时必须检查地址冲突、总线电容、上拉阻值以及器件掉电时的引脚状态,不能认为一定不会影响其他器件。器件地址、发送器与接收器的概念见本章第 1 节。

(3)总线通过上拉电阻接到电源。当 I2C 设备空闲时,会输出高阻态, 而当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平(详见第二章)。

(4)常见几种传输模式:标准模式(Standard)100 kbit/s、快速模式(Fast)400 kbit/s、快速模式+(Fast-mode Plus)1 Mbit/s、高速模式(High-speed)3.4 Mbit/s,另有单向的 Ultra Fast 模式 5 Mbit/s。

连接到相同总线的 IC 数量主要受总线电容限制:标准模式和快速模式的最大总线电容为 400 pF,快速模式+为 550 pF;具体设计还需满足所连器件和布线的要求。

二、上拉电阻 ​

1. 为什么需要上拉电阻? ​

I2C 上拉电阻接法

我们见到的 I2C 总线都是要连接上拉电阻的,为什么?简单来说,核心原因在于:I2C 的 SDA 和 SCL 引脚都是“开漏输出”(Open-Drain)或“开集输出”(Open-Collector)。它们只能把总线拉成低电平,不能主动输出高电平。至于引脚为什么必须做成开漏——答案在第三章:应答、多主仲裁、时钟拉伸全都依赖“只能拉低”的线与结构,第 5 节还有一个“换成推挽会怎样”的反面推演,第 7 节给出完整结论。

  • 什么是“开漏输出”?

可以把一个开漏输出的内部结构想象成一个简单的开关(实际上是一个MOSFET)串联一个到地的端口。当芯片想输出逻辑‘0’(低电平)时,它就闭合这个开关,将输出线直接连接到GND(地)。这时,线路被强行拉低到0V左右,形成一个明确的低电平。当芯片想输出逻辑‘1’(高电平)时,它就断开这个开关。这时,输出线与GND断开,处于高阻抗状态(可以理解为“悬空”或“浮空”)。它自己没有能力把输出线拉到高电平。

  • 问题来了:如何产生高电平?

既然芯片在输出‘1’时是“悬空”的,那么这条线路上就没有确定的电压,极易受到外界干扰,根本无法传递可靠的‘1’信号。为了解决这个问题,我们就需要外部的帮助。这个“外部的帮助”就是上拉电阻。

我们在输出线(SDA和SCL)与电源电压(VCC)之间各接一个电阻。当所有连接到总线上的芯片都断开它们的开关(即都想输出‘1’)时,这个上拉电阻会把线路的电压拉向VCC,从而在总线上产生一个确定的高电平。

当任何一个芯片闭合它的开关(想输出‘0’)时,其开漏输出级会导通,形成一个对地的低阻抗路径。该路径会从电源 VCC 通过上拉电阻 Rp 吸纳电流(即灌电流),从而在 Rp 上产生压降,将总线电压钳位至逻辑低电平。这一过程确保了在存在上拉的情况下,总线仍能被可靠地驱动至有效的低电平状态。另外虽然电流会从VCC通过电阻流到GND,但由于电阻的存在,电流不会无限大,从而保护了电路。

把I2C总线想象成一根弹簧门(比如超市的入口门)。

  • 开漏输出就像是一个人,他只能推门(把门关上,对应输出低电平),但不能拉门(把门打开)。
  • 上拉电阻就像是门上自带的一根弹簧,总是试图把门拉开(对应拉到高电平)。
  • 当没有人推门时,弹簧会把门保持在全开的状态(高电平)。
  • 当有人想关门时,他只需要推门,克服弹簧的拉力,就能把门关上(低电平)。

2. 一般多大? ​

上拉电阻的阻值没有一个绝对固定的值,它需要在一个范围内进行权衡选择。典型值通常在 1kΩ 到 10kΩ 之间,常见的是 4.7kΩ。

2.1 选择依据是什么? ​

电阻值的选择主要是在速度和功耗之间取得平衡,并受总线电容的影响。

  • 1. 电阻不能太小(有下限)

原因:功耗。 当总线为低电平时,会形成一个从VCC通过上拉电阻到GND的电流通路。根据欧姆定律 I = VCC / Rp,电阻越小,电流越大。例如,在5V系统中使用1kΩ电阻,低电平时电流为 5V / 1000Ω = 5mA。如果总线长时间保持低电平,这个功耗是不可忽视的。对于电池供电设备,这尤其重要。此外,过大的电流也可能超过芯片输出级的最大灌电流能力。

结论: 电阻不能太小,否则功耗大,可能损坏芯片。

  • 2. 电阻不能太大(有上限)

原因:速度。 总线不是理想的,它存在对地的寄生电容(来自导线、芯片引脚等)。这个电容(Cb)和上拉电阻(Rp)构成了一个RC低通滤波电路。当信号从低电平变为高电平时,VCC通过Rp给Cb充电。充电的速度由时间常数 τ = Rp * Cb 决定。Rp越大,充电越慢,信号上升沿就越平缓。如果上升沿太慢,可能会超过I2C协议规定的时间,导致信号在时钟沿到来时还未达到稳定的高电平,从而引发通信错误。

结论: 电阻不能太大,否则会限制总线的最高通信速度。

2.2 如何选择合适的值? ​

  • 参考数据手册: 首先查看使用的MCU或器件的数据手册,它通常会给出一个建议范围。

  • 考虑总线电容: 估算总线的寄生电容。线路越长、连接的设备越多,电容就越大(通常估计在 100~400 pF 之间)。

  • 根据速度需求:

(1)标准模式(100 kbit/s):对电阻要求宽松,4.7 kΩ 或 10 kΩ 非常常见。

(2)快速模式(400 kbit/s):需要更小的电阻来保证边沿速度,常用 2.2 kΩ 或 4.7 kΩ。

(3)快速模式+(1 Mbit/s):需要较小的上拉电阻,具体阻值应按电源电压、器件灌电流能力、总线电容和最大上升时间计算,不能一概取 1 kΩ;其最大总线电容为 550 pF。

(4)高速模式(3.4 Mbit/s):Hs 模式控制器的 SCLH 输出级包含电流源上拉(主动上拉),用于缩短时钟上升时间;外部上拉电阻仍可保留,较大总线电容下可改用外部电流源。芯片端的串联电阻是可选的保护与抑振措施,并非规范强制要求。

3. 有什么好处? ​

  • “线与”功能: 所有设备都是开漏输出并共享上拉电阻,因此只要任何一个设备输出低电平(‘0’),整条总线就是低电平;只有所有设备都释放总线(高阻)时,上拉电阻才把总线拉成高电平。这在硬件上实现了一个“与”逻辑,是多主机仲裁和时钟同步的基础,详见第三章。

  • 防止总线冲突: 如果两个主机同时发送数据,一个发‘0’,一个发‘1’,发‘0’的设备会成功地将总线拉低,而发‘1’的设备在检测到总线状态与自己预期不符时,会知道发生了冲突并退出。如果没有这个“线与”特性,一个设备输出高电平,另一个输出低电平,将会形成电源到地的短路,烧毁芯片——推挽总线还会让应答、仲裁、时钟拉伸逐个失效,完整的反面分析见第三章第 5 节。

  • 兼容不同电压的设备: 总线上的高电平由上拉电阻所接的电源决定,与各器件自身的供电电压无关;又因为开漏输出只拉低、不推高,不同电压的器件在满足条件时可以挂在同一条总线上,不会互相顶牛。除了要求每个器件的 SDA/SCL 引脚都能耐受上拉电压,还要确认各器件的 VIH/VIL 与总线电平兼容,并检查器件掉电时是否会拖住总线。例如 5 V 上拉时,3.3 V 器件必须使用 5 V 容忍引脚;若改用 3.3 V 上拉,也要确认 5 V 器件能把 3.3 V 识别为高电平。条件不满足时应使用合适的电平转换器。

三、线与(wired-AND)原理详解 ​

1. 什么是线与 ​

把多个开漏输出直接并在同一根信号线上,只要有一个输出导通(拉低),整根线就是低电平;只有所有输出都截止(高阻),上拉电阻才把线拉成高电平。写成布尔式就是:

text
SDA = A · B · C = A AND B AND C

也就是说,总线上的电平是各设备输出的逻辑与,这就是“线与”。若换个角度、按低电平有效来看,它又等效于“线或”(任一为低即低)——两种说法描述的是同一个物理现象。

2. 电路上怎么实现 ​

I2C 线与原理图

图中三个器件(主机、从机 1、从机 2)的开漏输出级分别用三个对地开关表示,它们并联在同一根 SDA 上,再经上拉电阻 Rp 接到 VDD。任何一个开关闭合,SDA 就被拉到地;全部断开时,SDA 由 Rp 拉高。对这个电路逐状态过一遍:

  • 全部截止:总线上没有对地通路,Rp 把 SDA 拉到 VDD,总线为 1,此时即空闲态。

  • 任一导通:VDD → Rp → 导通的 MOS → GND 形成通路。MOS 导通电阻只有几十欧,而 Rp 是 kΩ 级,两者分压后总线被钳位到 V_OL(通常 < 0.4 V),读作 0。以 VDD = 3.3 V、Rp = 4.7 kΩ、导通电阻 50 Ω 估算:V_OL ≈ 3.3 V × 50 Ω / (4700 Ω + 50 Ω) ≈ 35 mV,低电平期间电流约 0.7 mA。

  • 其余设备仍发 1:它们处于高阻,既不拉高也不拉低,对总线电平没有影响——所以“想发 1 的设备”永远是让步的一方。

3. 为什么这根线“打不起来” ​

如果是推挽输出的两条线并联,一个输出高、一个输出低,就会形成 VDD → 上管 MOS → 下管 MOS → GND 的低阻通路,产生很大的直通电流,可能损坏 IO。开漏输出只有“拉低”这一条通路,且这条通路始终串着 Rp,因此不会因一方推高、另一方拉低而形成这种直通;但仍须选择合适的 Rp,避免低电平灌电流超过器件能力。

GPIO 模拟 I2C 连接图:开漏从机与误配推挽的主机

(1)先认角色:谁在总线上,引脚里是什么。 上图画的正是 GPIO 模拟 I2C 的场景:左侧的 STM32 作主机,用 PB6、PB7 两个 GPIO 分别接 SCL、SDA——这是 I2C1 的习惯引脚,模拟 I2C 时任选两个 GPIO 也完全可以;中间的 AT24C02 与 MPU6050 作从机。这类专用 I2C 器件的引脚结构出厂就定死了:每个引脚内部是一只开漏 NMOS(栅极由 DATA/CLK OUT 驱动)加一个输入缓冲器(DATA/CLK IN 把线上电平读回芯片)——输出 1 时 NMOS 截止、引脚交给 Rp 拉高,输出 0 时导通拉低,想配成推挽也没有那个电路。STM32 的硬件 I2C 外设同样是开漏。所以整条总线上可能出现推挽的地方只有一处——主机的 GPIO 配置,而这完全取决于你写的初始化代码。

(2)误配推挽时,红色路径是怎么走起来的。 假设写代码时把 PB7 配成了推挽输出(GPIO_MODE_OUTPUT_PP),且此刻正在输出 1:PMOS 导通把引脚接到 VDD,NMOS 截止。偏偏这一刻 AT24C02 在回 ACK,它 SDA 上的 NMOS 经 DATA OUT 驱动而导通接地。两条路一接通,红色路径就形成了:VDD → STM32 的 PMOS → PB7 → SDA → AT24C02 的 NMOS → GND,全程绕开 Rp。对比一下同一回路的两种电流:正常开漏下拉低时,电流被 Rp 限制在 0.7 mA 左右(第 2 节算过);而红色路径里只剩两只 MOS 几十欧的导通内阻,电流可达数百 mA,远超引脚的承受能力——IO 就是这么烧掉的。与此同时,总线电平被“推高”与“拉低”对抗着钳在中间,既不是有效 0 也不是有效 1,通信也随之出错。

(3)改配开漏,问题从根源上消失。 同样是 PB7,配置成开漏(GPIO_MODE_OUTPUT_OD)后,内部只剩一只对地 NMOS,PMOS 上管连同它到 VDD 的连线整个不存在——不是“被关断”,是电路里根本没有这个管子。主机输出 1 = NMOS 截止 = 松手,电平交给 Rp 决定;输出 0 = NMOS 导通,电流走 VDD → Rp → NMOS → GND,全程串着 Rp、限制在 mA 级。无论输出 0 还是 1,VDD 到地都不存在不经过 Rp 的通路,红色路径自然无从谈起。

(4)右侧的虚线框是对照,不是第二个主机。 它画的是同一个 PB7 引脚的另一种配置:打叉的 PMOS 表示开漏模式下这只管子根本不存在,框内也刻意没画任何接 VDD 的线。左右对照着看——左边多出来的那只 PMOS(连同它到 VDD 的连线)正是全部危险的来源;开漏把它整个拿掉,“这根线打不起来”就从一句口号变成了电路事实。

4. I2C 中三处依赖线与的机制 ​

  • 多主仲裁(SDA):主机每发一位都回读 SDA。两个主机同时发送,一个发 1、一个发 0,总线被拉成 0;发 1 的那个采样到自己发出的位与总线不符,立即关闭自己的输出级、退出竞争,转去监听——因为退出的正是“发 1”的一方,总线上的数据不会被打断,信息不丢失。

  • 时钟同步(SCL):主机把 SCL 拉高后,只要还有从机(或另一主机)继续把它拉低,SCL 就保持低;只有所有器件都释放,SCL 才真正升高。于是低电平的持续时间由“最慢的那个”决定,这就是时钟同步,也常被用作从机的时钟拉伸(clock stretching)。

  • 应答:ACK 位期间由接收器拉低 SDA,发送器在第 9 个时钟高电平期间读取总线电平,即可判断接收器返回的是 ACK 还是 NACK。

5. 反过来想:如果总线是推挽的会怎样? ​

前面说的都是“有线与”的世界;反过来假设总线上出现推挽输出——现实中这正是 GPIO 模拟 I2C 时把引脚误配成推挽的场景(见第 3 节的图),协议的每个关键动作都会出问题:

  • 应答立即失效:主机发完 8 位后要让出 SDA 等从机应答,但推挽没有“让出”这个状态——主机继续推高,从机拉低应答,一个推高一个拉低,两个输出级形成 VDD 到 GND 的直通电流,轻则电平错乱,重则烧毁 IO;

  • 多主仲裁失效:仲裁靠“发 1 的一方检测到总线为 0 就退出”。推挽下两个主机一个推高一个拉低,谁都“看不到”总线变成对方的电平,只会互相短路,竞争无法收敛;

  • 时钟拉伸失效:从机拉低 SCL 想拖慢主机,主机却在推挽推高 SCL——又是直通短路,从机根本拉不住时钟;

  • 双向切换如履薄冰:SDA 一会儿主机驱动、一会儿从机驱动,推挽下每次换向都必须严格保证“上一个驱动者完全停止、下一个才能开始”,时序稍有重叠就短路;开漏下“松手”即高阻,交接天然无缝;

  • 挂的器件越多越危险:推挽并联的器件越多,出现输出对抗的机会越大,而对抗可能损伤硬件;开漏结构避免了这种推高与拉低的直通冲突,但器件增多会加大总线电容,且任一器件异常拉低都可能使总线无法通信。

五个动作没有一个能在推挽总线上活下去——这不是实现细节的取舍,而是协议需求对电气结构的硬性约束。那为什么“开漏 + 上拉”是唯一的解?下一节正面回答。

6. 使用前提与常见坑 ​

  • 挂在总线上的器件必须都是开漏/开集输出。若混入推挽输出(或某个 GPIO 被误配成推挽),随时可能短路,务必先确认引脚模式。

  • 线与的高电平完全依赖 Rp,而 Rp 与总线电容 Cb 构成 RC 充电路径:线与越多、线越长,Cb 越大,上升沿越慢,最高速率就越低。

  • 上拉所接的电源决定总线高电平,跨电压器件时须满足耐受要求(见 2.3 节最后一条)。

  • 某个器件掉电或复位时若引脚呈低阻,会把整条总线拽死,这是 I2C“总线死锁”的常见原因,必要时加总线缓冲器或 I2C 隔离/多路复用器件。

7. 为什么电气上要求开漏? ​

直接回答:因为 I2C 的立身之本是多器件共享一根双向线,而应答、多主仲裁、时钟拉伸(第 4 节)都依赖“任一器件拉低即为低、全部放手才为高”的线与特性;换成推挽输出,这些动作会逐个失效(第 5 节)。满足这一切的电气结构几乎只有“开漏输出 + 上拉电阻”一种低成本方案——规范因此把“总线必须为开漏/开集”写进电气层,第二章讲的“为什么需要上拉”正是这个结构的另外一半。

把整条因果链摆在一起:

(1)需求:多器件共享一根双向线,且协议要求应答、仲裁、时钟拉伸;

(2)机制:这三个动作都依赖线与特性(见第 4 节);

(3)反面验证:推挽输出下它们逐个失效(见第 5 节);

(4)结论:开漏 + 上拉是近乎唯一的低成本解。规范里唯一的例外恰好反证了这一点——Ultra Fast 模式(5 Mbit/s)改用推挽,代价是放弃多主、应答与共享双向(单向传输、收发分离)。

一句话总结本章:线与 = 开漏输出 + 上拉电阻 + 逻辑与,它用一根线同时完成了“共享总线”“总线仲裁”“时钟同步”三件事——这正是 I2C 只用两根线就能挂几十个器件还不冲突的根本原因。

四、通信速率 ​

本章把两个与速率有关的问题放在一起说:速率本身意味着什么,以及“速率高”是不是等于“读得勤”。

1. 速率意味着什么? ​

(1)先换算成吞吐量。 SCL 上的每个时钟对应 1 位数据,100 kbit/s 的字面含义就是每秒最多传 10 万个位。而传 1 个字节实际要占 9 个时钟(8 位数据 + 1 位应答),再算上起始信号、地址字节、停止信号这些固定开销,有效数据吞吐率大约只有速率的 1/10:100 kbit/s ≈ 10 KB/s,400 kbit/s ≈ 40 KB/s。作为对比,UART 常见的 115200 baud 约合 11 KB/s,而 SPI 轻松跑到几十 Mbit/s(每秒几 MB)——I2C 是标准的“低速接口”。

(2)决定了它适合什么。 10~40 KB/s 的吞吐量,适合“低频次、小块数据”:读几个字节的传感器数据、写几页配置。例如 AT24C02 整片只有 256 字节,400 kbit/s 下不到 10 ms 就能读完全片,绰绰有余。反过来,摄像头帧数据、屏幕整帧刷新、音频流这类持续大流量,I2C 就扛不住了——所以很多复杂芯片“两条腿走路”:I2C 做控制通道,高速接口做数据通道。

(3)速率本身受物理约束。 SCL 的高电平靠上拉电阻给总线电容充电,频率越高要求边沿越陡,上拉电阻就得越小;电阻小了,低电平时的电流和功耗又变大——速率、功耗、总线长度三者互相牵制(详见第二章)。I2C 规范因此还限制总线电容不超过 400 pF:线越长、挂的器件越多,能跑的速率上限就越低。此外主机要“就低不就高”:总线上所有器件都支持的模式才能用,挂上一个只支持 100 kbit/s 的老器件,整条总线就得降到 100 kbit/s。

2. 读取数据频率:速率不等于频率 ​

速率回答的是“每秒能搬多少位”,而“每秒能读到几次新数据”还要看器件的生产速度。这一节把两个概念分开,这也是选用 I2C 速率前最该想清楚的问题。

2.1 一次读取要多久? ​

以随机读 2 字节为例,把一次完整事务拆开数一数时钟:

一次 I2C 随机读事务的时钟分解

(1)固定开销约 30 个时钟:起始信号、设备地址字节(9)、寄存器地址字节(9)、重复起始信号、设备地址字节(9)、停止信号——无论读多少字节都要付一次;

(2)数据阶段每个字节 9 个时钟(8 位数据 + 1 位应答),读 N 字节就是 9N;

(3)合计约 30 + 9N 个时钟。1 个时钟多长?就是速率的倒数——I2C 每个 SCL 时钟对应 1 位,位率与时钟频率是同一个数:100 kbit/s 时 1 个时钟 = 1/100 kHz = 10 µs,400 kbit/s 时 = 2.5 µs。代进来:读 2 字节的 48 个时钟,100 kbit/s 下 = 48 × 10 µs ≈ 0.48 ms(每秒约 2000 次),400 kbit/s 下 = 48 × 2.5 µs = 0.12 ms(每秒约 8000 次)。速率越高,单次事务越快,每秒能完成的读取次数上限越高。

2.2 生产与搬运:两个速率 ​

  • 生产速率:传感器按自己的节拍产出新数据,即输出数据率(ODR,Output Data Rate),由内部 ADC 与转换时间决定,与 I2C 总线无关;

  • 搬运速率:由“单次事务耗时”决定每秒能搬走多少次,才是总线速率管的事;

  • 不丢样时可持续获取新数据的频率上限 ≈ min(ODR,总线事务率),判断流程如下:

读取频率的瓶颈判断流程

2.3 两种典型情形 ​

(1)ODR 远低于事务率(最常见):BMP280 的转换时间取决于过采样等配置;若某配置下一次转换约 26 ms(约 38 Hz),而 100 kbit/s 每秒可以读约 2000 次,那么总线快慢就不影响新数据的产出速度,单纯提速没有收益;

(2)ODR 高于事务率:MPU6050 以 1 kHz ODR 连读加速度 + 陀螺仪共 14 字节,事务约 156 个时钟,100 kbit/s 下每秒只有约 640 次,跟不上 1 kHz 的产出。如果要求逐样本不丢失,就会因读取不及时而丢样,启用 FIFO 时还可能溢出;若只关心最新值,则未必构成问题。此时把速率提到 400 kbit/s(每秒约 2600 次)即可满足逐样本读取的带宽需求。

【注意】速率上限取 min(主机能力,器件能力):传感器手册会标注支持的最高模式,很多只到 400 kbit/s,主机不能单方面跑更快。

2.4 FIFO:按平均带宽算 ​

不少高速传感器内置 FIFO:样本先攒在片内,主机周期性突发读走一批。此时不再要求“单次事务率 ≥ ODR”,只要求平均带宽够用:

(1)平均带宽 ≥ ODR × 每样本字节数,例如 1 kHz ODR、每样本 6 字节,只需 6 KB/s,400 kbit/s(约 40 KB/s)轻松覆盖;

(2)攒够一批再突发读,还能摊薄每次事务约 30 个时钟的固定开销。


到这里,I2C 的基本概念、电气特性与速率问题都介绍完了。一次传输的完整流程——起始、应答、数据有效性等信号的定义,每个信号的软件模拟实现,以及读写时序,见 60-通信专题/01-I2C协议/LV010-I2C时序与软件模拟.md。