
使用stm32f407zgt6的RMII接口驱动LAN8720的一些踩过的坑
硬件设计

在硬件设计完毕,打板回来,焊接完毕,供电之后,插上网线,在没有写驱动代码的情况下,网口的绿灯会保持常亮,橙色灯会不停的闪烁,如果看到这个现象,就基本没什么问题
软件设计
直接使用stm32cubeMX生成对应的驱动程序,关于参数的配置
用的软件版本 在之后的版本在配置eth会多一个步骤,并且不能直接在软件中配置phy地址

ETH设置参数

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

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


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


其他基本不用改,直接用就可以了
// 搭配一些打印信息 如果通信成功,那么读取的寄存器的值不会是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, ®value); printf("PHY_BCR %d: %X\r\n", PHY_BCR, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, PHY_BSR, ®value); printf("PHY_BSR %d: %X\r\n", PHY_BSR, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 2, ®value); printf("PHY 1 %d: %X\r\n", 2, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 3, ®value); printf("PHY2 %d: %X\r\n", 3, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 4, ®value); printf(" %d: %X\r\n", 4, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 5, ®value); printf(" %d: %X\r\n", 5, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 6, ®value); printf(" %d: %X\r\n", 6, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 17, ®value); printf(" %d: %X\r\n", 17, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 18, ®value); printf(" %d: %X\r\n", 18, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 26, ®value); printf(" %d: %X\r\n", 26, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 27, ®value); printf(" %d: %X\r\n", 27, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 29, ®value); printf(" %d: %X\r\n", 29, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 30, ®value); printf(" %d: %X\r\n", 30, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 31, ®value); printf(" %d: %X\r\n-------------------------------------------\r\n", 31, (unsigned int) regvalue);在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, ®value); printf("PHY_BCR %d: %X\r\n", PHY_BCR, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, PHY_BSR, ®value); printf("PHY_BSR %d: %X\r\n", PHY_BSR, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 2, ®value); printf("PHY 1 %d: %X\r\n", 2, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 3, ®value); printf("PHY2 %d: %X\r\n", 3, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 4, ®value); printf(" %d: %X\r\n", 4, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 5, ®value); printf(" %d: %X\r\n", 5, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 6, ®value); printf(" %d: %X\r\n", 6, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 17, ®value); printf(" %d: %X\r\n", 17, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 18, ®value); printf(" %d: %X\r\n", 18, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 26, ®value); printf(" %d: %X\r\n", 26, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 27, ®value); printf(" %d: %X\r\n", 27, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 29, ®value); printf(" %d: %X\r\n", 29, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 30, ®value); printf(" %d: %X\r\n", 30, (unsigned int) regvalue); HAL_ETH_ReadPHYRegister(&heth, 31, ®value); 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 */ }在ETH硬件初始化中添加复位代码

一些可能的问题
代码驱动方面,就是直接使用cubeMx生成,然后像上面代码中写的,就可以直接使用,然后在电脑端直接就可以ping通
所以如果不行的话,有很大的几率是硬件上没有连接好,检测一下lan8720A的晶振还有传给stm32的ref_clk信号,看看是不是信号都对,有一个很重要的,就是MDIO信号一定要上拉,不然通信肯定有问题,之前焊接一个10欧姆的电阻,导致插上网线,可以绿色常亮,橙色闪烁,但是,读取到的寄存器的值全都是0xffff,上拉电阻太小不行!!
#好好学习!