嵌入式以太网接口详解:MAC与PHY之间的MII/RMII/RGMII/SGMII选型指南
1. 先把底层的分工搞清楚MAC和PHY到底各管哪一段很多嵌入式工程师第一次接触以太网时最困惑的不是那堆协议栈代码而是硬件上那一堆引脚到底谁管谁。我以前带过好几个新人给他们扔一块带网口的核心板问“MAC在哪、PHY在哪”十有八九会指着RJ45座子说“这不就是网卡吗”。其实这个理解不能说全错但如果你想搞明白MII、RGMII、SGMII这些接口就非得先把MAC和PHY的职责边界掰扯清楚不可。1.1 从OSI分层说起MAC管“交通规则”PHY管“路况信号”以太网链路从逻辑上分好几层但硬件上真正干活的就两块芯片MACMedia Access Control介质访问控制层和PHYPhysical Layer物理层。MAC工作在OSI模型的数据链路层负责组帧、拆帧、地址过滤、CRC校验、冲突检测、流量控制这些“上层规矩”PHY工作在物理层负责把MAC送过来的并行数据变成真正能在网线上跑的电平信号或者反过来把网线上的模拟信号恢复成并行数据。用一个生活化的类比MAC和PHY的关系就像调度中心和外勤司机。MAC是调度中心它关心“车该什么时候发、车牌号对不对、货单要怎么写、验货怎么验”PHY是跑在路上的司机它只关心“眼前的这条路是柏油路还是土路、油门该给多大、怎么把车稳稳开到终点”。调度中心要求所有司机都照同一套单据交接这套单据就是MAC和PHY之间的接口标准。所以你要记住一个关键点PHY不解析以太网帧的内容它只负责把MAC给它的每一个字节变成物理信号扔到线上去再把线上收到的物理信号变成字节回给MAC。MAC才是真正会“读帧”的那个人。1.2 为什么中间非要插一个标准接口既然MAC和PHY分工明确那问题来了为什么不能让MAC直接把数据发给PHY非得定义一套MII、RMII、SGMII之类的接口标准最直接的原因是解耦。以太网标准发展了快五十年速度从10M一路涨到100M、1G、10GPHY的实现方式早就变了好几代。如果每换一颗PHY芯片主控里的MAC也要跟着改那系统厂商就彻底被某一家芯片供应商绑死了。于是IEEE在802.3系列标准里定义了一套MAC与PHY之间的独立接口规范让MAC一侧只需要关心“往接口上写数据”PHY一侧只需要关心“从接口上拿数据”两端互不绑架。另一个原因是成本。早期的10M以太网MAC和PHY是可以做到同一颗芯片里的比如经典的NE2000。但到了100M特别是千兆时代PHY前端要处理的模拟电路比如时钟恢复、均衡、编码解码和MAC的数字逻辑缓存、DMA、协议状态机工艺要求差异越来越大——数字逻辑用先进工艺划算模拟前端用成熟工艺更稳。强行集成在一颗SoC里面积成本和良率都受不了。于是业界的普遍做法是MCU/SoC里集成MAC外接一颗独立的PHY芯片两者通过标准化接口连接。你用STM32接LAN8720、用ESP32接IP101本质上都是在干这件事。除了数据接口MAC和PHY之间还有一条管理通道叫MDIO/MDC。MDIO是串行管理总线MAC通过它去读PHY的寄存器比如看link状态、协商结果、配置PHY的工作模式、读PHY芯片的ID。后面讲问题排查时会专门提到很多“连不上网”的坑都是先从MDIO读ID这一关开始的。2. 一张表看懂MII、RMII、GMII、RGMII、SGMII的区别接口的本质就三件事数据位宽、时钟频率、引脚数量。把这三个参数记住任何接口你都能快速看懂。我不喜欢一上来堆一堆术语先用一个类比接口协议就像两座城市之间的公路数据就是路上跑的车。有的路修得宽一次能并排跑8辆车有的路窄一次只能跑4辆甚至2辆但可以靠把车速提上来弥补。下面这张表是我常用的对照表建议直接收藏。它把几种主流MAC-PHY接口的关键参数列全了后面所有分析都围绕这张表展开。接口数据位宽时钟频率10M/100M/1000M是否支持典型引脚数不含MDIO电平标准适用场景MII4位25MHz / 2.5MHz10M / 100M16根左右3.3V CMOS老式ARM9、部分MCU现在用得少RMII2位50MHz10M / 100M9根左右3.3V CMOSSTM32、ESP32等MCU做百兆联网的主流选择GMII8位125MHz1G24根左右3.3V / 2.5V HSTL早期千兆设计引脚太多已经被替代RGMII4位DDR125MHz10M / 100M / 1000M12根左右2.5V / 3.3V千兆嵌入式主力性价比最高SGMII1位串行1.25Gbps10M / 100M / 1000M4根差分线收发各一对CML差分高性能交换、多端口路由器、背板互联2.1 MII以太网接口的元祖MIIMedia Independent Interface直译是“介质无关接口”名字里的“介质无关”意思是它不关心底层是双绞线还是光纤只要PHY支持就行。这是IEEE 802.3u标准里最早定义的MAC-PHY接口和100BASE-TX对应的Fast Ethernet是同一代产物。MII接口用4位数据线TXD[3:0]和RXD[3:0]在时钟的上升沿采样100M时时钟25MHz10M时降到2.5MHz。它还有收发控制信号TX_EN、TX_ER、RX_DV等和独立的收发时钟TX_CLK、RX_CLK。引脚数量算下来相当可观不算MDIO光数据相关的信号就接近16根。MII的问题非常直观——太占引脚。稍微算一下4位发送数据、4位接收数据、两个时钟、四五根控制线这还只是百兆。如果要做千兆位宽翻倍到8位时钟升到125MHz引脚数接近25根甚至更多这在现代高密度PCB设计里完全不可接受。所以MII现在更多是作为教学概念存在你在实际产品里见到它的概率比见到ISA总线还低。但理解MII很有价值它是后面所有接口演化的基础。2.2 RMII引脚减半的“省脚方案”RMIIReduced Media Independent Interface精简介质无关接口就是冲着省引脚去的。它的思路很直接把数据位宽从4位砍到2位让收发共用时钟把控制信号合并精简。代价是时钟频率从25MHz提高到50MHz靠频率翻倍补回位宽减半损失的带宽。RMII收发数据各只用2根线加上一条50MHz参考时钟、TX_EN发送使能、CRS_DV载波侦听/数据有效复用信号总数压到9根左右。相比MII板子上省出来的GPIO可以拿去干很多别的事对STM32、ESP32这种引脚不算宽裕的MCU来说非常友好。RMII有一个特别容易踩的坑是参考时钟的归属。MII的收发时钟分别由PHY或MAC提供RMII却把收发时钟合并成了一个50MHz的REF_CLK这个时钟到底由谁产生协议里并没有强制规定于是不同PHY芯片的接法差异很大。有的PHY要求MAC提供50MHz比如LAN8720在“从晶振/外部时钟输入”模式下有的PHY可以自己从25MHz晶振内部倍频出50MHz然后输出给MAC。我最开始调STM32F407DP83848的时候就是在这个REF_CLK上卡了两天——不是没接是时钟源方向搞反了导致RMII链路数据全乱。2.3 GMII与RGMII千兆接口的“重型”与“轻量”GMIIGigabit Media Independent Interface是千兆时代的MII数据位宽8位时钟125MHz收发分别有独立时钟和八位数据线全套信号加起来24根往上。数据吞吐量算下来正好是8bit×125MHz1Gbps和千兆以太网的线速率对齐。GMII在设计上没有任何问题问题还是那句话引脚太多而且125MHz的8位并行总线对PCB走线等长要求比较苛刻做起来非常痛苦。所以GMII在真实产品里很快就被RGMII取代了。RGMIIReduced Gigabit Media Independent Interface的思想和RMII一脉相承靠提高时钟利用率来压低引脚数。它的核心招数是DDRDouble Data Rate双沿采样——在125MHz时钟的上升沿和下降沿都采样数据用4位数据线实现等效8位位宽。换句话说一组TXD[3:0]在时钟上升沿送低4位、下降沿送高4位就相当于原来的8位数据线接收方向RXD[3:0]同理。这个设计把千兆接口的引脚数砍到12根左右在性能和引脚压力之间取得了极好的平衡所以RGMII成了目前千兆以太网最重要的板级接口。RGMII同时向下兼容10M/100M低速模式下时钟相应降低DDR采样依然生效。这里要提醒一句很多平台的RGMII是“降级复用”的如果你的主控手册写的是“支持RGMII”基本就不需要再考虑GMII了直接按RGMII布线就行。2.4 SGMII串行差分走向高速的基础SGMIISerial Gigabit Media Independent Interface把并行数据彻底抛弃改用一对发送差分线、一对接收差分线以1.25Gbps的串行速率传输数据。因为多了8B/10B编码开销1.25Gbps的实际有效带宽正好是1Gbps和千兆以太网的流量对应。SGMII为什么能成为更高端平台的主流根本原因在于串行差分信号的扩展性。并行总线上到一定速率就压不动了信号偏移、串扰、等长布线都头疼而差分串行可以轻松跑到几个G甚至几十个G。把MAC和PHY之间的接口做成串行之后PCB布线从“12根线等长”变成“两对差分线严格控制差分阻抗”面积、层数、调试难度都大幅下降。而且同一组SerDes物理通道只要配置不一样既可以当SGMII接以太网PHY也可以当PCIe或者其它协议用这对交换机、路由器这类多端口设备特别友好——所以很多交换芯片的MAC侧都是清一色的SGMII甚至QSGMII一个串行通道承载4路SGMII。SGMII有一个容易混淆的点它和链路另一端的网络接口比如RJ45那个口是完全独立的两码事。SGMII只负责主控MAC到PHY芯片之间的板级传输PHY芯片到了线缆侧还是要按1000BASE-T的物理层规范做编码和调制。有人以为用了SGMII就相当于“光口”或者“不用PHY了”这是不对的。只有在MAC自带SerDes并直接外接光模块的场景下才不走标准PHY那又属于1000BASE-X的范畴了不是今天讨论的SGMII接法。3. 实际选接口时到底看什么很多教程把每个接口的引脚画了一遍就结束了看得人头晕真到自己画板子、写设备树的时候还是不会选。其实选接口的决策链路非常清晰就是一条链主控支持什么 → 速率目标是什么 → 引脚预算和PCB条件允许什么 → PHY芯片有什么。下面把每个环节的实际考量拆开讲。3.1 主控和PHY的“菜单”决定了你的选择范围选接口的第一步不是看接口协议本身而是先打开主控芯片的数据手册看SoC集成的MAC到底支持哪几种接口模式。比如STM32F407的以太网MAC支持MII和RMII板上通过一个引脚ETH_MII_RMII_SEL切换ESP32内置MAC支持RMII很多Linux网关上的i.MX6ULL支持MII/RMII而到了i.MX8M系列、瑞萨RZ/G系列往往直接支持RGMIIXilinx的Zynq-7000内部MAC可以引出RGMII也可以通过软件配置走SGMII到PS侧的SerDes。反过来也要查PHY芯片支持的接口模式。LAN8720A只支持RMIIIP101GRI支持MII/RMIIDP83848支持MII/RMIIRTL8211F支持RGMII还有SGMII版本88E1512同时支持RGMII和SGMII。极限情况下一颗PHY的接口模式和速率如果和MAC对不上后面再怎么调软件都没用。所以选型第一步就是把两端的手册并排打开画出交集交集里的接口才是你的可行集。这里有一个很现实的建议如果MCU同时支持MII和RMII直接选RMII。省下的那六七个引脚在你后续增加传感器、串口、LCD或者调试接口时价值远大于MII带来的那一点点理论优势。MII只在某些特殊场景才值得选——比如MCU的RMII和某个外设产生了引脚复用冲突退回去用MII反而省事但这种场景太少见了。3.2 引脚预算与PCB布局的现实压力选接口就是一场引脚交换游戏。MII大约16根信号RMII大约9根RGMII大约12根SGMII只要4根差分线。在PCB上每多一根信号线就意味着多一份布线面积、多一些过孔、多一些等长约束有时候甚至直接决定你的板子能不能从4层降到2层。百兆RMII流行的一个很大原因就是它对PCB要求非常宽容。RMII是50MHz单端信号只要走线不要拉得太夸张基本不用做等长控制2层板也能跑得很稳。我之前做过一块用ESP32LAN8720的最小板RJ45的差分线做了10mil间距差分对RMII信号线随意走实测跑TCP下载能到90Mbps以上非常稳定。RGMII就不一样了125MHz的DDR信号收发数据和时钟之间必须做等长控制一般要求走线偏差控制在±50mil以内4层板起步否则时序窗口一紧张就会出现随机丢包——这类问题软件解决不了只能改板。SGMII对PCB的要求是另一种思路它不管等长但差分阻抗必须控制好。100Ω差分对走线按层叠计算好线宽线距收发两对尽量靠近PHY和MAC侧的SerDes引脚。SGMII对信号质量的容忍度比并行总线高一个量级板子设计得好走线长一点问题也不大。3.3 DDR时序与参考时钟RGMII和RMII最麻烦的两个坑如果说引脚数量是选接口的“面子”那时序和时钟就是“里子”绝大多数工程师踩的坑都在这里。RGMII的核心是DDR双沿采样它对CTS时钟到数据的建立保持时间非常敏感。IEEE规定RGMII的发送侧时钟由MAC和PHY各自沿PCB走线传输“源同步”的意味很强。说白了就是时钟沿着PCB走数据也沿着PCB走接收端在时钟沿采样数据双方必须在时序窗口内稳定。这就引出了PCB等长约束和FPGA里那一堆set_input_delay、set_output_delay约束——如果你在Zynq或者其它FPGA上做RGMII绕不开IDDR原语和IO时序约束。这部分在第四章的FPGA案例里我再详细展开。RMII的坑则主要集中在50MHz REF_CLK的方向上。我碰到过的典型情况有两种一是某些PHY比如LAN8720的REF_CLK既可以由MAC提供也可以由外部晶振提供如果模块上已经焊了50M晶振MAC侧就不能再输出时钟否则两路时钟打架链路起不来二是STM32F407做RMII时推荐方案是从MCO1引脚输出50MHz给PHY的REF_CLK但MCO1复用的是PA8引脚如果你把PA8当普通GPIO用了PHY就没时钟整个RMII直接瘫痪。这两种情况在调试的时候都极其隐蔽——因为软件配置看起来全对波形却不对。4. 几个典型项目的接口搭配思路光讲理论不给实战方案等于没讲。我挑了三类最常见的硬件组合把接口选择和关键注意事项写清楚你可以直接当设计参考用。4.1 ESP32 LAN8720低成本入门首选RMIIESP32内置MAC只支持RMIILAN8720A是市面上最便宜的百兆PHY之一只支持RMII这俩天生一对。接线非常简单RMII的TXD[1:0]接LAN8720的TXD[1:0]RXD[1:0]接RXDREF_CLK用50MHzTX_EN、CRS_DV各自对上再加上MDIO/MDC管理总线总共没几根线。这里的重点有三个。第一ESP32的REF_CLK可以自己产生也可以让LAN8720模块从外部晶振取时钟但如果你买的是常见的“ESP32-LAN8720模块”它默认方案是ESP32输出50M REF_CLK给LAN8720。第二PHY地址LAN8720默认是0或1取决于PHYAD0引脚很多模块把PHYAD0接地地址0或接3.3V地址1买回来先确认一下否则驱动里配不对地址MDIO读不到ID以太网起不来。第三LAN8720的复位引脚最好用ESP32的GPIO控制不能悬空上电后要保证一段时间的低电平复位再拉高进入工作状态。后面的避坑章节会把这三个问题再展开成完整的排查清单。4.2 STM32F407 DP83848工业联网经典RMIISTM32F407的MAC在STM32家族里算是很强的一代支持MII和RMII靠一个专用引脚切换。我最早做联网数据采集时用的就是F407DP83848当时选RMII是看中省引脚。F407做RMII的典型接法是MCO1引脚PA8输出50MHz时钟给DP83848的XI脚RMII的TXD[1:0]、RXD[1:0]、TX_EN、CRS_DV分别接到PHY对应引脚配置好复用功能。折腾过的人都知道F407的RMII有两大坑一是MCO1初始化和时钟树配置必须正确否则50M时钟出不来PHY直接摆烂二是RMII模式下ETH外设的引脚复用要全部配置成AF11漏配一个RXD引脚帧接收就断断续续。别问我怎么知道的——这两件事我在带新人时见过太多次了。还有一点DP83848的X1脚接时钟X2脚不接晶振时通常要悬空这个细节手册上写了但很多人画原理图时习惯性地给X2串个电容接地反而引入了不稳定的寄生参数。4.3 FPGA RGMII PHY时序约束是关键FPGA场景下MAC往往是你自己用逻辑写的或者用Xilinx的Tri-Mode Ethernet MAC IP核。PHY侧用RGMII几乎是默认选择比如Zynq-7000接RTL8211。RGMII对FPGA工程师最大的挑战不是逻辑而是IO时序约束。在Zynq的PL端做RGMII接收方向要用IDDR原语把DDR数据拆成两路单沿数据同时要给RXC设置合理的input delay。Xilinx的官方做法一般是在约束文件里用set_input_delay -clock [get_clocks rx_clk] -max 2.0之类的命令把Tsu/Th关系约束清楚。如果你不做这些约束综合实现后的时序报告大概率一片红跑起来随机丢包甚至完全不通。这个问题的典型症状是100M模式没问题、千兆模式下ping不通因为低速时时序裕量充足DDR采样根本不会错到了千兆125MHz时序窗口收紧没有约束的路径全暴露出来。我还碰到过一种更隐蔽的情况同一套RGMII设计在不同批次PHY芯片上表现不一样有些能跑千兆、有些只能跑百兆最后查下来就是RXC采样沿选错了——RGMII标准里建议把RXC反相后再采样数据但反过来用的PHY也有。建议在调试时先用示波器看RXC和RXD的相对相位再决定要不要加IDELAY。做RGMII的调试示波器不是可选项是必选项。4.4 高性能平台 SGMII走向更高端口密度在多网口网关、核心交换机这类设备里接口选择的逻辑完全不同。这类平台的主控或交换芯片往往自带SerDes通道比如Zynq UltraScale的PS-GTR、各种网络处理器的SerDes片上MAC通过SGMII接口直接和PHY芯片对接。比如88E1512支持SGMII和RGMII两种模式实际项目里如果主控在PCB布局上离PHY比较远就优选SGMII——4根差分线比12根并行线好拉得多而且差分线抗干扰能力也强。SGMII模式下还有一个优势不同PHY之间的“背靠背”测试很方便。什么意思呢当你想在没有主控的情况下验证两颗PHY是否正常可以把PHY1的SGMII或1000BASE-X侧接到PHY2的相同接口两边都配置成SGMII或自适应模式然后从PHY1的RJ45口发送数据走内部回环验证链路质量。这在产线测试和故障定位中都很有用。还要提一下车载以太网。车载上用100BASE-T1或1000BASE-T1物理层编码方向跟传统RJ45完全不同但MAC和PHY之间的接口并没有变——依然是从MAC侧引出RMII/RGMII到车载PHY芯片。所以你在车载ECU的原理图里看到的TJA1101、MARVELL 88Q2112这些车载PHY数据侧接口和普通PHY基本兼容反而是线缆侧的共模电感和ESD防护需要额外关注。理解了MAC-PHY接口车载以太网对你来说就只有物理层需要重新学。5. 避坑实录我踩过的那些PHY接口的坑调试经验这种东西文档里经常只有一句话实际踩一遍就是大半天。我把这几年遇到的典型问题整理成一个排查列表每个问题都写了症状和解决思路希望能帮你少走弯路。5.1 LAN8720的三板斧时钟、复位、PHY地址ESP32LAN8720这个组合是开源社区用得最多的低成本以太网方案但网上每天都有新人卡在同样三个地方。第一是REF_CLK时钟方向。LAN8720的第2脚PHYAD0/CLKOUT和第5脚REF_CLK在不同接地/配置下时钟来源会变。常见模板电路是外部25M晶振接LAN8720PHY内部倍频/输出50M给MAC也有模块把50M REF_CLK输入给LAN8720由MAC提供时钟。如果你买的模块没有原理图先测一下REF_CLK引脚上到底有没有50MHz波形再决定驱动里怎么配置。第二是复位时序。LAN8720的复位低电平时间不能太短我习惯用ESP32的GPIO控制复位脚上电后保持低电平10ms以上再拉高并延时一段时间等PHY稳定。如果复位时间不够PHY内部寄存器状态不确定MDIO可能能读但就是link不上。第三是PHY地址。LAN8720的SMI地址由PHYAD0脚决定接地是0接高是1。驱动里配置的PHY_ADDR必须和硬件一致如果配错了MDIO读ID会返回全1或者0xFFFFFFFF初始化直接失败。很多模块为了兼容性默认把PHYAD0接地地址0你从ESP-IDF示例程序里复制过来的代码如果写成1就要改回来。这个检查只需要一个电表测引脚电平比乱改软件快多了。5.2 千兆RGMII回环测试不过问题出在时序约束我做一块Zynq88E1512的板卡时遇到了一个特别磨人的问题单板静态测试一切正常两台设备对跑千兆吞吐过一段时间必掉一次包降到百兆跑一晚上都稳如老狗。开始怀疑是PHY芯片个体差异换了三片都一样。最后开着Vivado的时序报告一点点看发现问题出在RGMII RX路径上——软件里我只做了set_input_delay但没有把RXC时钟约束成与数据同源的“源同步时钟”导致实现工具对时钟树做了激进优化布线到了临界状态。这属于典型的“功能验证全过、长时间运行翻车”。给大家一个经验值RGMII的收发时钟和数据等长在FR4板材上按1 inch≈170ps延迟估算差分阻抗控制好之后PCB走线差50mil以内基本不用加IDELAY超过100mil或者跨层换过孔就必须在约束里显式补偿了。如果你用的是Xilinx器件直接用set_input_delay配好-min和-max再用set_clock_groups把RXC和其他时钟隔离不要省这一步。也不要迷信“板子画得好可以靠运气”时序约束必须写因为综合实现工具的算法不是为“刚好能跑”设计的它需要明确的目标来优化。5.3 MDIO读不到ID不是接口配对错误是引脚复用表骗了你MDIO读不到PHY的ID这个坑我在STM32上掉过一次也在Linux设备树调试时见过别人掉过一次。现象很统一ETH外设初始化失败ethtool或者裸机调试打印读回来的寄存器全是0xFFFF。第一反应都会去查PHY地址结果地址没错MDIO的引脚电平也正常。真正的问题在引脚复用表。STM32F407的MDIO在PA2MDC在PC1但如果板子上一开始把PA2复用成了USART2_TXMDIO引脚就不能正常输出802.3帧格式的MDC/MDIO波形了。这种问题最坑的地方在于你用万用表量PA2电平看起来有波形但波形完全不是MDIO的协议格式。排查方法很简单用示波器同时抓MDC和MDIO对照802.3协议看MDIO命令帧是否完整MDC频率是否在2.5MHz以内。频率太高是另一个常见原因——PHY的MDIO接口一般最高支持2.5MHz但有的MDC端口在软件里没有做分频直接跑在了几十MHz读寄存器当然一片乱码。5.4 RGMII千兆模式下随机丢包先查时钟相位再查电源纹波RGMII的另一个经典隐性故障就是“千兆随机丢包”。如果你已经把PCB等长、IO时序约束都做过了还是丢包那就把怀疑对象从信号完整性转到电源完整性上。PHY的数字电源和模拟电源如果共用一组LDO或者去耦电容放得太远在高负载时电源纹波会串进时钟频率综合器造成时钟抖动加大RGMII的建立保持时间裕量就会被吃掉。之前有个项目PHY芯片的AVDDH和DVDDH都是3.3V设计时图省事直接接在一起结果千兆大流量下RGMII偶发CRC错误包抓包根本看不出来因为错在PHY内部就已经恢复了。最后在AVDDH处加了一个磁珠和10μF100nF去耦电容才解决。所以画原理图的时候即使数据手册允许模拟和数字电源直连也建议按“模拟电源经过磁珠或小电阻再去耦”来做成本几乎为零却能避开一类特别难查的问题。5.5 时钟源、帧间隔和链路稳定性测试时容易被忽视的细节最后聊一个不那么起眼但很实际的点帧间隔。以太网标准规定两个帧之间要有最小帧间隔IFG百兆下是0.96μs。这个参数看起来是MAC侧的事但当你调RMII接口时如果MAC侧配置的IFG过小比如某些IP核默认配置成40bit而不是96bitPHY的发送FIFO在高负载下会处理不过来表现出来的症状就是吞吐上不去、偶发丢包。用iperf测试时如果发现“单线程上不去多线程正常”除了排查中断绑定之外也回头看一眼MAC IP核的IFG配置。还有一个和时钟源有关的细节很多RMII方案里REF_CLK的占空比要求比较严45%~55%如果你用了MCU内部时钟直接分频输出占空比可能达不到PHY的要求。实测下来用主控的PLL输出基本都能满足但用简单计数器分频出来的时钟就危险。所以RMII接法能用PLL输出或者外部有源晶振就尽量用省一个时钟芯片的钱后面可能要在调试上花十倍的精力。6. 接口学习的“钱花在刀刃上”思路把前面这些接口全看一遍之后很多人会纠结我到底要不要把所有接口都学会我的答案是对90%的应用场景认真玩透RMII和RGMII就够了。MII了解原理即可GMII基本可以跳过SGMII等真要做交换机、多网口网关时再深入也来得及。我个人的学习习惯是先拿一块ESP32LAN8720的板子把百兆RMII调通通过MDIO把PHY的所有关键寄存器读一遍搞清楚link状态位、协商结果、中断标志都在哪里然后再拿一块Zynq或者带RGMII的ARM板把RGMII时序约束写出来用示波器实测TXC和TXD的相对时序。这两步做完你对“MAC和PHY是怎么配合的”会有一种很难忘的体感——比看十篇文章都管用。实际去翻芯片手册的时候也别把几百页的datasheet从头看到尾。重点只看三部分接口时序图、寄存器表、参考原理图。时序图告诉你信号怎么对齐寄存器表告诉你状态从哪里读参考原理图告诉你电容电阻怎么摆放。三个都过一遍再难调的PHY也就那么回事。最后说个我一直以来的习惯画原理图之前先把MAC侧和PHY侧的每个接口信号列成一张Excel表格标清楚方向、电平、时钟域、复位归属。这看起来多花了半小时但真正到了打样回来调试的时候你会发现这张表能帮你省好几个通宵。选接口选到最后选的不只是协议更是你对整条链路可控度的把握。