4. I2C时序测量:SCL时钟频率测量、SDA数据建立/保持时间测量

好,咱们今天来聊聊I2C时序测量。说实话,I2C这玩意儿看起来简单,就两根线——SCL和SDA。但真要在示波器上把时序量准了,还是有不少门道的。我见过不少工程师,代码写得飞起,结果板子一调起来就是通信失败,最后查出来都是时序没卡到位。

嗯,咱们分两块来讲:先测SCL时钟频率,再测SDA的建立时间和保持时间。这两项是I2C通信的命根子,测准了,问题就解决了一大半。

4.1 SCL时钟频率测量

SCL时钟频率,说白了就是主设备给从设备打的拍子。拍子打快了,从设备跟不上;打慢了,效率又低。所以第一步,你得知道你的SCL到底跑在多少Hz。

测量方法其实很简单:

  • 用示波器探头勾住SCL引脚
  • 设置合适的时基,让屏幕上显示3~5个完整的时钟周期
  • 测量两个上升沿之间的时间差,这就是一个周期T
  • 频率 f = 1 / T

我个人习惯用示波器的“测量”功能直接读频率,省得自己算。但要注意,有些便宜示波器的测量精度一般,最好还是手动用光标卡一下周期,再算一遍。

关键点:标准模式下I2C频率是100kHz,快速模式是400kHz,高速模式能到3.4MHz。但实际测量时,由于线路寄生电容、上拉电阻的影响,实际频率往往会偏低一些。

我在项目中遇到过一件事:一块板子上I2C总线挂了三个从设备,怎么调都调不通。后来用示波器一测,SCL频率只有85kHz。按理说100kHz的设备应该能跑,但其中一个从设备的时序余量太小,85kHz的边沿斜率不够,导致采样出错。最后我把上拉电阻从4.7kΩ换成了2.2kΩ,频率回到了98kHz,问题解决。

小技巧:测量SCL频率时,最好在总线空闲状态下测,也就是没有数据传输的时候。因为传输过程中SCL会被从设备拉低(时钟拉伸),测出来的频率会偏慢。

4.2 SDA数据建立时间测量

建立时间(tSU:DAT)指的是:在SCL上升沿锁存数据之前,SDA上的数据必须提前稳定下来的时间。说白了,就是数据要“提前到位”,不能等时钟来了才变。

测量步骤:

  1. 示波器同时勾住SCL和SDA
  2. 触发方式设为SCL上升沿触发
  3. 找到SDA最后一次变化的位置
  4. 测量从SDA变化点到SCL上升沿的时间差

这个时间差,就是实际的建立时间。I2C规范要求:标准模式tSU:DAT ≥ 250ns,快速模式 ≥ 100ns。

注意:建立时间不够,最常见的后果就是从设备采到错误的数据位。我曾经调试一个温湿度传感器,读出来的数据偶尔跳变,查了半天发现是SDA建立时间只有80ns,而传感器要求至少100ns。后来在SDA上串了一个33Ω的小电阻,稍微减缓了边沿,建立时间就达标了。

4.3 SDA数据保持时间测量

保持时间(tHD:DAT)正好反过来:在SCL上升沿之后,SDA上的数据还要维持一段时间不变。这是为了让从设备有足够的时间把数据锁存进去。

测量方法:

  • 同样用SCL上升沿触发
  • 测量从SCL上升沿到SDA第一次变化的时间
  • 这个时间就是保持时间

I2C规范要求:tHD:DAT ≥ 0ns(标准模式和快速模式)。注意,是≥0,也就是说理论上SCL上升沿之后SDA可以立刻变。但实际中,我建议至少留出20~50ns的余量,因为从设备内部还有延迟。

实测经验:保持时间过长反而可能出问题。如果SDA在SCL下降沿之后还不变,下一个数据位就来不及准备了。所以保持时间不是越大越好,要适中。

4.4 实测数据参考表

下面是我整理的一份实测数据,供大家参考。这些数据来自我手头几块常见的开发板,用200MHz带宽的示波器测的:

设备 SCL频率 tSU:DAT tHD:DAT 备注
STM32F103 + 4.7kΩ上拉 98.2 kHz 320 ns 45 ns 标准模式,余量充足
ESP32 + 2.2kΩ上拉 392 kHz 115 ns 28 ns 快速模式,建立时间临界
ATmega328P + 10kΩ上拉 89.5 kHz 410 ns 62 ns 上拉电阻太大,频率偏低

你看,同样的I2C外设,不同的上拉电阻和主控,测出来的时序差别很大。所以别光看数据手册,一定要上示波器实测。

4.5 避坑指南

最后,我把自己踩过的坑总结一下,希望能帮你省点时间:

  • 探头地线要短:示波器探头的地线夹子越长,测出来的信号噪声越大。我习惯用地线弹簧,直接套在探头前端,效果很好。
  • 别在总线空闲时测建立时间:空闲时SDA和SCL都是高电平,没有变化,测不出建立时间。一定要在数据传输过程中抓波形。
  • 注意探头电容:普通探头有10~15pF的输入电容,对高速I2C(400kHz以上)会有影响。有条件的话用有源探头,或者至少用10x档位。
  • 我曾经犯过一个低级错误:用示波器的自动测量功能直接读建立时间,结果读出来的是负值。后来发现是触发点没设对,手动用光标卡一下就正常了。所以,自动测量可以看个大概,但关键数据一定要手动确认。

嗯,关于I2C时序测量,SCL频率、SDA建立时间和保持时间,这三项是最核心的。测准了它们,I2C通信的底子就稳了。下一节咱们聊聊SPI时序,那个比I2C要快得多,测量方法也不太一样。