最近因为做的项目出了BUG,STM32 单片机在未接网线的状态下,上电一段时间后,将网线插入网口后,IP地址ping不通,网络模块无法正常使用,重启一下程序就没问题了。
这次的问题查找全靠网友,把问题扔给百度,然后就能看见一大群网友的评论,都反馈有 LAN8720 在没有接网线的情况下上电后,插入网线,网络模块无法正常工作,然后就有大佬些评论回复,我看的我觉得比较靠谱的一个回答如下图:
我觉得讲的蛮有道理的,然后就通过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