3. MII信号详解:从时钟到控制,逐个击破

MII 接口,说白了就是 MAC 和 PHY 之间的一条“数据高速公路”。它一共用了 16 根信号线(如果算上管理接口的话更多),但别怕,咱们拆成四组来理解,马上就清爽了。

我个人习惯把这四组归为:时钟、数据、控制、监视。下面这张图可以帮你快速建立整体概念。

MII接口信号分组框架 MII 信号 时钟信号 TX_CLK, RX_CLK 数据信号 TXD[3:0], RXD[3:0] 控制信号 TX_EN, RX_DV 监视信号 CRS, COL 核心原则:MII 是 4 位总线,25MHz 时钟下达到 100Mbps 每根信号线都有严格的时序关系,采样沿和有效电平不能搞错

3.1 时钟信号:TX_CLK 与 RX_CLK

想搞好 MII,先搞定时钟。这是所有数据同步的基础。

信号 方向 速率(100M) 谁提供
TX_CLK PHY → MAC 25 MHz PHY
RX_CLK PHY → MAC 25 MHz PHY

重要规则:时钟由 PHY 提供,不是 MAC。发送时钟和接收时钟彼此独立,但频率必须相同(10M 时为 2.5MHz)。

这里有个事我得提一下。时钟质量直接影响信号采样。如果时钟上有抖动或者占空比不达标,数据就等着出错吧。我在项目中遇到过,因为 PCB 布局不好,TX_CLK 被干扰了,结果 100M 模式下丢包率达到了 10%。排查了一整天,最后发现是时钟走线太靠近电源层了。

实战经验:TX_CLK 和 RX_CLK 必须单独走线,不要和别的信号共用。走线长度尽量短,阻抗控制在 50Ω ± 10%。如果你是新手,建议在 PHY 附近加个 RC 滤波,防止高频噪声串扰。

3.2 数据信号:TXD[3:0] 与 RXD[3:0]

数据线是主角。TXD 是发送数据,RXD 是接收数据,各 4 根,共 8 根。这就是为什么叫“4 位接口”。

数据信号的采样时刻很关键。MAC 在 TX_CLK 的上升沿送出发送数据,PHY 在同样的上升沿采样接收数据——但值得注意的是,RX_DV 和 RXD 必须在上升沿之前稳定一段时间。这个时间我习惯叫它“建立时间”。

你想想看,100M 模式下,每个时钟周期是 40ns。在这 40ns 里,数据必须稳定下来。如果建立时间不够,PHY 内部逻辑可能会采到错误的值。

重要:
  • TXD[0] 是最低位(LSB),TXD[3] 是最高位(MSB)。
  • 当 TX_EN 为高时,TXD 上的数据才有效。
  • RXD 同样只在 RX_DV 为高时有效。

一个常见的坑:很多工程师把 TXD[3:0] 和 RXD[3:0] 搞反了顺序。我见过有人把 TXD[0] 接到 PHY 的 RXD[3] 上,结果整个数据流都乱了。我的建议:设计原理图时,一定要在每一根数据线上标注编号。

3.3 控制信号:TX_EN 与 RX_DV

这两个信号相当于“数据有效”的开关。

信号 方向 作用 有效时
TX_EN MAC → PHY 发送使能 高电平
RX_DV PHY → MAC 接收数据有效 高电平

TX_EN 由 MAC 发出,告诉 PHY“我现在要发数据了”。PHY 在 TX_CLK 的上升沿检测到 TX_EN 为高时,就知道 TXD 上的数据是有效的,于是开始编码发送。

RX_DV 相反,是 PHY 告诉 MAC“我准备好接收数据了”。当 RX_DV 为高,MAC 就在 RX_CLK 的上升沿读取 RXD 上的数据。

特别注意:TX_EN 和 RX_DV 必须在时钟上升沿之前稳定。尤其是 RX_DV,它在 10M 模式下可能保持多个时钟周期的高电平,这没问题。但在 100M 模式下,每个数据包传输时 RX_DV 只能在高电平持续期间有效。如果它在数据中间变成了低电平,MAC 可能认为包结束了,导致 CRC 错误。

说实话,我调试过很多网络不通的问题,有 30% 都是因为 TX_EN 时序不对。比如 TX_EN 还没拉高,数据就已经送到 TXD 上了,或者 TX_EN 一直保持高电平,PHY 不停地发数据。解决办法其实很简单:逻辑分析仪一挂,一看波形全明白了。

3.4 监视信号:CRS 与 COL

这两个信号是半双工模式下的核心。别小看它们,半双工通信时全靠这俩来协调。

  • CRS(Carrier Sense):载波监听。PHY 检测到介质上有数据时,就把 CRS 拉高。不管你是不是在发送,只要介质忙,它就告诉你“别冲动”。
  • COL(Collision):冲突检测。当两个设备同时发送数据时,PHY 会检测到冲突,于是拉高 COL 信号。MAC 收到后启动退避算法。
场景 CRS COL
介质空闲 低 低
正在发送数据(无冲突) 高 低
正在发送数据(有冲突) 高 高

一个容易误解的点:很多人以为 CRS 只在接收数据时有效。其实它反映的是整条链路的忙闲状态。只要 PHY 观察到介质上有能量(哪怕不是发给你的),CRS 就会拉高。我曾经在项目中遇到过:交换机上连了一台笔记本电脑,笔记本电脑大流量下载时,另一台设备就发不了数据。后来发现是半双工模式下,CRS 一直高,MAC 以为介质一直在忙。

COL 信号在半双工时代很重要,但现在全双工普遍了,COL 基本不用了。很多新款的 PHY 芯片已经把 COL 管脚省略了。但如果你还在维护老设备,COL 是你调试“网络拥堵”问题的好帮手。

最后一个小提醒:有些 PHY 在 10M 模式下,CRS 的响应时间会比 100M 模式慢。如果你在做兼容性测试,一定要用示波器确认 CRS 在两种速率下的行为是否一致。我吃过这个亏,当时产品在 10M 模式下总是丢包,折腾了两天,最后发现是 PHY 的 CRS 过滤时间配置太长了。