本帖最后由 DKENNY 于 2025-5-22 15:22 编辑
#技术资源# #申请原创# @21小跑堂
前言
接上文讲了PHY的原理,也以LAN8720(RMII)为例,实现了一些伪代码,我们知道以太网通信是嵌入式系统中连接世界的“高速公路”,而APM32F407单片机就像一个高效的“交通指挥中心”,通过其内置的以太网MAC模块,与外部PHY芯片(如LAN8720和DP83825)协作,完成数据的收发任务。
在这篇文章中,我们将以LAN8720(RMII协议)和DP83825(MII协议)为例,深入讲解这两种接口的通信过程,涵盖原理、时序、代码实现。
1、背景:为什么要用LAN8720和DP83825?
- LAN8720:一款常用的RMII接口PHY芯片,支持10Mbps和100Mbps速率,引脚少、设计简单,适合资源受限的嵌入式系统。
- DP83825:一款支持MII接口的PHY芯片,同样支持10Mbps和100Mbps,信号线多但功能全面,适合需要高可靠性的场景。
MII和RMII作为MAC与PHY之间的“桥梁”,决定了数据如何在这两者间高效传递。LAN8720用RMII协议,引脚少、设计紧凑;DP83825用MII协议,信号丰富、可靠性高。接下来,我们将详细剖析这两种模式的通信过程,带你看清数据在“高速公路”上是如何跑起来的!
2、MII与RMII通信原理:从“大路”到“窄路”的区别
在深入通信过程之前,我们先搞清楚MII和RMII的原理和区别。
2.1 MII:宽敞的“四车道高速公路”
MII(Media Independent Interface,介质无关接口)就像一条宽敞的四车道高速公路,专门为MAC和PHY之间传递数据设计。它的特点是:
- 数据宽度:每次传输4位数据(用TXD[3:0]发送,RXD[3:0]接收)。
- 时钟信号:用两个独立的时钟——TX_CLK(发送时钟)和RX_CLK(接收时钟)。10Mbps时钟频率是2.5MHz,100Mbps是25MHz。
- 信号线多:总共需要18根信号线,包括数据线、控制线(像TX_EN、RX_DV)和管理线(MDC、MDIO)。
MII的优点是传输稳定,适合需要高可靠性的场景,比如工业控制。但缺点也很明显:信号线多,占用了很多引脚,PCB布线也更复杂。
MII就像一条宽路,每次能跑四辆车(4位数据),但需要很多车道(18根线),修路成本高。
2.2 RMII:高效的“双车道快车道”
RMII(Reduced Media Independent Interface,精简介质无关接口)是MII的“瘦身版”,像一条双车道快车道,通过优化设计减少了引脚需求。它的特点是:
- 数据宽度:每次只传输2位数据(TXD[1:0]发送,RXD[1:0]接收)。
- 时钟信号:用一个统一的50MHz参考时钟(REF_CLK),取代MII的两个时钟,发送和接收都靠这个时钟同步。
- 信号线少:总共只需要9根信号线,合并了部分控制信号(如CRS和RX_DV合并为CRS_DV)。
RMII通过提高时钟频率(50MHz)和减少数据位宽,实现了与MII相同的传输效率,同时大大降低了引脚数,适合引脚资源紧张的嵌入式系统。
相比MII来说,RMII像一条窄路,每次只能跑两辆车(2位数据),但车速快(50MHz),车道少(9根线),修路成本低。
3、LAN8720(RMII)通信过程:数据在“双车道”上如何跑?
LAN8720是一款典型的RMII接口PHY芯片,广泛用于嵌入式以太网设计。我们以APM32F407和LAN8720的组合为例,详细讲解RMII通信的整个过程,从初始化到数据收发,再到时序分析。
3.1 RMII通信的硬件连接
在RMII模式下,APM32F407的MAC通过9根信号线与LAN8720连接。以下是典型的引脚分配:
信号名
| APM32F407引脚
| LAN8720引脚
| 功能
| TXD0
| PB12
| TXD0
| 发送数据位0
| TXD1
| PB13
| TXD1
| 发送数据位1
| TX_EN
| PB11
| TX_EN
| 发送使能,告诉PHY有数据要发
| RXD0
| PC4
| RXD0
| 接收数据位0
| RXD1
| PC5
| RXD1
| 接收数据位1
| CRS_DV
| PA7
| CRS_DV
| 载波检测/数据有效,告诉MAC有数据可收
| REF_CLK
| PA1
| REF_CLK
| 50MHz参考时钟,同步发送和接收
| MDC
| PC1
| MDC
| 管理时钟,用于配置PHY
| MDIO
| PA2
| MDIO
| 管理数据,读写PHY寄存器
| 注意:
- REF_CLK可以由LAN8720提供(通过其内部晶振),也可以由外部50MHz晶振或APM32F407的时钟输出提供。
- LAN8720还需要连接RJ45接口(带变压器)和25MHz晶振(用于其内部时钟)。
3.2 RMII通信的初始化流程
在数据传输之前,APM32F407需要初始化以太网MAC和LAN8720。初始化就像“修好高速公路并设置交通规则”,主要步骤如下:
1. 使能时钟:
- 打开APM32F407的以太网MAC、GPIO和DMA的时钟。
- 确保LAN8720的电源和25MHz晶振正常工作。
2. 配置GPIO引脚:
- 将TXD0、TXD1、TX_EN、MDC、MDIO配置为复用推挽输出。
- 将RXD0、RXD1、CRS_DV配置为输入。
- REF_CLK根据时钟源配置为输入或输出。
3. 配置MAC:
- 设置RMII模式(通过ETH_MACCR寄存器)。
- 配置速度(100Mbps或10Mbps)和双工模式(全双工或半双工)。
- 使能DMA传输。
4. 配置LAN8720:
- 通过MDC和MDIO接口,写入LAN8720的寄存器,设置速度、双工模式和自动协商。
- 读取LAN8720的状态寄存器,确认链路已建立。
5. 启动通信:
- 使能MAC的发送和接收功能,准备好数据缓冲区。
代码示例:RMII初始化
#include "apm32f4xx_eth.h"
#include "apm32f4xx_gpio.h"
#include "apm32f4xx_rcm.h"
void RMII_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();
}
3.3 RMII发送数据的通信过程
假设APM32F407要发送一个数据包(比如一个UDP包),RMII的发送过程就像“把货物装上卡车,通过双车道送到目的地”。具体步骤如下:
1. 准备数据:
- 应用程序(比如LwIP协议栈)生成一个数据包,存储在内存中。
- MAC的DMA控制器将数据从内存搬到TX缓冲区。
2. 通知发送:
- MAC把数据分成2位一组,依次放到TXD[1:0]上。
- 同时置TX_EN为高,告诉LAN8720“有数据要发”。
3. 数据传输:
- LAN8720在REF_CLK的上升沿采样TXD[1:0]上的2位数据。
- 因为RMII每次只传2位,而MII一次传4位,所以RMII用50MHz的REF_CLK,速度快一倍,保证传输效率。
- 数据传输完成后,MAC置TX_EN为低,表示发送结束。
4. PHY处理:
- LAN8720将收到的数字数据编码为物理信号(比如曼彻斯特编码),通过RJ45接口发送到网线。
3.4 RMII接收数据的通信过程
接收过程就像“从网线收到货物,通过双车道运回仓库”。具体步骤如下:
1. PHY接收信号:
- LAN8720从网线接收物理信号,解码为数字数据。
- 数据被分成2位一组,准备通过RXD[1:0]发送给MAC。
2. 通知接收:
- LAN8720置CRS_DV为高,表示“有数据可收”或“链路有信号”。
- 数据被放到RXD[1:0]上。
3. 数据传输:
- MAC在REF_CLK的上升沿采样RXD[1:0]上的2位数据。
- 每2位数据需要一个50MHz时钟周期,MAC将数据拼凑成完整的数据包。
4. 存储数据:
- MAC的DMA控制器将接收到的数据搬到RX缓冲区。
- 应用程序读取缓冲区数据,完成接收。
3.5 RMII的管理接口(MDC/MDIO)
除了数据传输,MAC还需要通过MDC和MDIO配置LAN8720或读取其状态。比如:
- 设置LAN8720为100Mbps全双工模式。
- 检查链路是否连接(通过读取状态寄存器)。
过程:
- MDC提供1-2.5MHz的时钟信号。
- MDIO传输数据帧,包含操作码(读/写)、PHY地址、寄存器地址和数据。
- 比如,写入LAN8720的控制寄存器(地址0x00)值为0x3100,设置100Mbps全双工。
代码示例:MDIO配置
void ConfigureLAN8720(void)
{
// 设置100Mbps,全双工
ETH_WritePHYRegister(0x00, 0x00, 0x3100);
// 读取状态寄存器
uint16_t status;
ETH_ReadPHYRegister(0x00, 0x01, &status);
if (status & 0x0004) {
printf("Link is up!\n");
}
}
4、DP83825(MII)通信过程:数据在“四车道”上如何跑?
DP83825是一款MII接口PHY芯片,信号线多但功能全面。同样的,我们以APM32F407和DP83825为例,讲解MII通信的完整过程。
4.1 MII通信的硬件连接
MII模式需要18根信号线,APM32F407与DP83825的引脚分配如下:
信号名
| APM32F407引脚
| LAN8720引脚
| 功能
| TXD0
| PG13
| TXD0
| 发送数据位0
| TXD1
| PG14
| TXD1
| 发送数据位1
| TXD2
| PC2
| TXD2
| 发送数据位2
| TXD3
| PB8
| TXD3
| 发送数据位3
| TX_EN
| PG11
| TX_EN
| 发送使能,告诉PHY有数据要发
| TXCLK
| PC3
| TXCLK
| 发送时钟(2.5/25MHz)
| RXD0
| PC4
| RXD0
| 接收数据位0
| RXD1
| PC5
| RXD1
| 接收数据位1
| RXD2
| PH6
| RXD2
| 接收数据位2
| RXD3
| PH7
| RXD3
| 接收数据位3
| RX_DV
| PA7
| RX_DV
| 接收数据有效
| RX_CLK
| PA1
| RX_CLK
| 接收时钟(2.5/25MHz)
| RX_ER
| PI10
| RX_ER
| 接收错误
| CRS
| PH2
| CRS
| 载波检测/数据有效,告诉MAC有数据可收
| COL
| PH3
| COL
| 冲突检测
| MDC
| PC1
| MDC
| 管理时钟,用于配置PHY
| MDIO
| PA2
| MDIO
| 管理数据,读写PHY寄存器
| 注意:
- TX_CLK和RX_CLK由DP83825提供,频率根据速率(10Mbps为2.5MHz,100Mbps为25MHz)。
- DP83825还需要25MHz晶振和RJ45接口。
4.2 MII通信的初始化流程
MII的初始化与RMII类似,但需要配置更多引脚和设置MII模式。步骤如下:
1. 使能时钟:
- 打开以太网MAC、GPIO和DMA时钟。
- 确保DP83825的电源和晶振正常。
2. 配置GPIO引脚:
- 配置TXD[3:0]、TX_EN、MDC、MDIO为复用推挽输出。
- 配置RXD[3:0]、RX_DV、RX_CLK、CRS、COL为输入。
3. 配置MAC:
- 设置MII模式(ETH_MACCR寄存器)。
- 配置速度和双工模式。
4. 配置DP83825:
- 通过MDC/MDIO设置速度、双工模式和自动协商。
5. 启动通信:
- 使能MAC的发送和接收。
代码示例:MII初始化
#include "apm32f4xx_eth.h"
#include "apm32f4xx_gpio.h"
#include "apm32f4xx_rcm.h"
void MII_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_8;
GPIO_Config(GPIOB, &gpioConfig);
// ... 其他引脚初始化配置
GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_1, GPIO_AF_ETH); // RX_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_MII;
ETH_Config(ðConfig);
// 配置DP83825
ETH_WritePHYRegister(0x00, 0x00, 0x3100); // 设置100Mbps,全双工
ETH_Start();
}
4.3 MII发送数据的通信过程
MII的发送过程就像“用四车道大卡车运送货物”。步骤如下:
1. 准备数据:
- 应用程序生成数据包,DMA将数据搬到TX缓冲区。
2. 通知发送:
- MAC将数据分成4位一组,放到TXD[3:0]上。
- 置TX_EN为高,通知DP83825开始发送。
3. 数据传输:
- DP83825在TX_CLK的上升沿采样TXD[3:0]上的4位数据。
- TX_CLK由DP83825提供,100Mbps时为25MHz。
- 发送完成后,MAC置TX_EN为低。
4. PHY处理:
- DP83825将数据编码为物理信号,发送到网线。
4.4 MII接收数据的通信过程
MII的接收过程就像“从网线收到货物,用四车道运回”。步骤如下:
1. PHY接收信号:
- DP83825从网线接收信号,解码为4位数据。
2. 通知接收:
- DP83825置RX_DV为高,表示数据有效。
- 将4位数据放到RXD[3:0]上。
3. 数据传输:
- MAC在RX_CLK的上升沿采样RXD[3:0]上的4位数据。
- RX_CLK由DP83825提供,100Mbps时为25MHz。
4. 存储数据:
- DMA将数据搬到RX缓冲区,应用程序读取。
4.5 MII的管理接口(MDC/MDIO)
与RMII类似,MII也通过MDC和MDIO配置DP83825,过程相同,不再赘述。
5、MII与RMII的对比:LAN8720 vs DP83825
通过LAN8720和DP83825的通信过程,我们可以总结两者的差异:
特性
| LAN8720(RMII)
| DP83825(MII)
| 数据宽度
| 2位(TXD[1:0], RXD[1:0])
| 4位(TXD[3:0], RXD[3:0])
| 时钟
| 单一50MHz REF_CLK
| 两个时钟(TX_CLK, RX_CLK,25MHz)
| 信号线数量
| 9根
| 18根
| 引脚需求
| 少,适合小型封装
| 多,适合引脚充足的芯片
| PCB布线
| 简单,但REF_CLK需严格阻抗匹配
| 复杂,信号线多需避免干扰
| 适用场景
| 成本敏感、引脚受限的系统
| 高可靠性、支持半双工的系统
|
总结上文,
- LAN8720(RMII)就像一辆轻便的快递车,跑得快(50MHz),占道少(9根线),适合短途快速送货。
- DP83825(MII)就像一辆重型卡车,载货多(4位/周期),占道多(18根线),适合长途稳定运输。
6、调试与常见问题
在实际开发中,RMII和MII通信可能会遇到问题。以下是常见问题和解决办法:
1. 问题:无法ping通:
- RMII:检查REF_CLK是否为50MHz,LAN8720的晶振是否正常。
- MII:检查TX_CLK和RX_CLK是否正确输出(用示波器测量)。
- 确认PHY地址和寄存器配置是否正确。
2. 问题:数据包丢失:
- RMII:检查REF_CLK布线是否过长,添加33Ω串联电阻。
- MII:确保TXD/RXD信号线等长,减少信号偏差。
3. 问题:链路未建立:
- 检查MDC/MDIO时序,确认PHY寄存器是否正确配置。
- 检查RJ45接口和网线连接。
7、总结
通过对LAN8720(RMII)和DP83825(MII)的通信过程的详细剖析,我们从硬件连接、初始化、数据收发到时序分析,全面揭开了以太网通信的“神秘面纱”。RMII以其高效和低引脚数的优势,适合成本敏感的嵌入式系统;MII则以高可靠性和全面的功能,适合复杂场景。
|
条理清晰,深度讲解RMII和MII协议的两种接口的通信过程,从原理、时序到代码实现,逐步深入,重点描述清晰,关键点涵盖精准,质量较佳。