3. MII信号详解:从时钟到控制,逐个击破
MII 接口,说白了就是 MAC 和 PHY 之间的一条“数据高速公路”。它一共用了 16 根信号线(如果算上管理接口的话更多),但别怕,咱们拆成四组来理解,马上就清爽了。
我个人习惯把这四组归为:时钟、数据、控制、监视。下面这张图可以帮你快速建立整体概念。
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%。排查了一整天,最后发现是时钟走线太靠近电源层了。
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 上的数据。
说实话,我调试过很多网络不通的问题,有 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 是你调试“网络拥堵”问题的好帮手。