之前写过一篇某点原子探索者V2的rtt以太网驱动,后边公司给配了个F429阿波罗的,本来以为稍微改改就能用,没想到坑点还不少。探索者407的ETH_RESET口是PD3,但是阿波罗F429的ETH_RESET由PCF8574控制,所以一个简单的控制io口高低电平就能复位的操作变成了需要操作I2C。。。,可能是为了节省资源吧,不清楚。话不多说直接开始。
一.创建rtt工程
不用多说

二.打开rtt setting,打开lwip以及sal
点一下就行,不要双击,sal是给ifconfig命令用的。然后ctrl+s保存即可。

三.打开cubemx配置

选择IGTx

配置RCC

配置sys

配置USART1

配置ETH


配置时钟,直接拉满

生成代码关闭cubemx
四.干掉报错
编译完会有很多报错,不要慌,一个一个来
1.PHY_SR PHY_SPEED_STATUS PHY_DUPLEX_STATUS报错

解决办法:用下边代码覆盖即可。原因有兴趣可以查查
/* Section 4: Extended PHY Registers */
// #define PHY_SR ((uint16_t)) /*!< PHY status register Offset */
// #define PHY_SPEED_STATUS ((uint16_t)) /*!< PHY Speed mask */
// #define PHY_DUPLEX_STATUS ((uint16_t)) /*!< PHY Duplex mask */
#define PHY_SR ((uint16_t)0x1F) /*!< PHY special control/ status register Offset */
#define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< PHY Speed mask */
#define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< PHY Duplex mask */
2.cubemx生成的代码报错,

解决办法:全部屏蔽
//static void MX_ETH_Init(void)
//{
//
// /* USER CODE BEGIN ETH_Init 0 */
//
// /* USER CODE END ETH_Init 0 */
//
// static uint8_t MACAddr[6];
//
// /* USER CODE BEGIN ETH_Init 1 */
//
// /* USER CODE END ETH_Init 1 */
// heth.Instance = ETH;
// MACAddr[0] = 0x00;
// MACAddr[1] = 0x80;
// MACAddr[2] = 0xE1;
// MACAddr[3] = 0x00;
// MACAddr[4] = 0x00;
// MACAddr[5] = 0x00;
// heth.Init.MACAddr = &MACAddr[0];
// heth.Init.MediaInterface = HAL_ETH_RMII_MODE;
// heth.Init.TxDesc = DMATxDscrTab;
// heth.Init.RxDesc = DMARxDscrTab;
// heth.Init.RxBuffLen = 1524;
//
// /* USER CODE BEGIN MACADDRESS */
//
// /* USER CODE END MACADDRESS */
//
// if (HAL_ETH_Init(&heth) != HAL_OK)
// {
// Error_Handler();
// }
//
// memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig));
// TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
// TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
// TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;
// /* USER CODE BEGIN ETH_Init 2 */
//
// /* USER CODE END ETH_Init 2 */
//
//}
//ETH_TxPacketConfig TxConfig;
//ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
//ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
这时候编译就不会出问题了
五.board.h配置
使能ETH,以及LAN8720A
#define BSP_USING_ETH
#ifdef BSP_USING_ETH
#define PHY_USING_LAN8720A
/*#define PHY_USING_DM9161CEP*/
/*#define PHY_USING_DP83848C*/
#endif
这时候编译会报错,提示未定义phy_reset,这个函数需要自己写的,不着急后边会有

六.添加PCF8574驱动
applications内添加驱动,源码在F429官方示例的网络通信实验里,当然也可以在我的工程里下载,源码会放在最后,还不赶紧点赞收藏?

七.完善代码
在main.c里初始化pcf8574
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-06-25 RT-Thread first version
*/
#include <rtthread.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include "pcf8574.h"
int main(void)
{
PCF8574_Init();
return RT_EOK;
}
board.c底部添加HAL_ETH_MspInit以及刚刚需要自己写的phy_reset函数,直接放代码,可以直接复制。
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-06-25 RealThread first version
*/
#include <rtthread.h>
#include <board.h>
#include <drv_common.h>
#include "pcf8574.h"
RT_WEAK void rt_hw_board_init()
{
extern void hw_board_init(char *clock_src, int32_t clock_src_freq, int32_t clock_target_freq);
/* Heap initialization */
#if defined(RT_USING_HEAP)
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
hw_board_init(BSP_CLOCK_SOURCE, BSP_CLOCK_SOURCE_FREQ_MHZ, BSP_CLOCK_SYSTEM_FREQ_MHZ);
/* Set the shell console output device */
#if defined(RT_USING_DEVICE) && defined(RT_USING_CONSOLE)
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
/* Board underlying hardware initialization */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
}
void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if (heth->Instance == ETH)
{
/* USER CODE BEGIN ETH_MspInit 0 */
/* USER CODE END ETH_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_ETH_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/**ETH GPIO Configuration
PC1 ------> ETH_MDC
PA1 ------> ETH_REF_CLK
PA2 ------> ETH_MDIO
PA7 ------> ETH_CRS_DV
PC4 ------> ETH_RXD0
PC5 ------> ETH_RXD1
PB11 ------> ETH_TX_EN
PG13 ------> ETH_TXD0
PG14 ------> ETH_TXD1
*/
GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_13 | GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
/* USER CODE BEGIN ETH_MspInit 1 */
/* USER CODE END ETH_MspInit 1 */
}
}
void phy_reset(void)
{
PCF8574_WriteBit(ETH_RESET_IO, 1); // 硬件复位
HAL_Delay(50);
PCF8574_WriteBit(ETH_RESET_IO, 0); // 复位结束
HAL_Delay(50);
}
屏蔽RT-ThreadStudio\workspace\RTT_F429_ETH_LWIP\cubemx\Src\stm32f4xx_hal_msp.c里的void HAL_ETH_MspInit(ETH_HandleTypeDef* heth)函数

这时候编译就应该没问题了。
八.下载验证
ping通,大功告成!

如果对你有帮助请点赞收藏,谢谢!
代码仓库:RTT_F429_ETH_LWIP: 正点原子阿波罗F429IGT6的ETH驱动以及LWIP实现 (gitee.com)
参考链接:正点原子阿波罗F429+STM32CubeMX+LAN8720+LWIP:不带操作系统实现网络热插拔_正点原子阿波罗开发板项目-CSDN博客
3986

被折叠的 条评论
为什么被折叠?



