stm32_LAN8720驱动

一、驱动代码

#include "lan8720.h"
#include "stm32f4x7_eth.h"
#include "usart.h" 
#include "delay.h"
#include "malloc.h" 


ETH_DMADESCTypeDef *DMARxDscrTab;	//以太网DMA接收描述符数据结构体指针
ETH_DMADESCTypeDef *DMATxDscrTab;	//以太网DMA发送描述符数据结构体指针 
uint8_t *Rx_Buff; 					//以太网底层驱动接收buffers指针 
uint8_t *Tx_Buff; 					//以太网底层驱动发送buffers指针
  
static void ETHERNET_NVICConfiguration(void);
//LAN8720初始化
//返回值:0,成功;
//    其他,失败
u8 LAN8720_Init(void)
{
	u8 rval=0;
	GPIO_InitTypeDef GPIO_InitStructure;
  
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOG|RCC_AHB1Periph_GPIOD, ENABLE);//使能GPIO时钟 RMII接口
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);   //使能SYSCFG时钟
  
	SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII); //MAC和PHY之间使用RMII接口

	/*网络引脚设置 RMII接口
	  ETH_MDIO -------------------------> PA2
	  ETH_MDC --------------------------> PC1
	  ETH_RMII_REF_CLK------------------> PA1
	  ETH_RMII_CRS_DV ------------------> PA7
	  ETH_RMII_RXD0 --------------------> PC4
	  ETH_RMII_RXD1 --------------------> PC5
	  ETH_RMII_TX_EN -------------------> PG11
	  ETH_RMII_TXD0 --------------------> PG13
	  ETH_RMII_TXD1 --------------------> PG14
	  ETH_RESET-------------------------> PD3*/
					
	  //配置PA1 PA2 PA7
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	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_PinSource1, GPIO_AF_ETH); //引脚复用到网络接口上
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH);

	//配置PC1,PC4 and PC5
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH); //引脚复用到网络接口上
	GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH);
	GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH);
                                
	//配置PG11, PG14 and PG13 
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_14;
	GPIO_Init(GPIOG, &GPIO_InitStructure);
	GPIO_PinAFConfig(GPIOG, GPIO_PinSource11, GPIO_AF_ETH);
	GPIO_PinAFConfig(GPIOG, GPIO_PinSource13, GPIO_AF_ETH);
	GPIO_PinAFConfig(GPIOG, GPIO_PinSource14, GPIO_AF_ETH);
	
	//配置PD3为推完输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	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);
	
	LAN8720_RST=0;					//硬件复位LAN8720
	delay_ms(50);	
	LAN8720_RST=1;				 	//复位结束 
	ETHERNET_NVICConfiguration();	//设置中断优先级
	rval=ETH_MACDMA_Config();		//配置MAC及DMA
	return !rval;					//ETH的规则为:0,失败;1,成功;所以要取反一下 
}

//以太网中断分组配置
void ETHERNET_NVICConfiguration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	
	NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn;  //以太网中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0X00;  //中断寄存器组2最高优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0X00;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}


//得到8720的速度模式
//返回值:
//001:10M半双工
//101:10M全双工
//010:100M半双工
//110:100M全双工
//其他:错误.
u8 LAN8720_Get_Speed(void)
{
	u8 speed;
	speed=((ETH_ReadPHYRegister(0x00,31)&0x1C)>>2); //从LAN8720的31号寄存器中读取网络速度和双工模式
	return speed;
}
/
//以下部分为STM32F407网卡配置/接口函数.

