ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

STM32以太网开发实战:LAN8720A与YT8512C PHY芯片调试避坑指南

STM32以太网开发实战:LAN8720A与YT8512C PHY芯片调试避坑指南 1. 项目缘起与整体设计思路嵌入式以太网开发这件事说简单也简单说坑多那也是真的多。我前后做过十几个带网口的STM32项目从F107到F407再到H743PHY芯片从LAN8720A换到YT8512C中间踩过的坑足够写一本小册子。这篇文章就把这些经验一次性倒出来重点讲清楚STM32配合LAN8720A和YT8512C这两款常见PHY芯片时怎么把以太网连接做稳以及那些文档里不会写、但实际调试中一定会遇到的问题。先明确一下这个项目的定位主控用STM32F407系列F107、F429同样适用通过RMII接口连接PHY芯片PHY再通过网络变压器接到RJ45座子最终实现一个稳定的以太网通信链路。LAN8720A和YT8512C都是10/100M自适应的PHY前者是SMSC现Microchip的老牌经典型号后者是裕太微的国产替代方案引脚基本兼容但在时钟方案和配置细节上有差异。适合谁看正在做STM32以太网项目、被PHY初始化卡住、ping不通、丢包严重、或者想从LAN8720A切换到YT8512C的兄弟这篇内容应该能帮你省下不少调试时间。整体设计上我倾向于把硬件和软件分开讲因为以太网不通八成问题出在硬件上剩下两成里又有一大半是时钟配置的问题。所以思路是先把硬件链路理清楚再讲软件初始化流程最后集中火力讲排查。这个顺序也是我实际调试时遵循的顺序从物理层往上查比一上来就盯着代码看效率高得多。2. 硬件链路设计与PHY选型考量2.1 RMII接口的引脚连接与信号含义RMIIReduced Media Independent Interface是MAC和PHY之间的精简接口相比MII少了将近一半的引脚。STM32F407的RMII接口需要以下信号REF_CLK50MHz参考时钟这是RMII的命脉后面单独讲TXD0、TXD1发送数据2位宽RXD0、RXD1接收数据2位宽TX_EN发送使能CRS_DV载波侦听/数据有效复用信号MDIO、MDC管理接口用来读写PHY寄存器这里有个容易搞混的点RMII的REF_CLK是50MHz而MII是25MHz。很多人从MII参考电路抄过来时钟就错了。另外CRS_DV这个信号在RMII里是复用引脚既表示载波侦听又表示接收数据有效接错或者上拉电阻没处理好会出现能发送但收不到数据的情况。STM32F407这边RMII引脚是固定的不能随便映射。以F407为例PA1是REF_CLKPA2是MDIOPA7是CRS_DVPC1是MDCPC4是RXD0PC5是RXD1PB11是TX_ENPB12是TXD0PB13是TXD1。这些引脚在配置时要设成复用推挽输出或者浮空输入具体看方向。我见过有人把MDIO配成普通GPIO结果PHY寄存器读写全返回0xFFFF查了半天才发现是复用功能没开。2.2 LAN8720A与YT8512C的关键差异这两款芯片虽然引脚兼容但内部设计和配置方式有区别直接替换不一定能跑起来。对比项LAN8720AYT8512C厂商Microchip裕太微时钟方案需外部25MHz晶振或STM32提供50MHz内置PLL可外接25MHz晶振PHY地址默认0可通过引脚配置默认0配置方式略有不同寄存器兼容性标准IEEE 802.3基本兼容部分扩展寄存器不同自协商支持支持功耗较低更低价格较高有优势最大的差异在时钟方案。LAN8720A需要一个25MHz的晶振然后内部PLL倍频到50MHz输出给STM32或者反过来由STM32提供50MHz时钟。而YT8512C内置了PLL可以自己产生时钟对外部时钟的依赖更灵活。这个差异直接影响到REF_CLK的走线方向后面细说。2.3 网络变压器与RJ45的选型要点PHY出来之后不能直接接RJ45中间必须加网络变压器作用是隔离、滤波和阻抗匹配。选变压器时注意几个参数匝数比一般是1:1共模电感要够支持10/100M。常见的型号有HR911105A带变压器的RJ45座子用起来省事但要注意它的内部变压器质量参差不齐便宜的批次可能丢包。如果分开选变压器和RJ45座子变压器到RJ45的走线要尽量短差分对要等长阻抗控制在100欧姆。我试过用飞线接变压器结果丢包率飙升后来改成PCB走线就稳了。这个细节在调试阶段容易被忽略但影响很大。3. 时钟方案以太网稳定的命门3.1 REF_CLK的两种产生方式RMII的50MHz参考时钟有两种来源一种是PHY提供一种是STM32提供。这两种方式对应不同的硬件设计选错了就调不通。方式一PHY提供时钟。LAN8720A外接25MHz晶振内部PLL倍频到50MHz通过REF_CLK引脚输出给STM32的PA1。这种方式下STM32的PA1要配置成输入模式接收外部时钟。YT8512C也支持这种方式但要注意它的PLL配置寄存器可能需要初始化。方式二STM32提供时钟。STM32通过MCO引脚比如PA8输出50MHz给PHY的REF_CLK。这种方式下PHY不需要外部晶振但STM32的MCO配置要正确而且时钟精度要够。我实测下来STM32的MCO输出50MHz时抖动比专用晶振大长时间跑可能出现丢包所以更推荐方式一。3.2 时钟配置的实操步骤以LAN8720A提供时钟为例硬件上要确保LAN8720A的XTAL1和XTAL2接25MHz晶振负载电容按晶振规格选一般是12pF到22pFREF_CLK引脚接到STM32的PA1STM32的PA1配置为浮空输入或者复用输入不要配成输出软件上STM32的ETH外设要配置成RMII模式并且选择外部时钟源。在CubeMX里ETH的Clock source选External然后PA1会自动配置成输入。如果你用的是标准库要手动配置GPIO_Mode_IN和ETH_InitStructure.ETH_ClockSource ETH_ClockSource_External。注意有些开发板的原理图把REF_CLK标成PA1但实际连的是PA8的MCO输出这种板子要改硬件或者改软件配置别照着原理图死磕。3.3 时钟不稳导致的典型现象时钟问题最直接的表现就是ping不通或者丢包严重。具体来说完全ping不通PHY的link灯不亮可能是时钟根本没起来用示波器量REF_CLK看有没有50MHzlink灯亮但ping不通时钟频率不对比如是25MHz而不是50MHz能ping通但丢包率高时钟抖动大或者走线太长引入了干扰我遇到过一次REF_CLK的走线在PCB上绕了一大圈结果时钟信号边沿变缓PHY识别不稳定时好时坏。后来把走线改短问题消失。所以REF_CLK的走线要尽量短最好包地处理。4. 软件初始化流程与关键寄存器配置4.1 STM32 ETH外设初始化STM32的ETH外设初始化分几步GPIO配置、时钟使能、DMA描述符配置、MAC配置、PHY配置。这里重点讲容易出问题的部分。GPIO配置前面说过了关键是复用功能和模式要配对。时钟使能要注意ETH的时钟来自AHB总线使能ETH时钟之前要先使能SYSCFG时钟否则复用功能配不了。DMA描述符要放在内存里注意对齐。ETH的DMA描述符要求4字节对齐如果放在结构体里没对齐会出现DMA传输错误。我一般用__attribute__((aligned(4)))来强制对齐。MAC配置里最重要的是MII/RMII模式选择、速度设置、双工模式。RMII模式下ETH_InitStructure.ETH_Mode ETH_Mode_RMII速度先设成100M双工设成全双工后面PHY自协商成功后再根据结果调整。4.2 PHY寄存器读写与自协商PHY的配置通过MDIO/MDC接口读写寄存器。基本流程是先读PHY的ID寄存器地址2和3确认PHY型号和地址然后配置控制寄存器地址0启动自协商等待自协商完成读状态寄存器地址1确认link状态和速度。LAN8720A的PHY地址默认是0但可以通过PHYAD0引脚配置。如果板子上有多个PHY地址不能冲突。YT8512C的地址配置类似但具体引脚定义要看数据手册。自协商的过程需要时间一般几百毫秒到几秒。代码里要加超时判断不能死等。我见过有人写了个while循环等自协商完成结果PHY没接好程序卡死在那里看门狗都救不回来。// PHY自协商等待示例 uint32_t timeout 0; while (!(ETH_ReadPHYRegister(PHY_ADDRESS, PHY_BSR) PHY_Linked_Status)) { if (timeout 10000) { // 超时处理 break; } HAL_Delay(1); }4.3 LAN8720A的特殊配置LAN8720A有几个特殊寄存器需要配置。比如模式控制寄存器地址17要设置成RMII模式并且使能REF_CLK输出。如果这个寄存器没配PHY可能不输出50MHz时钟STM32就收不到时钟信号。另外LAN8720A的LED配置寄存器地址16可以控制link灯和速度灯的行为调试时可以把link灯配成常亮方便观察。YT8512C的寄存器基本兼容但有些扩展寄存器的地址不同。比如它的时钟配置寄存器可能不在标准地址上需要查数据手册。我建议在代码里把PHY型号检测做进去根据读到的ID选择不同的配置流程。5. 常见问题排查与避坑指南5.1 问题速查表现象可能原因排查方法PHY link灯不亮时钟没起来、电源不对、复位没释放量REF_CLK、量PHY电源、检查复位引脚link灯亮但ping不通时钟频率不对、MAC配置错误、IP冲突量时钟频率、检查MAC寄存器、换IP试能ping通但丢包时钟抖动、走线干扰、变压器质量差换晶振、改走线、换变压器PHY寄存器读回0xFFFFMDIO/MDC没配好、PHY地址错检查GPIO复用、扫描PHY地址发送正常接收异常CRS_DV接错、RXD引脚配错检查CRS_DV上拉、检查RXD复用长时间运行后断连时钟漂移、电源纹波大、散热问题换晶振、加滤波电容、改善散热5.2 几个典型的坑坑一REF_CLK走线太长。前面提过这个坑我踩过。PCB布局时REF_CLK要优先走线尽量短最好包地。如果实在走不开可以考虑用STM32提供时钟把时钟源放在STM32旁边。坑二PHY复位时间不够。LAN8720A的复位引脚需要至少100微秒的低电平有些板子的RC复位电路时间常数不够导致PHY没复位干净。可以在代码里加个延时或者改小复位电容。坑三MDIO上拉电阻缺失。MDIO是开漏输出需要上拉电阻一般是1.5k到10k。有些参考电路图省了这个电阻结果PHY寄存器读写不稳定。我一般用4.7k实测比较稳。坑四YT8512C替换LAN8720A时没改配置。虽然引脚兼容但YT8512C的PLL配置和LAN8720A不同直接替换可能不输出时钟。要查YT8512C的数据手册配置对应的寄存器。坑五网络变压器中心抽头没接对。变压器的中心抽头要接电源或者地具体看PHY的要求。LAN8720A的TX中心抽头接3.3VRX中心抽头接3.3V。YT8512C可能不同要查手册。接错了会导致信号幅度不对丢包严重。5.3 调试工具与技巧调试以太网示波器是必备的。量REF_CLK看频率和幅值量MDC看有没有时钟输出量TX_EN看发送时有没有使能。如果没有示波器可以用逻辑分析仪便宜的那种也能看个大概。软件层面可以写个PHY寄存器扫描程序把所有可能的PHY地址都读一遍看哪个地址能读到有效的ID。这个方法在不确定PHY地址时特别有用。另外STM32的ETH外设有中断和状态寄存器可以读DMA的状态看有没有传输错误。比如ETH_DMASR寄存器的错误位能告诉你DMA传输有没有出问题。6. 从LAN8720A切换到YT8512C的实操记录6.1 硬件改动的注意事项YT8512C和LAN8720A引脚兼容但外围电路有差异。YT8512C内置PLL可以不需要外部25MHz晶振直接用STM32提供的50MHz时钟。如果要用YT8512C的内部时钟要把它的时钟配置引脚拉对具体看数据手册。我最近一个项目就是从LAN8720A切到YT8512C硬件上把25MHz晶振拆了REF_CLK改成STM32的MCO输出。软件上改了PHY初始化部分YT8512C的自协商流程和LAN8720A基本一样但扩展寄存器要重新配。6.2 软件配置的差异点YT8512C的PHY ID和LAN8720A不同读ID寄存器能区分。初始化时先读ID如果是YT8512C走YT8512C的配置流程。主要差异在时钟配置和LED配置其他寄存器基本兼容。自协商完成后读状态寄存器确认link速度和双工模式。YT8512C的状态寄存器和LAN8720A的位定义基本一致可以直接用。6.3 切换后的实测结果切换后实测ping延迟和LAN8720A差不多丢包率在正常范围内。功耗方面YT8512C确实低一些发热也小。但要注意YT8512C的时钟配置如果不对会出现link灯亮但ping不通的情况这时候要重点查时钟。7. 一些实操心得与建议以太网调试这件事硬件和软件各占一半。我的经验是先确保硬件没问题再调软件。硬件上重点查时钟、电源、复位、MDIO上拉这几个点。软件上重点查GPIO复用、MAC配置、PHY自协商。另外不要迷信参考电路。我见过很多开发板的参考电路有问题比如REF_CLK走线太长、MDIO上拉电阻缺失、变压器中心抽头接错。照着抄不一定能跑要理解每个元件的作用。最后分享一个小技巧如果ping不通先别急着改代码用示波器量一下REF_CLK和MDC。这两个信号正常问题大概率在软件配置这两个信号不正常问题一定在硬件。这个判断方法帮我省了很多时间。
返回列表