LAN8720A是一个10/100M 的以太网PHY芯片。带有SMI接口,支持RMII。
MDIO MDC是站管理接口(SMI接口)引脚。SMI是标准接口,比如交换机芯片一般都有此接口。MCU通过这两条线可以访问PHY的寄存器。比如STM32F407的以太网外设有站管理功能,直接接到对应MCU的功能引脚上,如果MCU没有此功能就需要通过模拟时序来实现。
RXD0 RXD1 是RMII接口的接收数据信号线。PHY芯片启动完成后是接收信号线,PHY启动时是MODE信号线。
TXD0 TXD1 是RMII发送数据信号线。TXEN是发送使能信号线。注意:RXD0、RXD1、TXD0、TXD1的T和R是相对于MAC内核说的。
RXER/PHYAD0 PHY启动的时引脚是PHYAD0功能,PHY会读取PHYAD0管脚的信号,决定PHY的地址,默认内部下拉,下拉PHY的地址是0,上拉PHY的地址是1。启动完成后该引脚是RXER信号(接收错误信号)。在RMII接口中没有使用到此信号线。
CRS_DV/MODE2 载波侦听信号引脚。PHY启动时是MODE功能,启动完成后是CRS_DV功能。当物理层接收到载波信号后,CRS_DV会变得有效,当载波信号消失后,CRS_DV会变得无效。
nRST 是复位信号,低电平有效。
RBIAS固定接一个12.1K的电阻到GND。
LED1/REGOFF。PHY启动时是REGOFF功能,PHY会读取REGOFF的电平,为低电平时内部调节器打开。为高电平时内部调节器关闭。 PHY启动完成后是连接指示灯,连接的时候高低电平变化。
LED2/nINTSEL。PHY启动时是nINTSEL功能,PHY会读取nINTSEL的电平。低电平时,nINT/REFCLKO是REFCLKO功能,会输出时钟信号给MAC;高电平时,nINT/REFCLKO是nINT功能,会输出中断信号给MAC。PHY启动完成后是速度指示灯,用来指示100M/10M。 100M连接时输出高电平,10M连接时输出低电平。
我手里使用的时探索者V2开发板。LED1/REGOFF引脚下拉,打开内部调节器。LED2/nINTSEL引脚下拉,设置nINT/REFCLKO引脚是REFCLKO功能,会输出时钟信号给MAC;
TXP、TXN是发送信号的差分线,RXP、RXN是接收信号的差分线。
LAN8720具有自动极性翻转功能。因为支持自动极性翻转功能,所以使用交叉网线和直连网线都可以通讯。TX、RX是相对PHY本身来说的。比如W5500芯片就不支持自动极性翻转功能,如果两个W5500通过网线连接(不通过交换机转换),那么必须使用交叉网线。使用交叉网线相当于自己的TX接到了对方的RX。直插网线相当于TX接TX,RX接RX,两端都不支持极性翻转的情况下无法通讯。想一想这种情况:两个人嘴巴对着嘴巴说,耳朵对着耳朵听。
注意3个MODE复用引脚默认带有内部上拉,3个MODE引脚都上拉是全功能,启动自协商。
void lan8720_pin_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD,ENABLE);
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); //使能SYSCFG时钟
// SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII); //MAC和PHY之间使用RMII接口
//MDIO PA2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH);
//MDC PC1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH);
//RESET PD3
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
void lan8720_init(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC,ENABLE);//使能MAC内核时钟
GPIO_ResetBits(GPIOD,GPIO_Pin_3);
delay_ms(50);
GPIO_SetBits(GPIOD,GPIO_Pin_3);
delay_ms(50);
}
reg_value = ETH_ReadPHYRegister(0,31);
printf("reg_value=%04x\r\n",reg_value);
delay_ms(500);