PHY ID读取异常:无法识别芯片型号
说实话,遇到PHY ID读不出来,很多新手第一反应就是换芯片。但我跟你说,这事儿没那么简单。我做了这么多年车载网络,碰上PHY ID异常的次数还真不少,大部分时候都是外围电路或者配置的问题。
你想想看,MCU通过MDIO总线去读PHY的寄存器,如果读回来全是0xFFFF或者0x0000,那基本上就是通信链路出了问题。如果读回来是个奇怪的数值,比如0x0080之类的,那可能是芯片地址配错了。
核心要点:正常情况下,PHY的ID寄存器(寄存器2和3)会返回芯片厂商和型号的唯一标识。读不到正确值,就等于MCU和PHY之间“失联”了。
常见的几种现象
我在项目中遇到过这么几种情况,你可以对照看看:
- 读回0xFFFF:MDIO总线没通,或者PHY根本没上电
- 读回0x0000:PHY复位没出来,芯片处于复位状态
- 读回重复的某个值:地址冲突,总线上挂了多个相同地址的PHY
- 有时能读有时不能:时序问题,或者电源不稳
排查第一步:看硬件
我个人的习惯是,先拿示波器抓三个信号:电源、时钟、复位。
为什么先看这个?因为这三个是PHY工作的基础条件,缺一个都不行。
| 信号 | 检查要点 | 常见问题 |
|---|---|---|
| 电源 | 电压值是否在规格内 | 纹波太大,PHY不工作 |
| 时钟 | 频率和幅度是否达标 | 晶振不起振或频率偏差大 |
| 复位 | 复位时序是否满足要求 | 复位拉低时间不够 |
嗯,这里有个坑。有一回我排查一个项目,电源和时钟都对,复位也正常,但就是读不到ID。折腾了半天才发现——PHY的复位引脚和MCU的GPIO之间有个RC延时电路,电容值选大了,导致复位释放时间超出了MDIO通信的窗口期。说白了,复位虽然拉高了,但MCU已经等不及开始读寄存器了。
排查第二步:检查MDIO接口
如果上述三个信号都正常,那就轮到MDIO总线了。我建议按这个顺序来:
- 测上拉电阻:MDIO是漏极开路,必须有上拉。一般来说1.5kΩ到10kΩ都行,具体看总线负载
- 测地址配置引脚:PHY的地址通常由几个硬件引脚决定,比如AD0、AD1、AD2。用万用表量一下电平对不对
- 测波形时序:用示波器看MDC时钟和MDIO数据是否对齐
特别注意:有些PHY支持通过strap引脚配置地址和模式,如果这些引脚没正确上拉或下拉,PHY可能会进入test mode,这时候ID寄存器返回的值就不对了。我曾经碰到过一块板子,AD0引脚虚焊,结果PHY地址变成了0x1F,和MCU配置的0x01对不上,读了一晚上都是乱码。
排查第三步:检查软件配置
硬件没问题之后,咱们得看看软件那边。我见过太多人硬件排查半天,最后发现是代码里写错了PHY地址。
- 地址匹配:检查代码里用的地址和硬件strap配置的是不是同一个
- 帧格式:确认MDIO帧的起始码、操作码、地址位对不对。IEEE 802.3的规范里,读操作是“01 10 + PHY_ADDR + REG_ADDR”,写操作是“01 01 + PHY_ADDR + REG_ADDR”
- 时序延迟:有些MCU的MDIO控制器需要设置时钟分频,如果频率太快,PHY跟不上
// 典型的PHY ID读取代码(C语言示例)
uint32_t phy_read_id(uint8_t phy_addr) {
uint16_t reg2 = mdio_read(phy_addr, 0x02); // 读取ID低16位
uint16_t reg3 = mdio_read(phy_addr, 0x03); // 读取ID高16位
return ((uint32_t)reg3 << 16) | reg2;
}
你看,代码很简单。但问题往往出在mdio_read这个函数的实现上。我之前见过有人把MDC时钟周期设成了40ns,结果PHY最高只能跑到25ns,时序就对不上了。
进阶排查方法
如果以上都查过了还是不行,那我建议你用逻辑分析仪抓一下MDIO总线。把波形导出来,手动解析每一帧,看看MCU发出去的数据对不对,PHY返回的数据又是什么。
举个实际例子:我有个项目,PHY ID读回来固定是0x0000。用逻辑分析仪一看,MCU发的帧完全正确,但PHY根本没有应答。后来查datasheet才发现,这颗PHY有个隐藏的pin叫INT_N,如果这个脚被拉低,芯片就不响应MDIO。嗯,板子上刚好有个测试点把它短路到地了。
一个小技巧:如果怀疑地址冲突,可以试着手动修改PHY的strap跳线,换一个地址试试。如果换地址后能读到ID,那基本可以确定是原来的地址被别的设备占用了。
避坑指南
- 有些PHY在上电后需要一段时间才能准备好,MCU别急着去读。加个100ms延时
- 注意MDIO总线上的电容负载,线太长或者挂的设备太多,波形会变形
- 不同厂商的PHY对MDIO时序要求不一样,比如Broadcom的某些芯片需要更长的保持时间
- 如果你用FPGA做MDIO控制器,注意状态机的设计,我曾经遇到过因为状态机少跳了一步,导致读回来的数据总差一位
最后,总结一下PHY ID读不到的排查逻辑,我画了个流程图,你一看就明白了:
嗯,以上就是PHY ID读取异常的整套排查思路。说白了,大部分问题都出在硬件基础和通信链路上,先把这些基础打牢了,再去看软件。按照这个流程走一遍,八成的问题都能定位到。