2. I2C时序分析:标准模式与快速模式参数详解
I2C的时序,说白了就是SCL时钟和SDA数据线之间怎么配合。很多工程师调不通I2C,十有八九是时序没卡好。我刚开始做嵌入式那会儿,就吃过这个亏——芯片手册上写着支持400kHz,结果板子一跑起来,从机就是不响应。后来拿示波器一抓,发现上升沿太慢了,根本达不到快速模式的要求。
这一节,咱们就把标准模式(100kHz)和快速模式(400kHz)的时序参数掰开揉碎了讲。你把这些参数记牢了,以后调I2C心里就有底了。
2.1 I2C时序的基本框架
先看一张整体时序图,把各个参数的位置搞清楚。
这张图里,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通信问题时,按这个顺序查一遍,基本能定位问题。
- 检查上拉电阻:用示波器看SCL和SDA的上升沿。如果上升沿太缓(超过300ns),换更小的上拉电阻。
- 检查总线电容:数一数总线上挂了多少个从机。每个从机引脚电容约5-10pF,加上走线电容,总电容超过100pF就要小心了。
- 检查时钟频率:用示波器量SCL的实际频率。有些MCU的I2C时钟分频器配置不对,实际频率比设定值高。
- 检查数据建立时间:在SCL上升沿附近看SDA是否稳定。如果SDA在时钟沿附近跳变,说明建立时间不够。
- 检查起始/停止条件:看SDA和SCL的切换顺序是否正确。起始条件是SCL高时SDA下降,停止条件是SCL高时SDA上升。
- 检查总线空闲时间:两个传输之间是否留够了tBUF。快速模式下至少1.3μs。
- 检查从机地址:地址是否正确?7位地址还是10位地址?从机是否支持该地址?
- 检查时钟拉伸:从机是否拉低了SCL?如果从机时钟拉伸时间过长,主机会超时。
总结一下:I2C时序的核心就三个字——快、准、稳。快是指上升下降要快,准是指建立保持时间要准,稳是指时钟和数据要稳定。把这三点记住了,I2C调试就成功了一半。