MDIO 物理层:双线制(MDC/MDIO)、电气特性、上拉电阻

讲协议之前,咱们先把物理层的底子打牢。MDIO 总线说白了就两根线:时钟线 MDC 和数据线 MDIO。别小看这两根线,很多项目出问题就出在物理层——布线不对、上拉电阻选错,或者电平不匹配。我曾在一个交换板项目中,就因为上拉电阻用了 10kΩ,结果总线负载一重,上升沿直接软了,通信死活不稳定。后来才发现,物理层的细节,真能让你折腾一整天。

双线制总线结构

MDC 是主控发出的时钟,频率通常 2.5MHz 以下(也有跑到 12.5MHz 的,但要看芯片是否支持)。MDIO 是双向数据线,半双工工作。主控通过 MDC 的上升沿或下降沿采样 MDIO 上的数据,具体方式要看协议帧格式(后面章节会细讲)。

大家注意,这根 MDIO 线是开漏输出结构。主控和所有从设备(PHY 芯片)都只是把 MDIO 拉到低电平,拉高靠外部上拉电阻。嗯,这就引出了上拉电阻的重要性。

核心点: 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 线——谁想发送数据,谁就控制拉低,其他芯片保持高阻。这就是总线仲裁的基础。

上拉电阻的阻值可不是随便选的。选太大,上升沿会变得很慢,导致时序违规;选太小,功耗大,而且当芯片拉低时,灌电流可能超出引脚驱动能力。来看一个快速估算方法:

  1. 确定总线寄生电容 Cbus:PCB 走线电容 + 每个 PHY 引脚电容。一般每 cm 走线约 1pF,每个 PHY 约 5-10pF。假设 4 个 PHY,走线 15cm,总电容 ≈ 15pF + 4×8pF = 47pF。
  2. 设定允许的最大上升时间 tr:MDC 周期 T = 1/f。通常要求上升时间 ≤ 0.1T。比如 2.5 MHz → T = 400ns → tr ≤ 40ns。
  3. 计算最大电阻 Rmax:tr ≈ 2.2 × R × Cbus → R ≤ tr / (2.2 × Cbus) = 40e-9 / (2.2 × 47e-12) ≈ 387Ω。但这么小的电阻会导致灌电流过大,所以一般还要考虑驱动能力。
  4. 检查灌电流 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Ω 左右。

曾经踩过的坑: 我用 10kΩ 上拉,接了 5 个 PHY,总线电容大概 60pF。计算上升时间约 1.3μs,而 MDC 周期才 400ns,上升沿就占了三分之一周期,MDIO 采样窗口完全丢失。后来换 2.2kΩ 解决。

布线布局注意事项

MDC 和 MDIO 最好走成平行短线,尽量靠近主控。不要在总线上引出长的分支 stubs——每根 stub 都会引入额外的反射和电容。对于多 PHY 设备,我建议采用菊花链拓扑,而不是星型。菊花链就是把 MDC 和 MDIO 依次从一个 PHY 穿到下一个,最后在末端接上拉电阻。这样每个分支都很短。

另外,MDC 时钟线要避免与其他高频信号(比如 RGMII 的时钟)平行太长,不然串扰会让你怀疑人生。我曾经在 4 层板上,MDC 走第二层,下面正好是 DDR 时钟,结果 MDIO 波形一路毛刺。最后加了个 22Ω 串联电阻在 MDC 源端,才压住振铃。

一张图看懂物理层

下面这个 SVG 画了一个典型的 MDIO 物理连接。主控通过 MDC 和 MDIO 连接到三个 PHY 芯片,总线上挂了一个上拉电阻到 VDD。注意右侧的上升沿波形——没有上拉,波形永远到不了高电平。

MDIO 物理总线连接图 主控 (MDC + MDIO) MDC MDIO PHY 1 PHY 2 PHY 3 RPU VDD 上升沿 无上拉,波形 无法到 VDD
小技巧: 如果总线上的 PHY 数量超过 4 个,或者走线超过 20cm,可以考虑在总线两端各加一个上拉电阻(阻值加倍),或者用一个总线缓冲器。

总结一下关键点

  • MDC/MDIO 是双线制开漏总线,必须外部上拉。
  • 上拉电阻推荐 1.5kΩ~2.2kΩ(3.3V 系统),若电压低容值大,可适当减小。
  • 总线电容决定了最大上升时间,进而影响最高 MDC 频率。
  • 走线宜短、无长 stub,采用菊花链拓扑最稳妥。
  • 不同电平标准需要转换 I/O,切勿直接连接。

物理层搞定了,后面讲协议帧和读写操作才不心虚。嗯,先把这两根线伺候好,MDIO 通信就成功了一半。