你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32H5 评测】3、STM32H5 Lwip 移植、官方例程和UDP发送数据

[复制链接]
EPTmachine 发布时间:2026-10-18 22:13

NUCELO-H5E5ZJ的CubeMX配置中没有集成LWIP配置选项,运行Lwip需要参考ST官方社区的说明和官方示例仓库代码移植到工程中。

ST官方社区提供的移植教程:

https://community.st.com/stm32-mcus-60/how-to-use-the-lwip-ethernet-middleware-on-the-stm32h5-series-135644

STM32 H5系列示例教程仓库

https://github.com/STMicroelectronics/stm32h5-classic-coremw-apps

1、CubeMX工程配置

根据开发板型号NUCLEO-H5E5ZJ创建CubeMX工程,勾选BSP相关的外设

Board_Periph_Config.png

开发板创建的工程默认的时钟使用内部时钟,CubeMX中使能HSE使用外部晶振。

RCC_HSE_Select.png

开发板板载有48MHz的时钟用于提供外部时钟源

HSE_Schematic.png

Clock界面中配置开发板时钟参数,配置MCU达到最高主频250MHz。

CubeMX_Clock_Config.png

使能ETH外设为RMII,NUCLEO-H5E5ZJ以分配好相关的RMII引脚,修改RMII引脚的Speed参数为Very High。

Change_RMII_Speed_Very_High.png

修改Project Manager->Advanced Settings中的MX_ETH_Init函数的生成配置如下,不生成函数的调用,并可以在其他源文件引用该函数,用于lwip适配函数中调用ETH外设的初始化函数。

Change_Eth_Init_Gen_Option.png

保存并生成STM32CubeIDE工程。

2、添加和配置lwip代码

STM32 H5系列示例教程仓库中有相应的lwip代码仓库。

https://github.com/STMicroelectronics/stm32h5-classic-coremw-apps

复制仓库中的"stm32h5-classic-coremw-apps\Middlewares"目录到到工程所在的工作空间文件夹中。

Copy_middleware_folder_to_workspace.png

在工程中创建文件夹并连接到LwIP仓库文件夹

Create_LWIP_Src_Link.png

代码仓库中源码需要添加到工程索引中,其中不需要的代码通过设置过滤项将其排除到编译流程外。

Lwip_Source_folder_filter.png

工程的头文件路径中添加lwip协议栈相关的头文件路径。

Add_Lwip_Header_File_Path.png

复制"stm32h5-classic-coremw-apps\Projects\NUCLEO-H563ZI\Applications\LwIP\LwIP_UDP_Echo_Client\LWIP"文件夹中的应用代码到工程中。

添加应用代码的路径到源码路径,相应的头文件路径也添加到工程管理中

Add_AppFile_SourceFolder.png

Add_AppFile_HeaderPath.png

开发板的以太网芯片的型号为lan8742,驱动代码在stm32h5-classic-coremw-apps\Drivers\BSP\Components\lan8742文件夹中可以找到,复制其中的lan8742.c和lan8742.h到工程中。

3、修改代码

移植的代码是适配NUCLEO-H563ZI开发板的,在NUCLEO-H5E5ZJ开发板上运行该代码,需要修改进行相应的修改。

3.1 LWIP\Target\ethernetif.c 代码修改

根据添加源码的路径,修改包含路径设置。

ethernetif_header.png

由于CubeMX生成会自动生成Ethernet相关的数据结构体,造成重定义问题,修改文件中的变成的声明。

extern ETH_DMADescTypeDef  DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
extern ETH_DMADescTypeDef  DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */

/* Global Ethernet handle*/
extern ETH_HandleTypeDef heth;
extern ETH_TxPacketConfig TxConfig;

low_level_init函数初始化ETH外设部分的代码调用CubeMX生成的ETH初始化函数MX_ETH_Init,并修改netif中的MAC地址赋值代码。删除代码中的TxConfig参数配置代码。

/* Set Tx packet config common parameters */
  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;

修改后的low_level_init函数代码如下

static void low_level_init(struct netif *netif)
{
  /* configure ethernet peripheral (GPIOs, clocks, MAC, DMA) */
  MX_ETH_Init();

  /* set MAC hardware address length */
  netif->hwaddr_len = ETH_HWADDR_LEN;

  netif->hwaddr[0] = heth.Init.MACAddr[0];
  netif->hwaddr[1] = heth.Init.MACAddr[1];
  netif->hwaddr[2] = heth.Init.MACAddr[2];
  netif->hwaddr[3] = heth.Init.MACAddr[3];
  netif->hwaddr[4] = heth.Init.MACAddr[4];
  netif->hwaddr[5] = heth.Init.MACAddr[5];

  /* maximum transfer unit */
  netif->mtu = ETH_MAX_PAYLOAD;

  /* device capabilities */
  /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
  netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;

  /* Initialize the RX POOL */
  LWIP_MEMPOOL_INIT(RX_POOL);

  /* Set PHY IO functions */
  LAN8742_RegisterBusIO(&LAN8742, &LAN8742_IOCtx);

  /* Initialize the LAN8742 ETH PHY */
  if(LAN8742_Init(&LAN8742) != LAN8742_STATUS_OK)
  {
    netif_set_link_down(netif);
    netif_set_down(netif);
    return;
  }

  ethernet_link_check_state(netif);
}

