STM32F429+LAN8720A网络通信保姆级教程:从CubeMX配置到LWIP Ping通(含IO扩展芯片驱动)

张开发
2026/6/21 20:35:21 15 分钟阅读
STM32F429+LAN8720A网络通信保姆级教程:从CubeMX配置到LWIP Ping通(含IO扩展芯片驱动)
STM32F429与LAN8720A以太网开发实战从CubeMX配置到LWIP调通全流程解析第一次接触STM32以太网开发时面对PHY芯片、RMII接口、LWIP协议栈这些陌生概念不少开发者都会感到无从下手。本文将用最直白的语言带你一步步完成STM32F429与LAN8720A的以太网通信实现。不同于简单的流程罗列我会重点分享那些容易踩坑的细节——比如为什么PHY地址要设为0、如何用IO扩展芯片控制PHY复位、LWIP初始化时IP地址丢失怎么办等实际问题。1. 硬件环境搭建与原理图解析拿到STM32F429开发板和LAN8720A模块后第一步不是急着写代码而是要彻底理解硬件连接方式。LAN8720A作为PHY芯片负责将MAC层的数字信号转换为网线中的模拟信号它与STM32F429通过RMII接口通信。这种接口相比传统的MII接口引脚数量减少了一半但需要更高的时钟频率。关键引脚连接对照表LAN8720A引脚STM32F429引脚功能说明ETH_MDIOPA2管理数据输入输出ETH_MDCPC1管理数据时钟RMII_TXD0PG13发送数据线0RMII_TXD1PG14发送数据线1RMII_TX_ENPB11发送使能RMII_RXD0PC4接收数据线0RMII_RXD1PC5接收数据线1RMII_CRS_DVPA7载波侦听/数据有效RMII_REF_CLKPA150MHz参考时钟特别注意开发板上如果使用了PCF8574这类IO扩展芯片来控制PHY复位引脚需要在原理图中确认具体连接的是哪个IO位。比如在我的开发板上PHY复位连接的是PCF8574的P7引脚。2. CubeMX工程配置详解打开STM32CubeMX新建工程时选择正确的STM32F429型号。时钟配置是整个工程的基础以太网外设对时钟要求严格建议按以下步骤操作时钟树配置外接HSE晶振通常8MHzPLL配置输出180MHz系统时钟确保ETH时钟为25MHz来自PLL输出分频ETH外设配置// 在CubeMX中依次设置 // 1. 激活ETH外设 // 2. 选择RMII接口模式 // 3. PHY地址设为0LAN8720A的默认地址 // 4. 在Advanced Parameters中指定PHY名称为LAN8720AFreeRTOS集成在Middleware选项卡中激活FreeRTOS将HAL库的Timebase Source从SysTick改为其他定时器如TIM2堆栈大小建议设置为1024字根据实际需求调整LWIP协议栈配置使能LWIP组件禁用DHCP初始调试建议使用静态IP手动设置IP地址、子网掩码和网关3. PHY芯片驱动与复位电路实现LAN8720A需要通过SMIMDIO/MDC接口进行配置。很多开发板为了节省GPIO资源会使用PCF8574这类I2C接口的IO扩展芯片来控制PHY复位。以下是完整的驱动实现// pcf8574.h #define PCF8574_ADDR 0x40 // 根据硬件连接的A0/A1/A2引脚确定 #define ETH_RESET_IO 7 // 假设PHY复位连接在P7引脚 uint8_t PCF8574_Init(void); void PCF8574_WriteBit(uint8_t bit, uint8_t sta);// pcf8574.c #include pcf8574.h uint8_t PCF8574_Init(void) { uint8_t data 0xFF; // 初始化为全高电平 if(HAL_I2C_Mem_Write(hi2c2, PCF8574_ADDR, 0xFF, I2C_MEMADD_SIZE_8BIT, data, 1, 100) ! HAL_OK) { return 1; // 初始化失败 } return 0; } void PCF8574_WriteBit(uint8_t bit, uint8_t sta) { uint8_t data; HAL_I2C_Mem_Read(hi2c2, PCF8574_ADDR|0x01, 0xFF, I2C_MEMADD_SIZE_8BIT, data, 1, 100); if(sta) data | (1 bit); else data ~(1 bit); HAL_I2C_Mem_Write(hi2c2, PCF8574_ADDR, 0xFF, I2C_MEMADD_SIZE_8BIT, data, 1, 100); }在ethernetif.c文件的low_level_init()函数中添加PHY复位序列// 复位PHY芯片 PCF8574_WriteBit(ETH_RESET_IO, 1); HAL_Delay(100); // 保持100ms高电平 PCF8574_WriteBit(ETH_RESET_IO, 0); HAL_Delay(100); // 保持100ms低电平4. LWIP协议栈初始化与网络测试CubeMX生成的代码有时会遗漏IP地址配置需要手动检查lwip.c文件中的MX_LWIP_Init()函数// 确保以下数组被正确初始化 uint8_t IP_ADDRESS[4] {192, 168, 1, 10}; uint8_t NETMASK_ADDRESS[4] {255, 255, 255, 0}; uint8_t GATEWAY_ADDRESS[4] {192, 168, 1, 1};在FreeRTOS的默认任务中添加网络测试代码void StartDefaultTask(void const * argument) { MX_LWIP_Init(); for(;;) { // 每隔1秒闪烁LED指示系统运行正常 HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); // 可以添加ping响应测试等更多网络功能 osDelay(1000); } }完成以上步骤后编译下载程序到开发板。在PC端进行以下操作验证用网线连接开发板和PC设置PC网卡IP为同一网段如192.168.1.100打开命令提示符执行ping测试ping 192.168.1.10如果看到类似以下输出说明通信成功来自 192.168.1.10 的回复: 字节32 时间1ms TTL2555. 常见问题排查指南当ping不通开发板时可以按照以下步骤排查硬件检查清单确认开发板和PC用网线直连或通过交换机连接检查RMII接口所有引脚连接是否正确测量PA1引脚是否有50MHz时钟输出确认LAN8720A的VDD电压为3.3V软件调试技巧在main()函数初始化后添加PHY寄存器读取测试uint32_t phy_id 0; HAL_ETH_ReadPHYRegister(heth, 0x02, phy_id); printf(PHY ID: 0x%04X\n, phy_id);正常应输出LAN8720A的ID0x0007C0F1检查lwipopts.h中的配置#define LWIP_ARP 1 #define LWIP_ICMP 1 #define LWIP_UDP 1 #define LWIP_TCP 1如果使用FreeRTOS确保以太网中断优先级设置正确HAL_NVIC_SetPriority(ETH_IRQn, 5, 0); HAL_NVIC_EnableIRQ(ETH_IRQn);通过以上步骤你应该已经完成了STM32F429与LAN8720A的以太网通信基础实现。在实际项目中接下来可以继续开发TCP服务器、UDP通信等更高级的网络功能。

更多文章