2. I2C时序分析:标准模式与快速模式参数详解

I2C的时序,说白了就是SCL时钟和SDA数据线之间怎么配合。很多工程师调不通I2C,十有八九是时序没卡好。我刚开始做嵌入式那会儿,就吃过这个亏——芯片手册上写着支持400kHz,结果板子一跑起来,从机就是不响应。后来拿示波器一抓,发现上升沿太慢了,根本达不到快速模式的要求。

这一节,咱们就把标准模式(100kHz)和快速模式(400kHz)的时序参数掰开揉碎了讲。你把这些参数记牢了,以后调I2C心里就有底了。

2.1 I2C时序的基本框架

先看一张整体时序图,把各个参数的位置搞清楚。

I2C 标准/快速模式时序参数总览 SCL SDA tHD:STA tSU:STA tLOW tHIGH tr tf tSU:DAT tHD:DAT tBUF 图例: SCL SDA 蓝色标注 = 时钟相关 红色标注 = 起始/停止 绿色标注 = 数据相关 橙色标注 = 总线空闲

这张图里,SCL是蓝色的方波,SDA是红色的数据线。各个参数用不同颜色标出来了——蓝色是时钟相关的,红色是起始/停止条件,绿色是数据建立和保持,橙色是总线空闲时间。

2.2 核心时序参数详解

I2C的时序参数,我习惯把它们分成三组来记:时钟参数、边沿参数、数据参数。咱们一个一个看。

2.2.1 时钟参数:tLOW 和 tHIGH

这两个参数决定了I2C的通信速率。

  • tLOW:SCL时钟低电平的最小持续时间
  • tHIGH:SCL时钟高电平的最小持续时间

标准模式下,tLOW和tHIGH都是4.7μs。快速模式下,tLOW是1.3μs,tHIGH是0.6μs。你算一下,一个完整时钟周期 = tLOW + tHIGH + 上升时间 + 下降时间。标准模式100kHz就是这么来的。

我的经验:很多MCU的I2C外设会自动满足tLOW和tHIGH的要求。但如果你用GPIO模拟I2C,就得自己算延时了。我一般会在tLOW里多留10%的余量,防止时钟拉伸(Clock Stretching)时出问题。

2.2.2 边沿参数:tr 和 tf

这两个参数最容易被人忽略,但恰恰是故障的高发区。

  • tr:SCL和SDA的上升时间(从30% VDD到70% VDD)
  • tf:SCL和SDA的下降时间(从70% VDD到30% VDD)

标准模式下,tr最大1000ns。快速模式下,tr最大300ns。下降时间tf在两个模式下都是最大300ns。

注意:上升时间主要由上拉电阻和总线电容决定。RC时间常数τ = Rp × Cb。如果上拉电阻太大,或者总线电容太大(比如挂了太多从机、走线太长),上升时间就会超标。我曾经在一个项目里挂了8个I2C从机,结果快速模式死活跑不起来,最后发现是总线电容太大,上升时间超过了300ns。

2.2.3 数据参数:tSU:DAT 和 tHD:DAT

这两个参数决定了数据采样的可靠性。

  • tSU:DAT:数据建立时间——SDA数据在SCL上升沿之前必须保持稳定的最小时间
  • tHD:DAT:数据保持时间——SCL上升沿之后SDA数据必须保持稳定的最小时间

标准模式下,tSU:DAT最小250ns,tHD:DAT最小0ns(实际上就是0,但建议留点余量)。快速模式下,tSU:DAT最小100ns,tHD:DAT也是0ns。

关键点:tHD:DAT虽然是0ns,但你不能真的让数据在时钟沿处跳变。我建议至少留50ns的保持时间,特别是当SCL和SDA走线长度不一致时,信号偏移会导致采样错误。

2.3 标准模式 vs 快速模式:参数对比表

我把所有参数整理成了一张表,方便你对照查阅。

参数 符号 标准模式 (100kHz) 快速模式 (400kHz) 单位
SCL时钟频率 fSCL 0 - 100 0 - 400 kHz
SCL低电平时间 tLOW 4.7 1.3 μs
SCL高电平时间 tHIGH 4.0 0.6 μs
SCL/SDA上升时间 tr 1000 300 ns
SCL/SDA下降时间 tf 300 300 ns
数据建立时间 tSU:DAT 250 100 ns
数据保持时间 tHD:DAT 0 0 ns
起始条件保持时间 tHD:STA 4.0 0.6 μs
重复起始条件建立时间 tSU:STA 4.7 0.6 μs
停止条件建立时间 tSU:STO 4.0 0.6 μs
总线空闲时间 tBUF 4.7 1.3 μs

