STM32H723ZGT6+LAN8720用CubeMX生成LWIP+FreeRTOS,只需要添加PHY复位代码即可ping通

STM32H723ZGT6+LAN8720用CubeMX生成LWIP+FreeRTOS,只需要添加PHY复位代码即可ping通

软件版本

CubeMX 6.9.2
Firmware STM32Cube_FW_H7_V1.11.1

建立工程

1.选择芯片 STM32H723ZGT6
在这里插入图片描述

2.H7带MPU,默认要开启,这里选择否,我们进入工程后再配置.
在这里插入图片描述
3.首先配置MPU

  • 区域0配置LWIP内存为Normal Non-cacheable模式,后面的LWIP内存地址设置为0x30000400,长度30K,所以这里设置为32K
  • 区域1配置ETH DMA 描述符内存为Device模式,如图下图
    在这里插入图片描述
  • 这里简单说一下STM32H7的MPU配置,不想了解的按上图配置,然后直接去第4步;
  • MPU有16个配置区域,这里只用到了两个,上面的设置对应到的代码如下:
void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct = {0};

  /* Disables the MPU */
  HAL_MPU_Disable();

  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;		//ENABLE
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;		//0~15一共16个,数字越大优先级越高
  MPU_InitStruct.BaseAddress = 0x30000400;			//起始地址
  MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;		//SIZE
  MPU_InitStruct.SubRegionDisable = 0x00;			//SRD 子域设置
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;		//TEX
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;		//AP
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;	//XN
  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;		//S
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;		//C
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;		//B

  HAL_MPU_ConfigRegion(&MPU_InitStruct);

  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Number = MPU_REGION_NUMBER1;
  MPU_InitStruct.BaseAddress = 0x30000000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_1KB;
  MPU_InitStruct.SubRegionDisable = 0x0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /* Enables the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

}
  • 上面的代码其实就是配置MPU的RASR的寄存器,寄存器和库函数也贴出来供参考
    在这里插入图片描述
    在这里插入图片描述

  • 库函数代码,后面的备注是对应Cube MX配置选项

void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
{
  /* Check the parameters */
  assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
  assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));

  /* Set the Region number */
  MPU->RNR = MPU_Init->Number;

  if ((MPU_Init->Enable) != 0UL)
  {
    /* Check the parameters */
    assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
    assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
    assert_param(IS_MPU_TEX_LEVEL(MPU_Init->TypeExtField));
    assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_Init->IsShareable));
    assert_param(IS_MPU_ACCESS_CACHEABLE(MPU_Init->IsCacheable));
    assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
    assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
    assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));

    MPU->RBAR = MPU_Init->BaseAddress;	//MPU Region Base Address
    MPU->RASR = ((uint32_t)MPU_Init->DisableExec             << MPU_RASR_XN_Pos)   |	//MPU Instruction Access
                ((uint32_t)MPU_Init->AccessPermission        << MPU_RASR_AP_Pos)   |	//MPU Access Permission
                ((uint32_t)MPU_Init->TypeExtField            << MPU_RASR_TEX_Pos)  |	//MPU TEX filed level
                ((uint32_t)MPU_Init->IsShareable             << MPU_RASR_S_Pos)    |	//MPU Shareability Permission
                ((uint32_t)MPU_Init->IsCacheable             << MPU_RASR_C_Pos)    |	//MPU Cacheable Permission
                ((uint32_t)MPU_Init->IsBufferable            << MPU_RASR_B_Pos)    |	//MPU Bufferable Permission
                ((uint32_t)MPU_Init->SubRegionDisable        << MPU_RASR_SRD_Pos)  |	//MPU SubRegion Disable
                ((uint32_t)MPU_Init->Size                    << MPU_RASR_SIZE_Pos) |	//MPU Region Size
                ((uint32_t)MPU_Init->Enable                  << MPU_RASR_ENABLE_Pos);	//MPU Region
  }
  else
  {
    MPU->RBAR = 0x00;
    MPU->RASR = 0x00;
  }
}

