【笔记】STM32F429IGT6+RT-Thread+ETH+LWIP

之前写过一篇某点原子探索者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博客

基于RT Thread的ETH应用(一)_rtthread studio eth-CSDN博客

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值