//初始化ETH MAC层及DMA配置
//返回值:ETH_ERROR,发送失败(0)
//		ETH_SUCCESS,发送成功(1)
u8 ETH_MACDMA_Config(void)
{
	u8 rval;
	ETH_InitTypeDef ETH_InitStructure; 
	
	//使能以太网MAC以及MAC接收和发送时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | RCC_AHB1Periph_ETH_MAC_Tx |RCC_AHB1Periph_ETH_MAC_Rx, ENABLE);
                        
	ETH_DeInit();  								//AHB总线重启以太网
	ETH_SoftwareReset();  						//软件重启网络
	while (ETH_GetSoftwareResetStatus() == SET);//等待软件重启网络完成 
	ETH_StructInit(&ETH_InitStructure); 	 	//初始化网络为默认值  

	///网络MAC参数设置 
	ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;   			//开启网络自适应功能
	ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;					//关闭反馈
	ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable; 		//关闭重传功能
	ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable; 	//关闭自动去除PDA/CRC功能 
	ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable;						//关闭接收所有的帧
	ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;//允许接收所有广播帧
	ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;			//关闭混合模式的地址过滤  
	ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;//对于组播地址使用完美地址过滤   
	ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;	//对单播地址使用完美地址过滤 
#ifdef CHECKSUM_BY_HARDWARE
	ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable; 			//开启ipv4和TCP/UDP/ICMP的帧校验和卸载   
#endif
	//当我们使用帧校验和卸载功能的时候,一定要使能存储转发模式,存储转发模式中要保证整个帧存储在FIFO中,
	//这样MAC能插入/识别出帧校验值,当真校验正确的时候DMA就可以处理帧,否则就丢弃掉该帧
	ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable; //开启丢弃TCP/IP错误帧
	ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;     //开启接收数据的存储转发模式    
	ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;   //开启发送数据的存储转发模式  

	ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;     	//禁止转发错误帧  
	ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable;	//不转发过小的好帧 
	ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable;  		//打开处理第二帧功能
	ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;  	//开启DMA传输的地址对齐功能
	ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable;            			//开启固定突发功能    
	ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat;     		//DMA发送的最大突发长度为32个节拍   
	ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat;			//DMA接收的最大突发长度为32个节拍
	ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1;
	rval=ETH_Init(&ETH_InitStructure,LAN8720_PHY_ADDRESS);		//配置ETH
	if(rval==ETH_SUCCESS)//配置成功
	{
		ETH_DMAITConfig(ETH_DMA_IT_NIS|ETH_DMA_IT_R,ENABLE);  	//使能以太网接收中断	
	}
	return rval;
}

extern void lwip_pkt_handle(void);		//在lwip_comm.c里面定义
//以太网DMA接收中断服务函数
void ETH_IRQHandler(void)
{
	while(ETH_GetRxPktSize(DMARxDescToGet)!=0) 	//检测是否收到数据包
	{ 
		lwip_pkt_handle();		
	}
	ETH_DMAClearITPendingBit(ETH_DMA_IT_R); 	//清除DMA中断标志位
	ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);	//清除DMA接收中断标志位
}  
//接收一个网卡数据包
//返回值:网络数据包帧结构体
FrameTypeDef ETH_Rx_Packet(void)
{ 
	u32 framelength=0;
	FrameTypeDef frame={0,0};   
	//检查当前描述符,是否属于ETHERNET DMA(设置的时候)/CPU(复位的时候)
	if((DMARxDescToGet->Status&ETH_DMARxDesc_OWN)!=(u32)RESET)
	{	
		frame.length=ETH_ERROR; 
		if ((ETH->DMASR&ETH_DMASR_RBUS)!=(u32)RESET)  
		{ 
			ETH->DMASR = ETH_DMASR_RBUS;//清除ETH DMA的RBUS位 
			ETH->DMARPDR=0;//恢复DMA接收
		}
		return frame;//错误,OWN位被设置了
	}  
	if(((DMARxDescToGet->Status&ETH_DMARxDesc_ES)==(u32)RESET)&& 
	((DMARxDescToGet->Status & ETH_DMARxDesc_LS)!=(u32)RESET)&&  
	((DMARxDescToGet->Status & ETH_DMARxDesc_FS)!=(u32)RESET))  
	{       
		framelength=((DMARxDescToGet->Status&ETH_DMARxDesc_FL)>>ETH_DMARxDesc_FrameLengthShift)-4;//得到接收包帧长度(不包含4字节CRC)
 		frame.buffer = DMARxDescToGet->Buffer1Addr;//得到包数据所在的位置
	}else framelength=ETH_ERROR;//错误  
	frame.length=framelength; 
	frame.descriptor=DMARxDescToGet;  
	//更新ETH DMA全局Rx描述符为下一个Rx描述符
	//为下一次buffer读取设置下一个DMA Rx描述符
	DMARxDescToGet=(ETH_DMADESCTypeDef*)(DMARxDescToGet->Buffer2NextDescAddr);   
	return frame;  
}
//发送一个网卡数据包
//FrameLength:数据包长度
//返回值:ETH_ERROR,发送失败(0)
//		ETH_SUCCESS,发送成功(1)
u8 ETH_Tx_Packet(u16 FrameLength)
{   
	//检查当前描述符,是否属于ETHERNET DMA(设置的时候)/CPU(复位的时候)
	if((DMATxDescToSet->Status&ETH_DMATxDesc_OWN)!=(u32)RESET)return ETH_ERROR;//错误,OWN位被设置了 
 	DMATxDescToSet->ControlBufferSize=(FrameLength&ETH_DMATxDesc_TBS1);//设置帧长度,bits[12:0]
	DMATxDescToSet->Status|=ETH_DMATxDesc_LS|ETH_DMATxDesc_FS;//设置最后一个和第一个位段置位(1个描述符传输一帧)
  	DMATxDescToSet->Status|=ETH_DMATxDesc_OWN;//设置Tx描述符的OWN位,buffer重归ETH DMA
	if((ETH->DMASR&ETH_DMASR_TBUS)!=(u32)RESET)//当Tx Buffer不可用位(TBUS)被设置的时候,重置它.恢复传输
	{ 
		ETH->DMASR=ETH_DMASR_TBUS;//重置ETH DMA TBUS位 
		ETH->DMATPDR=0;//恢复DMA发送
	} 
	//更新ETH DMA全局Tx描述符为下一个Tx描述符
	//为下一次buffer发送设置下一个DMA Tx描述符 
	DMATxDescToSet=(ETH_DMADESCTypeDef*)(DMATxDescToSet->Buffer2NextDescAddr);    
	return ETH_SUCCESS;   
}
//得到当前描述符的Tx buffer地址
//返回值:Tx buffer地址
u32 ETH_GetCurrentTxBuffer(void)
{  
  return DMATxDescToSet->Buffer1Addr;//返回Tx buffer地址  
}

