The STM32F407 interacts with the Ethernet chip 83848 and uses an unplugged network cable, resulting in initialization failure and no connection.

Project scenario:

When debugging the project, I found that the Ethernet initialization failed when the STM32F407 drives the 83848 chip.


Problem Description:

The specific performance is: the board is powered on without plugging in the network cable, and after the program is running, it cannot be connected after plugging in the network cable. Plug in the network cable before power on and use it normally.


Cause Analysis:

After checking some online instructions, they all point to the initialization failure here.

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);
 }

The problem here is that the auto-negotiation mode is configured so that the speed cannot be set to 10M or 100M and the full-duplex or half-duplex mode.
insert image description here

As a result, the return value is 0, and the initialization fails.
insert image description here


solution:

solution:

  1. Re-initialize the network configuration by using the network cable plug-in interrupt. The advantage is that the auto-negotiation function is retained. The disadvantage is that it is more cumbersome and needs to write another initialization judgment program. I have tested several plug-in interrupts (without re-initialization), and probably only entered two or three interrupts and can no longer enter the interrupt. , Viewed the 83848 interrupt register, the interrupt enable is turned on. (It may also be that I have not configured some configurations well)

insert image description here
Use ETH_WritePHYRegister(uint16_t PHYAddress, uint16_t PHYReg, uint16_t PHYValue)the function to complete the writing of the 83848 chip control register, where the PHYReg is 0X11, and the PHYValue is 0X0003, so that the 83848INT pin is in interrupt mode and the output is enabled.
insert image description here
Use ETH_WritePHYRegister(uint16_t PHYAddress, uint16_t PHYReg, uint16_t PHYValue)the function to complete the writing of the 83848 chip interrupt status register, where the PHYReg is 0X12, and the PHYValue is 0X0020, so that the 83848 can send the INT pin interrupt level to trigger the STM32 interrupt through the connection status of the network cable. Then initialize in the STM32F4 interrupt (the program is not listed here, remember to configure the EXTI interrupt of the pin)
2. Directly change to the required setting mode. (The actual test is connected to the computer at 100M full duplex without pressure) The amount of change is very small. If you are worried that the connection speed is not enough, just set it to 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);
 }

Guess you like

Origin blog.csdn.net/weixin_43058521/article/details/121895044