2. I2C时序参数详解:五个关键数字

做I2C调试,说白了就是在跟几个时间参数较劲。SCL时钟频率、高电平持续时间、低电平持续时间、上升时间、下降时间——这五个数字一旦没对齐,传感器就跟你“装死”。我每次拿到一块新板子,第一件事就是把这五个参数从数据手册里翻出来,写到白板上。

为什么?因为它们是I2C通信的骨架。你想想看,主设备发一个时钟脉冲,从设备得在这个脉冲的高电平期间把数据准备好,在低电平期间采样。任何一个时间不够,数据就歪了。

下面我把这五个参数一个一个拆开讲。每个参数我都会给出标准值、常见陷阱,还有我自己的血泪教训。

2.1 SCL时钟频率——通信的“心跳”

SCL时钟频率就是I2C总线上一秒钟产生多少个时钟脉冲。标准模式100kHz,快速模式400kHz,高速模式3.4MHz。不过绝大多数温度传感器都用100kHz或400kHz。

我个人习惯是先看从设备数据手册里标的最大频率。比如某款常见的温度传感器,手册写“SCL frequency up to 400kHz”,那你就不能跑500kHz。跑快了数据会错乱,而且不是立刻出错——可能是跑半小时才丢一个字节,这种问题最要命。

我曾经在一个量产项目上,为了省几十微秒的读取时间,把SCL频率从400kHz超到480kHz。测试部跑了两天都没事,结果第三批产线上有一成左右的传感器间歇性读回0xFF。查了三天才定位到是频率超标导致从设备内部状态机偶尔跳变。从那以后,我给自己定了个规矩:频率留20%余量。

小提示: 计算SCL周期时,用公式 T_scl = 1 / f_scl。比如100kHz,周期就是10µs。这个周期要分给高电平和低电平两部分。

2.2 高电平持续时间(tHIGH)

高电平持续时间是指SCL线保持高电平的时间。从设备在这段时间里读SDA线上的数据。如果高电平太短,从设备来不及采样,就会漏掉位数据。

I2C规范对tHIGH有明确要求:

模式最小tHIGH典型值(我常用)
标准模式 (100kHz)4.0 µs5.0 µs
快速模式 (400kHz)0.6 µs1.0 µs
高速模式 (3.4MHz)0.06 µs0.1 µs

嗯,这里要注意:tHIGH跟SCL频率是耦合的。频率定了,周期就定了,高电平加低电平必须等于一个周期。如果你设置频率400kHz,周期2.5µs,那高电平不能小于0.6µs,低电平也不能小于1.3µs(快速模式要求最小低电平1.3µs)。这两个必须同时满足。

我见过不少工程师把高电平设得特别短,低电平很长,以为只要周期对就行。不是的,从设备要求高电平必须够宽才能正确锁存数据。避坑指南:至少给tHIGH留20%余量,别卡着最小值。

2.3 低电平持续时间(tLOW)

低电平持续时间是SCL线保持低电平的时间。主设备在这段时间里改变SDA线上的数据,从设备在低电平期间准备下一次采样。

规格要求:

模式最小tLOW典型值(我常用)
标准模式4.7 µs5.5 µs
快速模式1.3 µs1.5 µs
高速模式0.13 µs0.2 µs

低电平太短,主设备来不及把SDA拉到正确电平就开始下一个上升沿,数据就脏了。我有一次调试一块带长线缆的传感器板,示波器一看SCL低电平只有0.8µs(快速模式),而实际线缆电容把SDA上升沿拉得很慢。结果数据位经常在上升沿时还没稳定,读出来乱码。后来我把低电平加到2.0µs,问题消失。

警告: 低电平不是越长越好。太长会导致整体通信速率下降。如果多个从设备挂在同一条总线上,太长的低电平会影响其他设备的时间窗口。建议用示波器实测,找到“刚好够用”的值。

2.4 上升时间(tr)与下降时间(tf)

这两个参数很多人忽略,但它们往往是隐形的杀手。上升时间是指SCL或SDA信号从30% VDD上升到70% VDD所需的时间。下降时间则反过来,从70%降到30%。

规范限值:

模式最大上升时间 tr最大下降时间 tf
标准模式1000 ns300 ns
快速模式300 ns300 ns
高速模式160 ns160 ns

上升时间主要由上拉电阻和总线电容决定。电容越大,上升沿越慢。我记得有一次项目用到1米长的I2C线缆,本来在实验板上100ns搞定的事,接上线缆后上升时间飙升到1.2µs,直接超出标准模式限值。我不得不把上拉电阻从4.7kΩ换成1kΩ才压下来。

下降时间主要由主设备的开漏驱动能力决定。大部分MCU的I/O引脚驱动都够用,但如果你用很弱的IO或者加了电平转换芯片,下降沿可能变慢。示波器一定要看下降沿,别只顾上升沿。

我的经验法则: 上升/下降时间不要超过SCL周期的一半(极端情况)。更实际的做法:保证 tr + tf ≤ 0.3 × Tscl,否则波形会变得太圆,从设备误判边沿位置。

2.5 五个参数的关系——一张图说清楚

下面这张SVG图展示了SCL时钟脉冲上五个关键时间参数的位置关系。记住:一个完整的SCL周期 = 高电平时间 + 低电平时间。上升和下降发生在电平切换的瞬间,它们的时间并不占用高/低电平的“有效值”,但在计算实际可用窗口时,必须把它们考虑进去。

I2C SCL时序参数图示 SCL时钟脉冲与五个时序参数 SCL周期 T_scl t_HIGH t_LOW t_r t_f 注意:t_r和t_f属于电平切换时间,不占用t_HIGH和t_LOW的有效部分,但它们会压缩可用数据窗口

2.6 如何在实际项目中快速定位时序问题

说了这么多参数,你得知道怎么查。我总结了一个三步排查法:

  1. 看示波器测量值——直接量SCL高电平、低电平、上升沿、下降沿,跟数据手册对比。这一步能排除80%的问题。
  2. 算总预算——确认 tHIGH + tLOW + 上升时间 + 下降时间 ≤ Tscl。注意上升和下降时间占用的时间片是重叠在高低电平边缘的,不要简单相加,但可以估算为 Tscl ≥ tHIGH + tLOW。
  3. 看SDA相对SCL的建立时间——SDA必须在SCL上升沿之前稳定。这个留到下一节细讲,但你先记住:如果前面四个参数都合规还出问题,多半是建立时间不够。
避坑指南: 我曾经遇到一个案例,示波器量出来所有时间参数都合规,但就是间歇性ACK失败。后来发现是下降时间太快(< 20ns)产生了振铃,导致从设备误检测到额外的边沿。下降时间不是越快越好,建议控制在50ns~200ns之间(快速模式)。

好了,这五个参数你心里有数了。去翻你的温度传感器数据手册,找到这些数字,对照一下你现在代码里设置的时序。很多时候问题就出在“差不多”上——差不多就是差很多。参数一个一个核对,用示波器一个一个验证,这是调试I2C最笨但也最有效的方法。