3. I2C通信协议基础
说到光模块调试,I2C协议是绕不开的核心技能。我个人习惯把它比作模块的"神经系统"——你通过它读写寄存器,控制激光器偏置,监控温度电压。搞不懂I2C,调试就无从谈起。
这一节,咱们把I2C协议掰开揉碎了讲。你想想看,QSFP28模块内部其实就是一个微型系统,MCU通过I2C总线跟主机通信。说白了,就是两根线(SCL时钟、SDA数据)完成所有控制任务。
3.1 I2C总线工作原理
I2C总线采用主从架构。主机(通常是你的交换机或测试板)产生时钟,从机(光模块)响应数据。两根线都是开漏输出,需要上拉电阻。
关键特性:
- SCL:时钟线,由主机控制
- SDA:数据线,双向传输
- 速率:标准模式100kHz,快速模式400kHz,光模块常用100kHz
- 上拉电阻:通常4.7kΩ,具体看总线电容
避坑指南:我曾经遇到过一批模块I2C通信时好时坏,排查了半天发现是上拉电阻焊错了。10kΩ电阻在长走线时信号上升沿太慢,导致时序违规。嗯,这里要注意:上拉电阻不是随便选的,得根据总线电容算一下。
3.2 起始条件与停止条件
I2C总线的数据传输,由起始条件和停止条件界定。这两个信号是SCL和SDA的特定电平变化。
起始条件(Start Condition):
- SCL为高电平时,SDA从高电平跳变到低电平
- 表示一次传输开始
- 主机主动发起
停止条件(Stop Condition):
- SCL为高电平时,SDA从低电平跳变到高电平
- 表示一次传输结束
- 主机主动释放总线
我的经验:调试时用示波器抓SDA和SCL波形,先找起始和停止条件。如果波形不对,先检查上拉电阻和电源。我习惯用逻辑分析仪抓I2C时序,比示波器方便得多。
3.3 从机地址:0xA0与0xA2
QSFP28模块的I2C从机地址是固定的。这里有个容易混淆的点——地址有7位和8位两种表示法。
| 地址类型 | 7位地址 | 8位地址(含读写位) | 说明 |
|---|---|---|---|
| 低页地址 | 0x50 | 0xA0(写)/ 0xA1(读) | 访问低128字节 |
| 高页地址 | 0x51 | 0xA2(写)/ 0xA3(读) | 访问高128字节 |
你想想看,为什么会有两个地址?因为QSFP28的存储空间分成了低页和高页。低页存基本信息(温度、电压、告警),高页存扩展信息(诊断、厂商数据)。
注意:很多初学者搞混7位和8位地址。我建议你统一用8位地址(0xA0/0xA2),因为实际代码里写的就是这个值。0xA0 = (0x50 << 1) | 0,最后一位0表示写操作。
3.4 读写操作时序
I2C的读写操作,说白了就是主机发地址、发数据、收数据的过程。咱们分两种情况讲。
3.4.1 写操作时序
写操作相对简单:主机发送从机地址(写位),然后发送寄存器地址,再发送数据字节。每个字节后从机都要回复ACK。
// 写操作伪代码
主机: 起始条件
主机: 发送0xA0 (从机地址 + 写位)
从机: 回复ACK
主机: 发送寄存器地址 (例如0x00)
从机: 回复ACK
主机: 发送数据字节 (例如0x55)
从机: 回复ACK
主机: 停止条件
3.4.2 读操作时序
读操作稍微复杂一点。需要先写寄存器地址,然后重新发送起始条件,再发送读地址。这叫"组合传输"。
// 读操作伪代码
主机: 起始条件
主机: 发送0xA0 (从机地址 + 写位)
从机: 回复ACK
主机: 发送寄存器地址 (例如0x00)
从机: 回复ACK
主机: 重新起始条件
主机: 发送0xA1 (从机地址 + 读位)
从机: 回复ACK
主机: 读取数据字节
主机: 发送NACK (表示读取结束)
主机: 停止条件
避坑指南:我曾经在调试时发现读回来的数据全是0xFF,查了半天发现是重新起始条件没发对。有些MCU的I2C外设需要手动配置才能产生重新起始条件,否则它会发停止条件再发起始条件,这样从机就懵了。
3.5 时钟拉伸与仲裁
这两个概念比较高级,但调试时经常会遇到。
3.5.1 时钟拉伸
时钟拉伸是从机的一种"慢下来"机制。当从机还没准备好处理下一个字节时,它会拉低SCL线,迫使主机等待。
为什么会这样?因为光模块内部的MCU可能正在处理其他任务(比如ADC采样),来不及响应I2C请求。它通过时钟拉伸告诉主机:"等一下,我还没忙完。"
我的经验:有些主机的I2C控制器不支持时钟拉伸。如果你用的MCU不支持,就得在软件里做超时处理。我习惯设置5ms超时,如果从机一直拉低SCL,就复位I2C总线。
3.5.2 总线仲裁
总线仲裁发生在多主机系统中。当两个主机同时尝试控制总线时,谁发送低电平谁就赢得仲裁。因为I2C是开漏输出,低电平会覆盖高电平。
在光模块调试中,总线仲裁不常见。但如果你用I2C转接板或者多主机系统,就得注意了。仲裁失败的设备会释放总线,等待下次机会。
注意:仲裁过程中,数据不能丢失。I2C协议保证了仲裁的原子性——赢得仲裁的设备继续传输,输掉的设备检测到仲裁丢失后停止发送。
3.6 知识体系总览
下面这张图把I2C协议的核心知识点串起来了。你可以把它当作调试时的快速参考。
这张图把I2C协议拆成了五个维度。我个人觉得,调试时最常用的是时序和地址部分。你只要把起始条件、停止条件、0xA0/0xA2地址搞清楚,80%的问题都能解决。
最后说一句:I2C协议看着简单,但实际调试中坑不少。我建议你准备一个逻辑分析仪,抓几组波形看看。纸上得来终觉浅,绝知此事要躬行。
公众号:蓝海资料掘金营,微信deep3321