本帖最后由 DKENNY 于 2025-5-20 14:10 编辑
#申请原创# #技术资源# @21小跑堂
前言
如果你是第一次接触以太网(Ethernet,简称ETH),尤其是用APM32F407单片机开发网络应用,可能会被一个名叫PHY的东西搞得晕头转向。文档里提到它,代码里配置它,硬件上还得接它,但它到底是个啥?为什么每次谈到以太网通信都绕不开PHY?
1、引言:PHY是个啥?为啥它这么重要?
这么说吧,假设以太网通信就像一座城市里的快递系统。你的程序(比如一个UDP包)是“货物”,APM32F407单片机是“物流中心”,而网线则是“高速公路”。货物要从物流中心送到客户手中,得经过一系列处理:打包、运输、送到目的地。这个过程中,PHY(Physical Layer,物理层)就像是负责把货物从数字世界(0和1)装上卡车、通过高速公路送到目的地的“司机”。
在APM32F407的以太网模块中,PHY是连接数字信号和物理世界(网线、光纤等)的关键组件。没有PHY,数据就没法通过网线传出去,也没法从网线收进来。简单来说,PHY是让以太网通信“落地”的核心部件,负责把数字信号变成电信号(或光信号),再反过来把电信号变回数字信号。
但PHY具体干了啥?它怎么跟APM32F407的以太网模块协作?为啥配置它那么麻烦?
2、PHY的定义:它到底是个啥?
PHY是Physical Layer的缩写,翻译成中文就是“物理层”。在以太网通信的OSI模型(七层网络模型)中,物理层是最低的一层,负责处理与物理介质(如网线、光纤)相关的信号传输。PHY的具体形式通常是一个独立的芯片(比如LAN8720、DP83825),或者集成在某些高级芯片内部。
简单来说,PHY就是一个“翻译官”:
- 发送时:把APM32F407的数字信号(0和1)翻译成网线能懂的电信号。
- 接收时:把网线传来的电信号翻译回数字信号,交给APM32F407处理。
PHY的工作有点像你家里的路由器和网线之间的“转换器”。没有它,数字世界和物理世界就没法对话。
2.1 PHY和MAC:一对好搭档
在以太网通信中,PHY总是跟另一个家伙——MAC(Media Access Control,介质访问控制)——形影不离。MAC和PHY就像一对好搭档,分别负责不同的任务:
- MAC:属于数据链路层,负责“打包”和“拆包”。它把数据加上地址、校验码,变成标准的以太网帧(Frame),或者把收到的帧拆开,交给上层处理。APM32F407的以太网模块内置了MAC功能。
- PHY:属于物理层,负责“运输”。它把MAC打包好的数据变成物理信号,送到网线,或者把网线上的信号变回数字数据,交给MAC。
我们可以说,MAC像快递公司的“打包员”,把货物(数据)装箱、贴标签;PHY像“司机”,开着卡车把箱子送到目的地。
图1:MAC与PHY的协作
3、PHY的作用:它具体干了啥?
要搞懂PHY的本质,我们得看看它在以太网通信中的具体作用。PHY的“活儿”可以分成三大块:信号转换、链路管理和接口通信。
3.1 信号转换:从数字到物理的“魔法”
PHY的核心任务是把数字信号和物理信号互相转换。这个过程听起来简单,但其实很复杂,涉及编码、调制和物理传输。
- 发送过程:
- APM32F407的MAC把数据(一串0和1)通过接口(比如MII或RMII)传给PHY。
- PHY把这些0和1编码成适合网线传输的信号。比如,在100Mbps以太网中,PHY会用4B/5B编码(4位数据编码成5位符号)和MLT-3调制(多级传输-3),把数据变成电信号。
- 这些电信号通过RJ45接口和网线发送出去。
- 接收过程:
- PHY从网线接收到电信号(可能是微弱的、带噪声的信号)。
- PHY解码信号(比如解MLT-3和4B/5B),还原成0和1。
- 还原后的数字数据通过MII/RMII接口传回MAC。
总的来说,PHY像个“信号翻译机”,把MAC的“ Morse 码”翻译成网线的“电波语言”,再把电波翻译回Morse 码。
3.2 链路管理:确保“高速公路”畅通
PHY不仅负责信号转换,还得确保网线这条“高速公路”是通畅的。这包括:
- 自动协商:PHY会跟对端的设备(比如路由器)“聊天”,商量用多快的速度(10Mbps还是100Mbps)和双工模式(全双工还是半双工)。
- 链路检测:PHY会检查网线是否插好,链路是否正常。如果网线断了,PHY会通知MAC“路断了,别发数据了”。
- 错误检测:PHY能检测到信号中的错误(比如噪声干扰),并通过特定信号(像RX_ER)告诉MAC。
总的来说,PHY像高速公路的“交警”,不仅负责运货,还得检查路况、协调交通规则。
3.3 接口通信:跟MAC的“对话”
PHY通过标准接口(MII、RMII等)跟MAC通信。这些接口定义了数据和控制信号的传输规则。常见的接口包括:
- MII:用18根信号线,数据宽度4位,时钟2.5/25MHz。
- RMII:用9根信号线,数据宽度2位,时钟50MHz。
PHY通过这些接口接收MAC的数据,发送自己的数据,或者通过管理接口(MDC/MDIO)接受MAC的配置指令。
总的来说,MII/RMII像MAC和PHY之间的“电话线”,他们通过这根线传递货物和指令。
4、PHY的工作原理:数据是怎么跑起来的?
现在我们知道PHY是个“翻译官+交警”,但它具体是怎么干活的?让我们以APM32F407和一个常见PHY芯片(比如LAN8720,RMII接口)为例,详细剖析PHY的工作原理。
4.1 PHY的内部结构
PHY芯片内部就像一个小型工厂,包含几个关键模块:
- 模拟前端(AFE):负责把数字信号变成模拟电信号,或者把模拟信号变回数字信号。AFE直接跟网线打交道。
- 数字信号处理器(DSP):处理编码、解码和错误校正,确保信号可靠。
- 时钟模块:生成或接收时钟信号(比如RMII的50MHz REF_CLK),同步数据传输。
- 寄存器组:存储PHY的配置(像速度、双工模式)和状态(像链路是否正常)。
- 接口模块:通过MII/RMII与MAC通信,通过MDC/MDIO接受配置。
图2:PHY内部结构
4.2 数据发送的过程
假设我们要用APM32F407发送一个UDP包,PHY是怎么把数据送到网线的?过程如下:
1. MAC准备数据:
- 你的程序生成一个UDP包(比如“Hello, World!”)。
- APM32F407的MAC把数据加上以太网帧头(目标地址、源地址等)和校验码,变成一个完整的数据帧。
- MAC通过RMII接口(以LAN8720为例)把数据传给PHY。
2. PHY接收数据:
- MAC把数据分成2位一组,通过TXD[1:0]发送给LAN8720。
- MAC同时置TX_EN为高,告诉PHY“有数据要发”。
- LAN8720在50MHz REF_CLK的上升沿采样TXD[1:0]上的数据。
3. PHY编码与调制:
- LAN8720的数字信号处理器把2位数据编码为5位符号(4B/5B编码),增加冗余以提高可靠性。
- 模拟前端把编码后的数据调制为MLT-3信号(一种三电平电信号),适合网线传输。
4. 信号发送:
- 调制后的电信号通过RJ45接口和网线发送到对端设备(比如路由器)。
图3:PHY发送时序(RMII)
4.3 数据接收的过程
现在反过来,假设路由器发来一个数据包,PHY是怎么接收的?
1. PHY接收信号:
- LAN8720通过RJ45接口从网线接收到电信号(MLT-3格式)。
- 模拟前端放大信号,去除噪声,解调为数字符号。
2. PHY解码:
- 数字信号处理器解码符号(5B/4B解码),还原成2位数据。
- 如果检测到错误(比如信号失真),PHY会通过RX_ER信号通知MAC。
3. PHY发送数据:
- LAN8720把2位数据放到RXD[1:0]上。
- 置CRS_DV为高,告诉MAC“有数据可收”。
- MAC在REF_CLK的上升沿采样RXD[1:0]上的数据。
4. MAC处理:
- APM32F407的MAC把数据拼凑成完整的数据帧,交给上层程序(比如LwIP协议栈)处理。
图4:PHY接收时序(RMII)
4.4 链路管理和自动协商
PHY还会跟对端设备“聊天”,确保通信顺畅。比如:
- 自动协商:LAN8720发送特殊的脉冲信号(Fast Link Pulse),跟对端商量速度和双工模式。结果存储在PHY的寄存器中,MAC可以通过MDC/MDIO读取。
- 链路状态:PHY不断检测网线是否连接。如果网线断了,PHY会更新状态寄存器,通知MAC。
可以这么理解,PHY像个“外交官”,一边运货,一边跟对端谈条件,确保双方用一样的“语言”和“速度”。
5、APM32F407中的PHY应用:怎么用它?
在APM32F407的以太网开发中,PHY通常是外部芯片(比如LAN8720或DP83825),通过MII或RMII接口与内置的MAC连接。以下是PHY在实际开发中的使用流程。而且Geehy官网的SDK是有ETH例程的,可以参考官方代码。
5.1 硬件连接
以LAN8720(RMII接口)为例,APM32F407和PHY的连接如下(不同版型可能不一样):
信号名
| APM32F407引脚
| LAN8720引脚
| 功能
| TXD0
| PB12
| TXD0
| 发送数据位0
| TXD1
| PB13
| TXD1
| 发送数据位1
| TX_EN
| PB11
| TX_EN
| 发送使能
| RXD0
| PC4
| RXD0
| 接收数据位0
| RXD1
| PC5
| RXD1
| 接收数据位1
| CRS_DV
| PA7
| CRS_DV
| 载波检测/数据有效
| REF_CLK
| PA1
| REF_CLK
| 50MHz参考时钟
| MDC
| PC1
| MDC
| 管理时钟
| MDIO
| PA2
| MDIO
| 管理数据
| 注意:
- LAN8720需要25MHz晶振提供时钟。
- RJ45接口需要带变压器,确保信号隔离和匹配。
图5:APM32F407与LAN8720连接
5.2 初始化PHY
在使用PHY之前,需要初始化APM32F407的MAC和LAN8720。步骤如下:
1. 使能时钟:
- 打开以太网MAC、GPIO和DMA的时钟。
- 确保LAN8720的电源和晶振正常。
2. 配置GPIO:
- 配置TXD[1:0]、TX_EN、MDC、MDIO为复用推挽输出。
- 配置RXD[1:0]、CRS_DV、REF_CLK为输入(或输出,视REF_CLK来源)。
3. 配置MAC:
- 设置RMII模式、速度(100Mbps)和双工模式(全双工)。
4. 配置PHY:
- 通过MDC/MDIO写入LAN8720的控制寄存器(比如地址0x00),设置速度和双工模式。
- 读取状态寄存器(地址0x01),确认链路状态。
代码示例:PHY初始化
#include "apm32f4xx_eth.h"
#include "apm32f4xx_gpio.h"
#include "apm32f4xx_rcm.h"
void PHY_Init(void)
{
GPIO_Config_T gpioConfig;
ETH_Config_T ethConfig;
// 使能时钟
RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_ETHMAC | RCM_AHB1_PERIPH_ETHMACTX | RCM_AHB1_PERIPH_ETHMACRX);
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA | RCM_APB2_PERIPH_GPIOB | RCM_APB2_PERIPH_GPIOC);
// 配置GPIO
gpioConfig.mode = GPIO_MODE_AF;
gpioConfig.speed = GPIO_SPEED_50MHz;
gpioConfig.outType = GPIO_OUT_TYPE_PP;
gpioConfig.pupd = GPIO_PUPD_NOPULL;
gpioConfig.pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
GPIO_Config(GPIOA, &gpioConfig);
gpioConfig.pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
GPIO_Config(GPIOB, &gpioConfig);
gpioConfig.pin = GPIO_PIN_4 | GPIO_PIN_5;
GPIO_Config(GPIOC, &gpioConfig);
GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_1, GPIO_AF_ETH); // REF_CLK
GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_2, GPIO_AF_ETH); // MDIO
// ... 其他引脚复用配置
// 配置MAC
ethConfig.mode = ETH_MODE_FULLDUPLEX;
ethConfig.speed = ETH_SPEED_100M;
ethConfig.interface = ETH_INTERFACE_RMII;
ETH_Config(ðConfig);
// 配置LAN8720
ETH_WritePHYRegister(0x00, 0x00, 0x3100); // 100Mbps,全双工
ETH_Start();
}
5.3 数据收发
数据收发的过程在第四节已经详细讲解,这里总结一下:
- 发送:MAC通过TXD[1:0]和TX_EN发送数据,PHY编码后通过网线发送。
- 接收:PHY解码网线信号,通过RXD[1:0]和CRS_DV传给MAC。
代码示例:数据收发
void ETH_SendPacket(uint8_t* data, uint32_t len)
{
ETH_TxDescriptor_T txDesc;
txDesc.buffer1Addr = (uint32_t)data;
txDesc.length = len;
DAL_ETH_Transmit(&txDesc);
}
void ETH_ReceivePacket(uint8_t* buffer, uint32_t* len)
{
ETH_RxDescriptor_T rxDesc;
if (DAL_ETH_Receive(&rxDesc) == DAL_OK)
{
*len = rxDesc.length;
memcpy(buffer, (uint8_t*)rxDesc.buffer1Addr, *len);
}
}
结合全文,PHY负责信号转换、链路管理和接口通信,它的存在让以太网通信变得可能。
6、本文参考资料
- APM32F407用户手册
- LAN8720数据手册
- DP83825数据手册
- IEEE 802.3标准
- LwIP协议栈文档
|
图文并茂,并借助APM32F407的代码实现,解开以太网中PHY的神秘面纱。文章详略得当,关键点清晰,读者容易理解,整体较佳!