MDIO 物理层:双线制(MDC/MDIO)、电气特性、上拉电阻
讲协议之前,咱们先把物理层的底子打牢。MDIO 总线说白了就两根线:时钟线 MDC 和数据线 MDIO。别小看这两根线,很多项目出问题就出在物理层——布线不对、上拉电阻选错,或者电平不匹配。我曾在一个交换板项目中,就因为上拉电阻用了 10kΩ,结果总线负载一重,上升沿直接软了,通信死活不稳定。后来才发现,物理层的细节,真能让你折腾一整天。
双线制总线结构
MDC 是主控发出的时钟,频率通常 2.5MHz 以下(也有跑到 12.5MHz 的,但要看芯片是否支持)。MDIO 是双向数据线,半双工工作。主控通过 MDC 的上升沿或下降沿采样 MDIO 上的数据,具体方式要看协议帧格式(后面章节会细讲)。
大家注意,这根 MDIO 线是开漏输出结构。主控和所有从设备(PHY 芯片)都只是把 MDIO 拉到低电平,拉高靠外部上拉电阻。嗯,这就引出了上拉电阻的重要性。
电气特性:电平与频率
MDIO 总线的电平标准不唯一。常见的有 3.3V、2.5V、1.8V,甚至有些老芯片还用 5V。在实际项目中,主控和 PHY 的 I/O 电压必须一致,否则得加电平转换。我记得有一次,主控用 1.8V 的 MDIO,而 PHY 要求 3.3V 电平,我就忘了加转换,结果数据完全读不出来,还以为是时序问题。
下面这个表格列出常见电平标准对应的参数。你自己用的时候一定要先看芯片 datasheet 的 I/O 特性部分。
| 电平标准 (V) | VIH min (V) | VIL max (V) | VOH min (V) | VOL max (V) |
|---|---|---|---|---|
| 3.3V | 2.0 | 0.8 | 2.4 | 0.4 |
| 2.5V | 1.7 | 0.7 | 2.0 | 0.4 |
| 1.8V | 1.2 | 0.6 | 1.4 | 0.45 |
MDC 的最高频率各芯片不同。IEEE 802.3 标准定义 MDC 最大为 2.5 MHz,但很多现代 PHY 支持到 12.5 MHz。如果你想把频率跑上去,就得确保总线电容够小、上拉电阻够小。我碰到过一个项目,在 PCB 上走了 20cm 长的 MDIO 线,还接了 4 个 PHY,结果一上 5 MHz 就出错,最后只能降频到 2 MHz。
上拉电阻的作用与选择
为什么一定要上拉?因为所有芯片的 MDIO 引脚都是开漏输出,芯片内部只有下拉场效应管。当芯片想输出 0 时,它把引脚拉到 GND;想输出 1 时,它什么都不做(高阻),靠外部电阻把引脚拉到 VDD。这种结构的好处是多个芯片可以安全地共享一根 MDIO 线——谁想发送数据,谁就控制拉低,其他芯片保持高阻。这就是总线仲裁的基础。
上拉电阻的阻值可不是随便选的。选太大,上升沿会变得很慢,导致时序违规;选太小,功耗大,而且当芯片拉低时,灌电流可能超出引脚驱动能力。来看一个快速估算方法:
- 确定总线寄生电容 Cbus:PCB 走线电容 + 每个 PHY 引脚电容。一般每 cm 走线约 1pF,每个 PHY 约 5-10pF。假设 4 个 PHY,走线 15cm,总电容 ≈ 15pF + 4×8pF = 47pF。
- 设定允许的最大上升时间 tr:MDC 周期 T = 1/f。通常要求上升时间 ≤ 0.1T。比如 2.5 MHz → T = 400ns → tr ≤ 40ns。
- 计算最大电阻 Rmax:tr ≈ 2.2 × R × Cbus → R ≤ tr / (2.2 × Cbus) = 40e-9 / (2.2 × 47e-12) ≈ 387Ω。但这么小的电阻会导致灌电流过大,所以一般还要考虑驱动能力。
- 检查灌电流 IOL:芯片拉低时,电流 I = VDD / R。如果 VDD=3.3V,R=387Ω,则 I≈8.5mA。大部分芯片 IOLmax 在 4-8mA,超了。所以 R 得再大一些。
实际项目中,我偏好使用 1.5kΩ~2.2kΩ 的电阻。对于 3.3V 系统,这个范围折中了上升时间和灌电流。如果总线负载很轻(只有一片 PHY,走线很短),可以用 4.7kΩ 或 10kΩ,省电。但注意:如果电压是 1.8V 系统,同样的阻值电流更小,上升时间会更长,这时候可能要用 1kΩ 左右。
布线布局注意事项
MDC 和 MDIO 最好走成平行短线,尽量靠近主控。不要在总线上引出长的分支 stubs——每根 stub 都会引入额外的反射和电容。对于多 PHY 设备,我建议采用菊花链拓扑,而不是星型。菊花链就是把 MDC 和 MDIO 依次从一个 PHY 穿到下一个,最后在末端接上拉电阻。这样每个分支都很短。
另外,MDC 时钟线要避免与其他高频信号(比如 RGMII 的时钟)平行太长,不然串扰会让你怀疑人生。我曾经在 4 层板上,MDC 走第二层,下面正好是 DDR 时钟,结果 MDIO 波形一路毛刺。最后加了个 22Ω 串联电阻在 MDC 源端,才压住振铃。
一张图看懂物理层
下面这个 SVG 画了一个典型的 MDIO 物理连接。主控通过 MDC 和 MDIO 连接到三个 PHY 芯片,总线上挂了一个上拉电阻到 VDD。注意右侧的上升沿波形——没有上拉,波形永远到不了高电平。
总结一下关键点
- MDC/MDIO 是双线制开漏总线,必须外部上拉。
- 上拉电阻推荐 1.5kΩ~2.2kΩ(3.3V 系统),若电压低容值大,可适当减小。
- 总线电容决定了最大上升时间,进而影响最高 MDC 频率。
- 走线宜短、无长 stub,采用菊花链拓扑最稳妥。
- 不同电平标准需要转换 I/O,切勿直接连接。
物理层搞定了,后面讲协议帧和读写操作才不心虚。嗯,先把这两根线伺候好,MDIO 通信就成功了一半。