你看,快速模式比标准模式快了4倍,但参数要求严格得多。特别是上升时间从1000ns缩到了300ns,这个变化对硬件设计影响最大。

2.4 起始条件和停止条件

这两个条件标志着一次I2C传输的开始和结束。

  • 起始条件(S):SCL为高电平时,SDA从高电平切换到低电平
  • 停止条件(P):SCL为高电平时,SDA从低电平切换到高电平

相关的参数有四个:

  • tHD:STA:起始条件保持时间——从SDA下降沿到SCL第一个下降沿
  • tSU:STA:重复起始条件建立时间——从SCL上升沿到SDA下降沿(重复起始时)
  • tSU:STO:停止条件建立时间——从SCL上升沿到SDA上升沿
  • tBUF:总线空闲时间——从停止条件到下一个起始条件

避坑指南:我曾经遇到过一个问题——从机在收到停止条件后,需要一段时间才能准备好接收下一个起始条件。如果主机连续发送两个独立的传输,中间没有留够tBUF,从机就会忽略第二个起始条件。所以,两个传输之间至少等1.3μs(快速模式)或4.7μs(标准模式)。

2.5 上拉电阻的选择与上升时间的关系

上升时间tr直接受上拉电阻影响。公式很简单:

t_r ≈ 0.847 × R_p × C_b

其中:

  • Rp:上拉电阻值(Ω)
  • Cb:总线总电容(pF),包括引脚电容、走线电容、过孔电容等

举个例子,假设总线电容Cb = 50pF,上拉电阻Rp = 4.7kΩ:

t_r = 0.847 × 4700 × 50 × 10^(-12)
    = 0.847 × 235 × 10^(-9)
    ≈ 199 ns

这个值在快速模式(300ns)以内,没问题。但如果总线电容增加到100pF,同样的上拉电阻:

t_r = 0.847 × 4700 × 100 × 10^(-12)
    = 0.847 × 470 × 10^(-9)
    ≈ 398 ns

这就超标了!所以,总线电容大了,要么换更小的上拉电阻,要么降低通信速率。

我的建议:上拉电阻的选择有个经验公式——Rp ≈ 1 / (Cb × fSCL)。对于400kHz、50pF的情况,算出来大约是50kΩ。但实际中我一般用4.7kΩ到10kΩ,因为还要考虑功耗和驱动能力。如果从机数量多,我习惯用2.2kΩ到4.7kΩ。

2.6 时序故障排查清单

最后,我把自己多年积累的时序故障排查经验整理成了一份清单。你遇到I2C通信问题时,按这个顺序查一遍,基本能定位问题。

  1. 检查上拉电阻:用示波器看SCL和SDA的上升沿。如果上升沿太缓(超过300ns),换更小的上拉电阻。
  2. 检查总线电容:数一数总线上挂了多少个从机。每个从机引脚电容约5-10pF,加上走线电容,总电容超过100pF就要小心了。
  3. 检查时钟频率:用示波器量SCL的实际频率。有些MCU的I2C时钟分频器配置不对,实际频率比设定值高。
  4. 检查数据建立时间:在SCL上升沿附近看SDA是否稳定。如果SDA在时钟沿附近跳变,说明建立时间不够。
  5. 检查起始/停止条件:看SDA和SCL的切换顺序是否正确。起始条件是SCL高时SDA下降,停止条件是SCL高时SDA上升。
  6. 检查总线空闲时间:两个传输之间是否留够了tBUF。快速模式下至少1.3μs。
  7. 检查从机地址:地址是否正确?7位地址还是10位地址?从机是否支持该地址?
  8. 检查时钟拉伸:从机是否拉低了SCL?如果从机时钟拉伸时间过长,主机会超时。

总结一下:I2C时序的核心就三个字——快、准、稳。快是指上升下降要快,准是指建立保持时间要准,稳是指时钟和数据要稳定。把这三点记住了,I2C调试就成功了一半。