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%余量。
2.2 高电平持续时间(tHIGH)
高电平持续时间是指SCL线保持高电平的时间。从设备在这段时间里读SDA线上的数据。如果高电平太短,从设备来不及采样,就会漏掉位数据。
I2C规范对tHIGH有明确要求:
| 模式 | 最小tHIGH | 典型值(我常用) |
|---|---|---|
| 标准模式 (100kHz) | 4.0 µs | 5.0 µs |
| 快速模式 (400kHz) | 0.6 µs | 1.0 µs |
| 高速模式 (3.4MHz) | 0.06 µs | 0.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 µs | 5.5 µs |
| 快速模式 | 1.3 µs | 1.5 µs |
| 高速模式 | 0.13 µs | 0.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 ns | 300 ns |
| 快速模式 | 300 ns | 300 ns |
| 高速模式 | 160 ns | 160 ns |
上升时间主要由上拉电阻和总线电容决定。电容越大,上升沿越慢。我记得有一次项目用到1米长的I2C线缆,本来在实验板上100ns搞定的事,接上线缆后上升时间飙升到1.2µs,直接超出标准模式限值。我不得不把上拉电阻从4.7kΩ换成1kΩ才压下来。
下降时间主要由主设备的开漏驱动能力决定。大部分MCU的I/O引脚驱动都够用,但如果你用很弱的IO或者加了电平转换芯片,下降沿可能变慢。示波器一定要看下降沿,别只顾上升沿。
2.5 五个参数的关系——一张图说清楚
下面这张SVG图展示了SCL时钟脉冲上五个关键时间参数的位置关系。记住:一个完整的SCL周期 = 高电平时间 + 低电平时间。上升和下降发生在电平切换的瞬间,它们的时间并不占用高/低电平的“有效值”,但在计算实际可用窗口时,必须把它们考虑进去。
2.6 如何在实际项目中快速定位时序问题
说了这么多参数,你得知道怎么查。我总结了一个三步排查法:
- 看示波器测量值——直接量SCL高电平、低电平、上升沿、下降沿,跟数据手册对比。这一步能排除80%的问题。
- 算总预算——确认 tHIGH + tLOW + 上升时间 + 下降时间 ≤ Tscl。注意上升和下降时间占用的时间片是重叠在高低电平边缘的,不要简单相加,但可以估算为 Tscl ≥ tHIGH + tLOW。
- 看SDA相对SCL的建立时间——SDA必须在SCL上升沿之前稳定。这个留到下一节细讲,但你先记住:如果前面四个参数都合规还出问题,多半是建立时间不够。
好了,这五个参数你心里有数了。去翻你的温度传感器数据手册,找到这些数字,对照一下你现在代码里设置的时序。很多时候问题就出在“差不多”上——差不多就是差很多。参数一个一个核对,用示波器一个一个验证,这是调试I2C最笨但也最有效的方法。