第3章:MDIO总线电气特性:电压、时序、驱动能力
做嵌入式系统的硬件工程师,免不了跟各种串行总线打交道。MDIO 看着简单,就两根线——MDC 和 MDIO,但真要让它跑稳了,电气上得抠细节。
我拆过不少故障板子,有一半以上 MDIO 问题其实不是协议逻辑错了,而是物理层没伺候好。说白了,电压没对上,时序建不了,驱动不够力——这三样哪个出问题,PHY 都不搭理你。
核心要点:MDIO 总线的电气特性可以拆成三个维度:电压域匹配、时序参数达标、驱动能力足够。任何一项短板,都会导致通信间歇性失败或完全不通。
3.1 电压电平——匹配是基础,不匹配全是坑
MDIO 接口最早是跟着 MII 一起出来的,逻辑电平直接取系统 IO 电压。大部分 PHY 芯片支持 1.8V、2.5V、3.3V。也有些新器件支持 1.2V。你得确保主控侧的 MDIO 和 PHY 侧的 MDIO 工作在同一个电压域。
我在一个项目中遇到过:主控是 1.8V 的 FPGA,PHY 是 3.3V 的老芯片。直接连上,读寄存器偶尔对偶尔错。用示波器一看,MDIO 高电平只有 1.6V,PHY 认为没到 VIH 阈值。接了个电平转换芯片就好了。
我的习惯:原理图阶段就检查两端的 VIH/VIL 表格。如果电压域不同,加双路电平转换器(比如 TXS0102),千万别用电阻分压——MDIO 是双向总线,分压会把输入信号也吃掉。
下面是常见电平标准参考:
| 参数 | 最小值 | 典型值 | 最大值 | 单位 |
|---|---|---|---|---|
| VIH | 2.0 | — | 3.6 | V |
| VIL | −0.3 | — | 0.8 | V |
| VOH | 2.4 | 3.0 | — | V |
| VOL | — | 0.2 | 0.4 | V |
注意:1.8V 系统的 VIH 一般要大于 1.17V,VIL 小于 0.63V。如果你的信号上升沿缓,很容易卡在阈值附近造成误采样。
3.2 时序参数——快有快的规矩,慢有慢的底线
IEEE 802.3 标准给 MDC 时钟下限划了一道线:最大频率是 2.5 MHz,最小周期 400 ns。但实际上很多现代主控能跑到 10 MHz 甚至更高。
你想想看,如果 MDC 太快,PHY 跟不上内部状态机,就可能漏采数据。反过来太慢,总线占用时间长,影响其他并发操作。
我曾经踩过的坑:在一款交换机项目里,为了减少 MDIO 访问延时,我把 MDC 设到 12 MHz。结果 PHY 偶尔返回全 F 的数据。查手册发现那个 PHY MDC 最大只支持 8 MHz。降回 5 MHz,问题消失。从此我养成习惯——先看 PHY 数据手册的 Timing Characteristics 表格,再定 MDC 频率。
MDIO 的时序主要看以下几个参数:
- Tcyc(时钟周期): 通常 ≥ 400 ns(对应 2.5 MHz),可适当放慢至 1 μs 以下
- Tsu(数据建立时间): MDIO 在 MDC 上升沿之前需有效,典型要求 ≥ 10 ns
- Thd(数据保持时间): 上升沿之后数据仍需保持稳定,典型要求 ≥ 10 ns
- Tr/Tf(上升/下降时间): 通常 ≤ 5 ns(20%-80%),避免振铃过冲
下面是一个典型的 MDC 与 MDIO 的时序图参数示例(数据来自某主流 PHY 手册):
| 符号 | 说明 | 最小值 | 最大值 | 单位 |
|---|---|---|---|---|
| fMDC | MDC 时钟频率 | 0 | 2.5 | MHz |
| tcyc | MDC 周期 | 400 | — | ns |
| thigh | MDC 高电平宽度 | 170 | — | ns |
| tlow | MDC 低电平宽度 | 170 | — | ns |
| tsu | 数据建立时间 | 10 | — | ns |
| thd | 数据保持时间 | 10 | — | ns |
| tr | 上升时间(20%~80%) | — | 5 | ns |
| tf | 下降时间(20%~80%) | — | 5 | ns |
实际调试中,我习惯先用示波器抓 MDC 波形,看占空比和边沿斜率。如果上升沿超过 10 ns,就有隐患。可以在 MDC 线上串一个 22 Ω 电阻来抑制过冲,但别太大,否则边沿更缓。
3.3 驱动能力——拉不上去,读回来就是零
MDIO 是开漏(或推挽)双向线,通常需要在主控侧或 PHY 侧加一个上拉电阻。因为总线空闲时是高阻态,靠上拉保持高电平。
上拉电阻的取值有讲究。阻值太小,灌电流太大,IO 口可能扛不住;阻值太大,上升时间会拉长。我一般从 1.5 kΩ 开始试,如果总线上挂的器件多,换成 4.7 kΩ,再大了就容易出问题。
快速估算公式: 上拉电阻 Rp = (VDD - VOL) / IOL。其中 IOL 是 IO 口允许的最大灌电流,通常在 4~8 mA 范围内。代入 3.3V,VOL=0.4V,IOL=4 mA,得 Rp ≈ 725 Ω。考虑裕量,取 1 kΩ ~ 2.2 kΩ 都没问题。
驱动能力还体现在输出电流上。如果主控的 GPIO 驱动强度不够(比如某些 MCU 默认只有 2 mA),高电平可能拉不到 VOH。我建议把 MDIO 和 MDC 对应的 GPIO 配置为 high-drive 模式(如果有的话),或选择专门的 MDIO 控制器引脚。
另外,注意总线的扇出能力。一个主控可以带多个 PHY,但每增加一个 PHY,总线电容就增加约 5 pF(含走线)。总电容超过 30 pF 时,上升沿会明显变缓,尤其在使用大上拉电阻的情况下。遇到过一块背板上挂了 8 个 PHY 的案子,MDIO 线上的波形几乎变成了三角形,后来把上拉电阻从 10 kΩ 改成 2.2 kΩ,同时缩短走线,问题才解决。
避坑指南:我曾经在调试时发现 MDIO 线在 PHY 侧有下拉电阻 10 kΩ 到地——那是上一个工程师遗留的测试焊盘。结果导致 MDIO 低电平时总线上还有 0.7V,PHY 一直读不到正确数据。所以,仔细检查原理图里所有跟 MDIO 相连的电阻,确认没有意外下拉或分压。
小结
MDIO 的电气特性看起来是基本功,但实操中出问题的频率很高。我的经验是:先确认电压匹配,再检查时序余量,最后验证驱动强度和上拉配置。这三步走完,物理层基本就稳了。如果还不行,拿示波器看波形,找边沿问题或噪声 — 别急着怀疑协议栈。