//为ETH底层驱动申请内存
//返回值:0,正常
//    其他,失败
u8 ETH_Mem_Malloc(void)
{ 
	DMARxDscrTab=mymalloc(SRAMIN,ETH_RXBUFNB*sizeof(ETH_DMADESCTypeDef));//申请内存
	DMATxDscrTab=mymalloc(SRAMIN,ETH_TXBUFNB*sizeof(ETH_DMADESCTypeDef));//申请内存  
	Rx_Buff=mymalloc(SRAMIN,ETH_RX_BUF_SIZE*ETH_RXBUFNB);	//申请内存
	Tx_Buff=mymalloc(SRAMIN,ETH_TX_BUF_SIZE*ETH_TXBUFNB);	//申请内存
	if(!DMARxDscrTab||!DMATxDscrTab||!Rx_Buff||!Tx_Buff)
	{
		ETH_Mem_Free();
		return 1;	//申请失败
	}	
	return 0;		//申请成功
}

//释放ETH 底层驱动申请的内存
void ETH_Mem_Free(void)
{ 
	myfree(SRAMIN,DMARxDscrTab);//释放内存
	myfree(SRAMIN,DMATxDscrTab);//释放内存
	myfree(SRAMIN,Rx_Buff);		//释放内存
	myfree(SRAMIN,Tx_Buff);		//释放内存  
}

二、硬件连接方式

2.1 STM32以太网接口引脚:

这些引脚是STM32微控制器上用于以太网通信的复用功能(AF11)引脚,下面我将分类详细介绍它们的作用:

  • 数据发送引脚

引脚信号名称作用描述
PB12/PG13ETH_MII_TXD0/ETH_RMII_TXD0发送数据位0(最低有效位)
PB13/PG14ETH_MII_TXD1/ETH_RMII_TXD1发送数据位1
PC2ETH_MII_TXD2MII发送数据位2(仅MII模式使用)
PB8/PE2ETH_MII_TXD3MII发送数据位3(仅MII模式使用)
  • 数据接收引脚

引脚信号名称作用描述
PC4ETH_MII_RXD0/ETH_RMII_RXD0接收数据位0(最低有效位)
PC5ETH_MII_RXD1/ETH_RMII_RXD1接收数据位1
PB0/PH6ETH_MII_RXD2MII接收数据位2(仅MII模式使用)
PB1/PH7ETH_MII_RXD3MII接收数据位3(仅MII模式使用)
  •  控制信号引脚

引脚信号名称作用描述
PB11/PG11ETH_MII_TX_EN/ETH_RMII_TX_EN发送使能信号,高电平表示正在发送数据
PA7ETH_MII_RX_DV/ETH_RMII_CRS_DVMII模式:接收数据有效<br>RMII模式:载波侦听/接收数据有效
PB10/PI10ETH_MII_RX_ER接收错误指示,高电平表示接收过程中检测到错误
  •  时钟信号