由于CubeMX自动生成的代码重定义,删除void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)函数的定义。

替换EthHandle变量名为eth

replace_EthHandle_with_heth.png

3.2 LWIP\App\app_ethernet.c

由于开发板的配置不同,修改相应的LED枚举常量

changeLED_BLUE.png

3.3 main.h和main.c 代码修改

main.h中添加UDP连接相关的宏定义。

/* UDP remote connection port */
#define UDP_SERVER_PORT    ((uint16_t)7U)

/*Static DEST IP ADDRESS: DEST_IP_ADDR0.DEST_IP_ADDR1.DEST_IP_ADDR2.DEST_IP_ADDR3 */
#define DEST_IP_ADDR0   ((uint8_t)10U)
#define DEST_IP_ADDR1   ((uint8_t)157U)
#define DEST_IP_ADDR2   ((uint8_t)129U)
#define DEST_IP_ADDR3   ((uint8_t)84U)

/*Static IP ADDRESS: IP_ADDR0.IP_ADDR1.IP_ADDR2.IP_ADDR3 */
#define IP_ADDR0   ((uint8_t) 192U)
#define IP_ADDR1   ((uint8_t) 168U)
#define IP_ADDR2   ((uint8_t) 0U)
#define IP_ADDR3   ((uint8_t) 10U)

/*NETMASK*/
#define NETMASK_ADDR0   ((uint8_t) 255U)
#define NETMASK_ADDR1   ((uint8_t) 255U)
#define NETMASK_ADDR2   ((uint8_t) 255U)
#define NETMASK_ADDR3   ((uint8_t) 0U)

/*Gateway Address*/
#define GW_ADDR0   ((uint8_t) 192U)
#define GW_ADDR1   ((uint8_t) 168U)
#define GW_ADDR2   ((uint8_t) 0U)
#define GW_ADDR3   ((uint8_t) 1U)

main.c中添加相关的头文件

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "string.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "lwip/opt.h"
#include "lwip/init.h"
#include "netif/etharp.h"
#include "lwip/netif.h"
#include "lwip/timeouts.h"
#if LWIP_DHCP
#include "lwip/dhcp.h"
#endif
#include "ethernetif.h"
#include "app_ethernet.h"
#include "udp_echoclient.h"
/* USER CODE END Includes */

添加lwip 以太网接口变量gnetif

struct netif gnetif;

定义网络接口初始化函数,初始化网络接口的IP地址和注册回调函数。

static void Netif_Config(void);

/**
  * @brief  Setup the network interface
  * @param  None
  * @retval None
  */
static void Netif_Config(void)
{
  ip_addr_t ipaddr;
  ip_addr_t netmask;
  ip_addr_t gw;

#if LWIP_DHCP
  ip_addr_set_zero_ip4(&ipaddr);
  ip_addr_set_zero_ip4(&netmask);
  ip_addr_set_zero_ip4(&gw);
#else

  /* IP address default setting */
  IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
  IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3);
  IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);

#endif

  /* add the network interface */
  netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &ethernet_input);

  /*  Registers the default network interface */
  netif_set_default(&gnetif);

  ethernet_link_status_updated(&gnetif);

#if LWIP_NETIF_LINK_CALLBACK
  netif_set_link_callback(&gnetif, ethernet_link_status_updated);
#endif
}

main函数中添加lwip初始化以及UDP Client启动函数。

int main(void)
{
    ...
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  printf("UDP Echo Client Application \r\n");
  printf("STM32H5E5ZJ board \r\n");
  printf("State: Ethernet Initialization ... \r\n");

  /* Initialize the LwIP stack */
  lwip_init();

  /* Configure the Network interface */
  Netif_Config();

  /* UDP client connect */
  udp_echoclient_connect();
  while (1)
  {

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    /* Read a received packet from the Ethernet buffers and send it
       to the lwIP for handling */
    ethernetif_input(&gnetif);

    /* Handle timeouts */
    sys_check_timeouts();

#if LWIP_NETIF_LINK_CALLBACK
    Ethernet_Link_Periodic_Handle(&gnetif);
#endif

#if LWIP_DHCP
    DHCP_Periodic_Handle(&gnetif);
#endif
  }
  /* USER CODE END 3 */
}

4、运行效果

编译烧录程序到开发板,网络调试助手设置UDP连接参数,开发板用户按键中断函数发送UDP数据,网络调试助手接收到的数据如图。

UDP_Recv.pngalt text

赞 收藏 评论0 发布时间:2026-10-18 22:13

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版