4.配置外部晶振,我这里还配置了MCO2输出25MHZ给LAN8720提供时钟.
在这里插入图片描述
5.给HAL库配置时钟,因为后面用到了Free RTOS,SysTick会被占用。这里选了一个基本定时器TIM6。
在这里插入图片描述
6.配置时钟频率,如图即可
在这里插入图片描述
7.配置ETH参数
在这里插入图片描述
8.打开ETH中断,LWIP是采用ETH的发送和回调函数来处理数据的。
在这里插入图片描述
9.ETH默认GPIO的速度都是low,这里要全部改为Very High。ETH引脚根据自己的原理图调整。
在这里插入图片描述
10.配置两个IO,一个是PHY_RESET,这个引脚是LAN8720的复位引脚,如果你的LAN8720有硬件复位电路,那么可以不用设置这一步,后面生成的代码可以直接ping通。还有一个LED是指示灯,用来观测系统是否运行成功。
在这里插入图片描述
11.配置FreeRTOS,把TOTAL_HEAP_SIZE改大一点,这里设置为30720。
在这里插入图片描述
12.修改和添加任务,defaultTask里面会初始化LWIP,并建立LWIP任务,defaultTask的StackSize要放大一点,不然会初始化失败,这里设置为2048,占用8K字节,用完可以删除该任务,释放内存。LedTask是后面用来闪烁LED的。

void StartDefaultTask(void const * argument)
{
  /* init code for LWIP */
  MX_LWIP_Init();
  /* USER CODE BEGIN StartDefaultTask */
  osThreadTerminate(defaultTaskHandle);
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END StartDefaultTask */
}

在这里插入图片描述
13.配置IP地址,关闭DHCP,直接设置IP地址,可以根据自己的IP地址网段设置。
在这里插入图片描述
14设置LWIP_RAM_HEAP_POINTER地址,默认是0x30044000,根据上面MPU的配置,改为0x30000400。
在这里插入图片描述

15.选择PHY,我用的是LAN8720,系统里只有LAN8740,两者地址兼容,可以直接使用。其他的PHY在生成代码后需要修改地址。
在这里插入图片描述
16.配置CubeMX工程代码为MDK模式,堆栈都设置成0x800
在这里插入图片描述
17.如图完成最后的配置,生成代码。
在这里插入图片描述
18.打开ethernet.c文件,在274行添加代码,如图:
在这里插入图片描述
代码如下:

/* USER CODE BEGIN PHY_PRE_CONFIG */
	HAL_GPIO_WritePin(PHY_RESET_GPIO_Port,PHY_RESET_Pin,GPIO_PIN_RESET);
	HAL_Delay(50);
	HAL_GPIO_WritePin(PHY_RESET_GPIO_Port,PHY_RESET_Pin,GPIO_PIN_SET);
	HAL_Delay(50);
/* USER CODE END PHY_PRE_CONFIG */

19.打开freertos.c,在LED任务里添加LED闪烁代码:
在这里插入图片描述
代码如下:

  for(;;)
  {
		HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
    osDelay(100);
  }

20.最后一步配置,关闭LWIP断言,在keil里添加预定LWIP_NOASSERT,不然LWIP会使用printf,而我们没有配置打印接口,会出错。
在这里插入图片描述
21.生成代码,编译下载,直接可以ping通
在这里插入图片描述
22.写在最后,SRAM1,SRAM2这两块内存是需要使能才能用的的,但是实际测试发现,不使能也可以正常使用。不过,建议还是开启下时钟,防止意想不到的问题发生。可以放在main函数/* USER CODE BEGIN SysInit */代码段里:

  /* USER CODE BEGIN SysInit */
	__HAL_RCC_D2SRAM1_CLK_ENABLE();
	__HAL_RCC_D2SRAM2_CLK_ENABLE();
  /* USER CODE END SysInit */

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值