引脚信号名称作用描述
PA1ETH_MII_RX_CLK接收时钟(由PHY提供,25MHz@100Mbps,2.5MHz@10Mbps)
PC3ETH_MII_TX_CLK发送时钟(由PHY提供,25MHz@100Mbps,2.5MHz@10Mbps)
  •  冲突检测

引脚信号名称作用描述
PA0/PH2ETH_MII_CRS载波侦听,表示信道被占用(半双工模式)
PA3/PH3ETH_MII_COL冲突检测,表示检测到冲突(半双工模式)
  •  RMII专用引脚

引脚信号名称作用描述
PA1ETH_RMII_REF_CLK50MHz参考时钟(必须由外部PHY或晶振提供)
  •  管理接口引脚

引脚信号名称作用描述
PA2ETH_MDIO管理数据输入输出,用于配置PHY寄存器
PC1ETH_MDC管理数据时钟,由MAC产生(最高2.5MHz)

 2.2 LAN8720 接线

	  ETH_MDIO -------------------------> PA2
	  ETH_MDC --------------------------> PC1
	  ETH_RMII_REF_CLK------------------> PA1
	  ETH_RMII_CRS_DV ------------------> PA7
	  ETH_RMII_RXD0 --------------------> PC4
	  ETH_RMII_RXD1 --------------------> PC5
	  ETH_RMII_TX_EN -------------------> PG11
	  ETH_RMII_TXD0 --------------------> PG13
	  ETH_RMII_TXD1 --------------------> PG14
	  ETH_RESET-------------------------> PD3*/

  2.3 配置顺序

电源和复位配置​

​电源上电顺序​

​VDDIO​​(1.6V–3.6V)、​​VDD1A/VDD2A​​(3.0V–3.6V)需在 ​​50 ms​​ 内达到标称电压(±10%容差)

​VDDCR​​(1.2V):

  • 若使用内部稳压器(默认):由VDD2A通过内部LDO生成,无需外部供电。
  • 若禁止内部稳压器(REGOFF=1):需在VDDIO达到80%后,再提供外部1.2V(±5%)。
复位信号(nRST)​
  • ​复位脉冲宽度​​:至少保持低电平 ​​100 μs​​(trstia)。
  • ​释放时机​​:所有电源稳定后,延迟 ​​25 ms​​(tpurstd)再拉高nRST。

关键配置脚锁存​

配置脚在 ​​nRST上升沿​​ 时锁存,需在复位前稳定电平:

PHY地址配置(PHYAD0)​
  • ​引脚​​:RXER/PHYAD0(引脚10)
  • ​功能​​:设置SMI管理接口的PHY地址(0或1)。
  • ​配置方式​​:
    • 拉低(下拉电阻):PHY地址=0(默认)。
    • 拉高(上拉电阻至VDDIO):PHY地址=1。
工作模式(MODE[2:0])​
  • ​引脚​​:
    • RXD0/MODE0(引脚8)
    • RXD1/MODE1(引脚7)
    • CRS_DV/MODE2(引脚11)
  • ​配置方式​​:通过外部电阻组合设置(见下表):
MODE[2:0]模式描述典型应用
00010BASE-T半双工,禁止自动协商固定10M半双工
111自动协商全功能(默认)支持10/100M全/半双工
110掉电模式低功耗待机

 时钟配置​

晶振模式(推荐)​
  • ​连接​​:
    • XTAL1(引脚5):接25 MHz晶振。
    • XTAL2(引脚4):接晶振另一端,并联负载电容(如20 pF)。
  • ​注意​​:晶振需满足±50 ppm精度。
外部时钟模式​
  • ​连接​​:
    • XTAL1/CLKIN(引脚5):输入25 MHz(REF_CLK输出模式)或50 MHz(REF_CLK输入模式)时钟。
    • XTAL2(引脚4):悬空。

RMII接口配置​

  • ​REF_CLK模式选择​​:
    • ​输入模式​​(nINTSEL=1):MAC提供50 MHz时钟至XTAL1/CLKIN
    • ​输出模式​​(nINTSEL=0):PHY生成50 MHz时钟至REFCLKO(需连接MAC的CLK输入)。
  • ​信号连接​​:
    • TXD[1:0](引脚17-18)、TXEN(引脚16):MAC发送数据。
    • RXD[1:0](引脚7-8)、CRS_DV(引脚11):MAC接收数据。

