STM32踩坑:LAN8720未接网线,上电后再接网线,网络模块无法正常使用

LAN8720未接网线,上电后再接网线,网络模块无法正常使用

一、问题描述

最近因为做的项目出了BUG,STM32 单片机在未接网线的状态下,上电一段时间后,将网线插入网口后,IP地址ping不通,网络模块无法正常使用,重启一下程序就没问题了。

二、问题查找

这次的问题查找全靠网友,把问题扔给百度,然后就能看见一大群网友的评论,都反馈有 LAN8720 在没有接网线的情况下上电后,插入网线,网络模块无法正常工作,然后就有大佬些评论回复,我看的我觉得比较靠谱的一个回答如下图:
STM32踩坑:LAN8720未接网线,上电后再接网线,网络模块无法正常使用_第1张图片

三、问题解决

我觉得讲的蛮有道理的,然后就通过LAN8720芯片的某个寄存器位,做了个热插拔功能,如果检测到不存在网线,则不初始化网络模块,直到检测到网线,再开始初始化网络,刚开始测试的时候,因为程序和板子不匹配,所以ping的时候延迟有点大,然后我也没找到这延迟大的问题,一直以为实现热插拔的逻辑有问题,考虑了好几种可能性,问题一直没得到解决,后面试了下和程序匹配的开发板,我勒个去,没问题,这会儿我才意识到是程序不匹配的问题,这里分享一下热插拔的模块代码。

四、源码分享

//lan8720.c
u8 LAN8720_Get_Link() {
	u8 status;
	
	status = ((ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, PHY_BSR) & PHY_Linked_Status) >> 2);

	return status;
}
//server.c
void server_init()
{
	int i = 0;
	u8 status;

	if(!last_status) {
		LAN8720_Init();
	}

	status = LAN8720_Get_Link();

	if(status == 1) {
		//网络初始化,这里省略千万行代码
		......

		server_start();
	}
		
	last_status = 0;
}

void server_start()
{
	ETH_MACAddressConfig(ETH_MAC_Address0, mjipdev.mac);        //向STM32F4的MAC地址寄存器中写入MAC地址
	ETH_DMATxDescChainInit(DMATxDscrTab, Tx_Buff, ETH_TXBUFNB);
	ETH_DMARxDescChainInit(DMARxDscrTab, Rx_Buff, ETH_RXBUFNB);

	ETH_Start(); //开启MAC和DMA
}

void server_online_chk() {
	u8 status = LAN8720_Get_Link();

	if(status == 0x01 && last_status == 0x00) {
		server_init();
	}
	else if(status == 0x00 && last_status == 0x01) {
		ETH_Stop();
	}

	last_status = status;
}

最后在 main 函数的 while 循环中调用 server_online_chk() 函数即可!

学习分享,一起成长!以上为小编的经验分享,若存在不当之处,请批评指正!

感谢来自于网友的经验分享,小编这里稍微整理了一下有分享给大家下面是参考博文:
《STM32移植LWIP网线热插入网络不通的解决办法》
https://blog.csdn.net/xukao5671927/article/details/77765464

你可能感兴趣的:(STM32学习,stm32,嵌入式硬件,单片机)