×

关于ETH以太网在stm32f407zgt6上驱动lan8720A的问题

zxjy辉 zxjy辉 发表于2025-07-20 20:23:04 浏览366 评论0

抢沙发发表评论

摄影图片-摄影照片-摄影作品免费下载-设图网

使用stm32f407zgt6的RMII接口驱动LAN8720的一些踩过的坑


  1. 硬件设计

    image.png

    在硬件设计完毕,打板回来,焊接完毕,供电之后,插上网线,在没有写驱动代码的情况下,网口的绿灯会保持常亮,橙色灯会不停的闪烁,如果看到这个现象,就基本没什么问题

  2. 软件设计

    直接使用stm32cubeMX生成对应的驱动程序,关于参数的配置

    1. 用的软件版本 在之后的版本在配置eth会多一个步骤,并且不能直接在软件中配置phy地址

      image.png

    2. ETH设置参数

      image.png

      需要注意你硬件上设置lan8720A的地址

      image.png

      注意你实际连接的引脚,如果不一样,要改

      image.png

      image.png

      这个PHY选择LAN8742A就可以了,其他不用改

    3. lwip设置

      image.png

      image.png

      其他基本不用改,直接用就可以了

    4. // 搭配一些打印信息 如果通信成功,那么读取的寄存器的值不会是0xffff,如果读取到这个值,说明通信失败,要检查硬件是否连接无误
      uint32_t regvalue;
          printf("F429IG LWIP LAN8720A %s\r\n", __TIME__);
      	printf("LAN8742A_PHY_ADDRESS %d \r\n", LAN8742A_PHY_ADDRESS);
      	HAL_ETH_ReadPHYRegister(&heth, PHY_BCR, &regvalue);
      	printf("PHY_BCR %d: %X\r\n", PHY_BCR, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  PHY_BSR, &regvalue);
      	printf("PHY_BSR %d: %X\r\n", PHY_BSR, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  2, &regvalue);
      	printf("PHY 1 %d: %X\r\n", 2, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  3, &regvalue);
      	printf("PHY2 %d: %X\r\n", 3, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  4, &regvalue);
      	printf(" %d: %X\r\n", 4, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  5, &regvalue);
      	printf(" %d: %X\r\n", 5, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth, 6, &regvalue);
      	printf(" %d: %X\r\n", 6, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  17, &regvalue);
      	printf(" %d: %X\r\n", 17, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth, 18, &regvalue);
      	printf(" %d: %X\r\n", 18, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth, 26, &regvalue);
      	printf(" %d: %X\r\n", 26, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  27, &regvalue);
      	printf(" %d: %X\r\n", 27, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  29, &regvalue);
      	printf(" %d: %X\r\n", 29, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  30, &regvalue);
      	printf(" %d: %X\r\n", 30, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  31, &regvalue);
      	printf(" %d: %X\r\n-------------------------------------------\r\n", 31,
      			(unsigned int) regvalue);
    5. 在cubeMX生成代码之后,在主程序中,添加代码
      int main(void)
      {
        /* USER CODE BEGIN 1 */
      
        /* USER CODE END 1 */
      
        /* MCU Configuration--------------------------------------------------------*/
      
        /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
        HAL_Init();
      
        /* USER CODE BEGIN Init */
      uint32_t regvalue;
        /* USER CODE END Init */
      
        /* Configure the system clock */
        SystemClock_Config();
      
        /* USER CODE BEGIN SysInit */
      
        /* USER CODE END SysInit */
      
        /* Initialize all configured peripherals */
        MX_GPIO_Init();
        MX_LWIP_Init();
        MX_USART3_UART_Init();
      
      
      	HAL_Delay(500);
      printf("F429IG LWIP LAN8720A %s\r\n", __TIME__);
      	printf("LAN8742A_PHY_ADDRESS %d \r\n", LAN8742A_PHY_ADDRESS);
      	HAL_ETH_ReadPHYRegister(&heth, PHY_BCR, &regvalue);
      	printf("PHY_BCR %d: %X\r\n", PHY_BCR, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  PHY_BSR, &regvalue);
      	printf("PHY_BSR %d: %X\r\n", PHY_BSR, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  2, &regvalue);
      	printf("PHY 1 %d: %X\r\n", 2, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  3, &regvalue);
      	printf("PHY2 %d: %X\r\n", 3, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  4, &regvalue);
      	printf(" %d: %X\r\n", 4, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  5, &regvalue);
      	printf(" %d: %X\r\n", 5, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth, 6, &regvalue);
      	printf(" %d: %X\r\n", 6, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  17, &regvalue);
      	printf(" %d: %X\r\n", 17, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth, 18, &regvalue);
      	printf(" %d: %X\r\n", 18, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth, 26, &regvalue);
      	printf(" %d: %X\r\n", 26, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  27, &regvalue);
      	printf(" %d: %X\r\n", 27, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  29, &regvalue);
      	printf(" %d: %X\r\n", 29, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  30, &regvalue);
      	printf(" %d: %X\r\n", 30, (unsigned int) regvalue);
      	HAL_ETH_ReadPHYRegister(&heth,  31, &regvalue);
      	printf(" %d: %X\r\n-------------------------------------------\r\n", 31,
      			(unsigned int) regvalue);
      			
      //			pbuff[0]= 'g';
      ////			pbuff[1]= 'g';
      //			
      //			printf("sram data = %s",pbuff);
      //			
      			
      			
      			
      			
        /* USER CODE END 2 */
      
        /* Infinite loop */
        /* USER CODE BEGIN WHILE */
        while (1)
        {
          /* USER CODE END WHILE */
      
          /* USER CODE BEGIN 3 */
      		MX_LWIP_Process();  // 这个是必须的,千万别忘了
      		HAL_Delay(100);
      //		HAL_GPIO_WritePin(LED_GREEN_GPIO_Port,LED_GREEN_Pin,GPIO_PIN_RESET);
      		HAL_GPIO_WritePin(LED_BLUE_GPIO_Port,LED_BLUE_Pin,GPIO_PIN_SET);
      		HAL_Delay(100);
      //		HAL_GPIO_WritePin(LED_GREEN_GPIO_Port,LED_GREEN_Pin,GPIO_PIN_SET);
      		HAL_GPIO_WritePin(LED_BLUE_GPIO_Port,LED_BLUE_Pin,GPIO_PIN_RESET);
      		
        }
        /* USER CODE END 3 */
      }
    6.  在ETH硬件初始化中添加复位代码

      image.png

  3. 一些可能的问题

    代码驱动方面,就是直接使用cubeMx生成,然后像上面代码中写的,就可以直接使用,然后在电脑端直接就可以ping通

    所以如果不行的话,有很大的几率是硬件上没有连接好,检测一下lan8720A的晶振还有传给stm32的ref_clk信号,看看是不是信号都对,有一个很重要的,就是MDIO信号一定要上拉,不然通信肯定有问题,之前焊接一个10欧姆的电阻,导致插上网线,可以绿色常亮,橙色闪烁,但是,读取到的寄存器的值全都是0xffff,上拉电阻太小不行!!

#好好学习!

群贤毕至

访客