配置顺序总结​

  • ​电源上电​​:确保VDDIO、VDD1A/VDD2A、VDDCR(若外部)稳定。
  • ​配置脚设置​​:在nRST拉低前,通过电阻设置PHYAD0、MODE[2:0]、REGOFF、nINTSEL。
  • ​复位释放​​:保持nRST低电平≥100 μs后拉高,锁存配置。
  • ​时钟初始化​​:晶振/外部时钟需在复位完成后稳定运行。
  • ​RMII接口​​:根据nINTSEL选择时钟模式,连接MAC接口。

三、MAC 层驱动配置(stm32f4x7_eth_conf.h)

#ifndef __STM32F4x7_ETH_CONF_H
#define __STM32F4x7_ETH_CONF_H
#include "stm32f4xx.h"

#define USE_ENHANCED_DMA_DESCRIPTORS

//这个 stm32f4x7_eth_conf.h 文件是 STM32F4 系列芯片在使用 LwIP 协议栈时,针对以太网外设(ETH)的硬件抽象层配置文件。

//如果使用自己定义的延时函数的话就注销掉下面一行代码,否则使用
//默认的低精度延时函数

//#define USE_Delay    	//使用默认延时函数,因此注销掉
#ifdef USE_Delay
	#include "main.h"               
	#define _eth_delay_    Delay     //Delay为用户自己提供的高精度延时函数
                                    
#else
	#define _eth_delay_    ETH_Delay //默认的_eth_delay功能函数延时精度差
#endif

#ifdef  CUSTOM_DRIVER_BUFFERS_CONFIG
	//重新定义以太网接收和发送缓冲区的大小和数量
	#define ETH_RX_BUF_SIZE    ETH_MAX_PACKET_SIZE //接收缓冲区的大小
	#define ETH_TX_BUF_SIZE    ETH_MAX_PACKET_SIZE //发送缓冲区的大小
	#define ETH_RXBUFNB        20                  //接收缓冲区数量
	#define ETH_TXBUFNB        5                   //发送缓冲区数量
#endif

//*******************PHY配置块*******************
#ifdef USE_Delay
	#define PHY_RESET_DELAY    ((uint32_t)0x000000FF)  	//PHY复位延时
	#define PHY_CONFIG_DELAY   ((uint32_t)0x00000FFF) 	//PHY配置延时
	#define ETH_REG_WRITE_DELAY ((uint32_t)0x00000001)	//向以太网寄存器写数据时的延时
#else
	#define PHY_RESET_DELAY    ((uint32_t)0x000FFFFF)	//PHY复位延时     0x000FFFFF 是一个较大的数值(约 1,048,575 个时钟周期)
	#define PHY_CONFIG_DELAY   ((uint32_t)0x00FFFFFF)	//PHY配置延时     0x00FFFFFF(约 16,777,215 个时钟周期)比复位延时更长,用于确保配置(如速度/双工模式)生效。
	#define ETH_REG_WRITE_DELAY ((uint32_t)0x0000FFFF)	//向以太网寄存器写数据时的延时
#endif

//LAN8720 PHY芯片的状态寄存器
#define PHY_SR				((uint16_t)31) 		//LAN8720的PHY状态寄存器地址
#define PHY_SPEED_STATUS    ((uint16_t)0x0004) 	//LAN8720 PHY速度值掩码
#define PHY_DUPLEX_STATUS   ((uint16_t)0x00010) //LAN8720 PHY连接状态值掩码  
#endif 


其中包含和stm32 MAC控制器对PHY的配置信息

3.1 延时函数配置

	#define PHY_RESET_DELAY    ((uint32_t)0x000FFFFF)	
	#define PHY_CONFIG_DELAY   ((uint32_t)0x00FFFFFF)
	#define ETH_REG_WRITE_DELAY ((uint32_t)0x0000FFFF)

其中((uint32_t)0x000FFFFF)代表时钟数,表示延时0x000FFFFF个时钟

3.2 PHY状态寄存器配置

#define PHY_SR				((uint16_t)31) 		
#define PHY_SPEED_STATUS    ((uint16_t)0x0004) 	
#define PHY_DUPLEX_STATUS   ((uint16_t)0x00010)   

其中PHY_SR = ((uint16_t)31) 是根据LAN8720数据手册得出,PHY_SPEED_STATUS  和PHY_DUPLEX_STATUS   是提取PHY状态寄存器具体位的掩码如下表。

PHY_SR 寄存器 BIT位

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值