第2章:RMII引脚定义与信号

记得我刚接触RMII的时候,第一反应就是——这玩意儿引脚真少。相比MII那种动辄二十多根线的接口,RMII只用了十根不到的信号线,布板子的时候心情那叫一个舒畅。但引脚少不代表坑少,今天我就把每个引脚掰开了讲,顺便聊聊我在项目里遇到的那些“事故现场”。

引脚总览

RMII一共定义了8根主要信号线,外加一根可选的管理接口线(MDC/MDIO,这一章先不展开)。你把这些信号理顺了,RMII的物理层连接也就通了。先看这张整体关系图:

RMII 引脚结构及信号流向 MAC / CPU (媒体接入控制器) PHY (物理层收发器) REF_CLK(50MHz) CRS_DV(载波+有效) RXD[1:0](接收数据) TXD[1:0](发送数据) TX_EN(发送使能) 箭头方向:→ 表示MAC到PHY或PHY到MAC; CRS_DV采用虚线,因为它在空载时可能保持低电平或高阻抗。

逐个引脚拆解

REF_CLK — 参考时钟(50MHz)

REF_CLK是RMII的“心跳”,频率固定50MHz,由外部晶振或PHY自身提供。我习惯把它叫作“全校时钟”,因为所有的发送接收都在它的上升沿上采样。注意,MAC和PHY必须用同源的时钟,否则就会出现抖动甚至数据错位。

避坑经验:曾经有个项目,硬件工程师为了省一颗晶振,让MAC从PHY引回REF_CLK,结果时钟走线太长、噪声耦合进PLL,导致丢包率飙升。嗯,从那以后我坚持“REF_CLK走线要短、包地要稳”。

CRS_DV — 载波检测与数据有效

这个引脚是二合一的。当PHY检测到网络上有载波(即有人正在发数据)时,CRS_DV拉高。同时,在帧接收期间它也会保持高,告诉MAC“现在RXD线上的数据是有效的”。说白了,它就是个“有数据,请接收”的旗子。

但这里有个容易翻车的地方:在百兆模式下,CRS_DV在帧间隙会拉低;假如PHY不支持内部回环时的CRS_DV处理,MAC可能会误判。我遇到过一次,PHY手册里一句都没提,结果整板调了三天才发现是CRS_DV在回环时乱跳。所以读PHY手册时一定看清楚CRS_DV的行为描述,特别是半双工模式下的载波冲突。

小技巧:调试时可以用示波器同时抓CRS_DV和RXD[1:0],你会发现CRS_DV的下降沿往往比RXD最后一个采样提前一个时钟周期,这是正常的“帧尾指示”。别因为提前了一点点就以为是问题。

RXD[1:0] — 接收数据总线

两比特宽度的接收数据线,在REF_CLK上升沿被MAC采样。每一拍传输2 bit(即一个“符号”),8个时钟周期完成一字节的接收。数据是“低位先行”还是“高位先行”?要看PHY配置,通常RMII规定低两位在前,但不同厂家的PHY可能有默认反转。我一般会在初始化时强制写寄存器确认。

时钟周期RXD[1:0]说明
T00b00前导码开始
T10b11SFD分隔符
T2~T9…数据字节依次传输

表格只是示例,实际抓包时要按照8拍一组来拼字节。我记得第一次调试时,把RXD的bit顺序看反了,结果解析出的MAC地址全颠倒了……后来我写了个小脚本,直接对比已知帧。

TXD[1:0] — 发送数据总线

和RXD类似,也是两比特宽度,在TX_EN有效时,MAC在REF_CLK上升沿输出待发送的数据。注意,TXD在TX_EN为低时必须保持稳定(通常为0),不然PHY会认为你在发垃圾数据。有一次我们修改代码时不小心把TXD在空闲时设置成了高阻,结果PHY一直检测到载波冲突,整个网络都连不上。排查了半天才发现是GPIO配置成了开漏输出。

TX_EN — 发送使能

这根线拉高,PHY就知道MAC要发帧了。TX_EN必须在第一个有效数据之前至少一个时钟周期拉高,并在最后一个有效数据后立即拉低。这个时序要求很严格,稍微慢一拍PHY就会漏掉前导码。我自己调试时习惯用逻辑分析仪同时看TX_EN和TXD,如果发现TX_EN的上升沿和TXD第一个符号不在同一个时钟沿,那就要检查MAC的MII接口配置了。

常见陷阱与检查清单

你在实际项目中可能遇到的问题,我列了一个清单,每一条都是我或者同事真金白银换来的教训:

  1. REF_CLK不同源:MAC和PHY用不同晶体,频率偏差超过50ppm直接导致链路不通。
  2. CRS_DV悬空:有些PHY的CRS_DV是开漏输出,必须外接上拉电阻,否则MAC永远读不到载波。
  3. RXD/TXD信号串扰:两对线并行走长线,特别是REF_CLK靠近RXD,容易产生时序抖动。
  4. TX_EN在复位期间拉高:很多MAC在初始化阶段乱输出,导致PHY误认为有数据,占住总线。
特别警告:不要假设PHY的默认寄存器配置。每次上电后最好读一遍PHY的Basic Mode Status Register,确认链路已经建立,再让MAC开始发送数据。否则TX_EN拉高后你发的帧可能会变成“幽灵帧”,连丢包都没地方查。

小结

RMII的引脚定义并不复杂,但每一个信号都有它的脾气。REF_CLK是根基,CRS_DV是眼睛,RXD/TXD是嘴巴,TX_EN是手——只有配合好了才能顺畅通信。你如果能把上面这些信号的行为和时序刻在脑子里,那“数据窗口分析”剩下的章节就会轻松很多。因为后面我们要看的那些波形图、抓包数据,本质上都是这几根信号在不同场景下的表演。