STM32F407与以太网芯片83848交互使用未插网线导致初始化失败再也连接不上问题

项目场景:

在调试项目时发现STM32F407驱动83848芯片时以太网初始化失败问题。


问题描述:

具体表现为:板子上电不插网线,等程序跑起来后再插入网线怎么也连接不上。上电前插入网线使用正常。


原因分析:

查了一些网上说明都是指向了此处初始化失败。

static void ETH_MACDMA_Config(void)
 {
    
    
  /* Enable ETHERNET clock */
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC |
   RCC_AHB1Periph_ETH_MAC_Tx|RCC_AHB1Periph_ETH_MAC_Rx,ENABLE);
   ...//此处省去一大串代码
   /*-------------------- MAC ----------------------------*/
 /* 开启网络自适应功能,速度和工作模式无需配置*/
   ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;
  // ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Disable;
  // ETH_InitStructure.ETH_Speed = ETH_Speed_10M;
  // ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;
    ...//此处省去一大串代码
 ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;
   EthStatus = ETH_Init(&ETH_InitStructure, ETHERNET_PHY_ADDRESS);
 }

问题在这里配置了自动协商模式导致无法设置速度是10M还是100M以及全双工还是半双工模式。
在这里插入图片描述

从而导致返回值为0,初始化失败。
在这里插入图片描述


解决方案:

解决方案:

  1. 利用网线插拔中断重新去初始化网络配置。好处是保留了自动协商功能,不好的地方在于比较繁琐还需要另写初始化判断程序,实测了几次插拔中断(不重新初始化),大概只进入了两三次中断再也进不去中断了,查看了83848中断寄存器,中断使能是打开的。(也可能是有些配置我没配置好)

在这里插入图片描述
使用ETH_WritePHYRegister(uint16_t PHYAddress, uint16_t PHYReg, uint16_t PHYValue)函数完成83848芯片控制寄存器的写入,这里PHYReg为0X11,PHYValue为0X0003 使得83848INT引脚为中断模式并使能输出。
在这里插入图片描述
使用ETH_WritePHYRegister(uint16_t PHYAddress, uint16_t PHYReg, uint16_t PHYValue)函数完成83848芯片中断状态寄存器的写入,这里PHYReg为0X12,PHYValue为0X0020 使得83848能够通过网线的连接状态发送INT引脚中断电平触发STM32中断。然后再STM32F4中断中进行初始化(此处程序不列出来了,记得配置好引脚的EXTI中断)
2. 直接改为需求的设置模式。(实测与电脑连接100M全全双工无压力)改动量很小,如果担心对接设配速率不够的话直接设置成10M就好了

static void ETH_MACDMA_Config(void)
 {
    
    
  /* Enable ETHERNET clock */
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC |
   RCC_AHB1Periph_ETH_MAC_Tx|RCC_AHB1Periph_ETH_MAC_Rx,ENABLE);
   ...//此处省去一大串代码
   /*-------------------- MAC ----------------------------*/
 /* 关闭网络自适应功能*/
   ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Disable;
   ETH_InitStructure.ETH_Speed = ETH_Speed_100M;//如果担心对接设配速率不够的话直接设置成ETH_Speed_10M就好了
   ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;
    ...//此处省去一大串代码
 ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;
   EthStatus = ETH_Init(&ETH_InitStructure, ETHERNET_PHY_ADDRESS);
 }

猜你喜欢

转载自blog.csdn.net/weixin_43058521/article/details/121895044