打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
STM32移植lwip之官方工程修改

本篇目标:在之前的硬件基础上,修改ST官方移植lwip的工程,使PC机能ping通stm32

材料准备:


跟着文件路径打开其中一个工程,先选择不带操作系统的练习测试
文件路径:STM32F4x7_ETH_LwIP_V1.1.1 -> Project -> Standalone -> tcp_echo_server -> MDK-ARM -> Project.uvproj

先编译一下,出现3个Warning,其中两个是变量定义未使用,不影响暂且不管,还有一个是ethernetif.c文件最后没有空白行,手动添加一行,再次编译~
消除所有错误警告~成功开始的第一步~


从main函数开始理解并修改(英文为官方注释,中文为修改注释):

int main(void){  /*!< At this stage the microcontroller clock setting is already configured to        168 MHz, this is done through SystemInit() function which is called from       startup file (startup_stm32f4xx.s) before to branch to application main.       To reconfigure the default setting of SystemInit() function, refer to       system_stm32f4xx.c file     */  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);#ifdef SERIAL_DEBUG  DebugComPort_Init();  #endif  /*Initialize LCD and Leds */   //LCD_LED_Init();    //硬件没有LCD,也暂时不用LED,将函数注释掉  /* configure ethernet (GPIOs, clocks, MAC, DMA) */  ETH_BSP_Config();    //MAC-PHY配置函数,主要理解修改函数  /* Initilaize the LwIP stack */  LwIP_Init();    //lwip初始化函数  /* tcp echo server Init */  //tcp_echoserver_init();    //tcp服务器建立函数,暂时只建立ping工程,将函数注释掉  /* Infinite loop */  while (1)  {      /* check if any packet received */    if (ETH_CheckFrameReceived())    {       /* process received ethernet packet*/      LwIP_Pkt_Handle();    }    /* handle periodic timers for LwIP*/    LwIP_Periodic_Handle(LocalTime);  } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

main函数中有两个修改:

  1. 注释 LCD_LED_Init() 函数,暂时用不到
  2. 注释 tcp_echoserver_init() 函数,暂时用不到

其次进入主要配置函数 ETH_BSP_Config() :

  • 这个函数中修改的内容只有一个,找到 DP83848_PHY_ADDRESS 的宏定义(在 stm32f4x7_eth_bsp.h 的第52行),修改原先的 0x01 为 0x00 地址,那么这个地址是怎么来的,等到代码解析的时候再做解剖
  • 函数中重点关注 ETH_GPIO_Config() 函数和 ETH_MACDMA_Config() ,这两个函数分别是配置RMII接口相关GPIO口的复用,配置MAC控制器和使能DMA

接着看 ETH_GPIO_Config() 函数:
由于官方移植lwip用的是MII接口,而之前搭建的硬件接口是RMII,所以需要修改相关宏定义和 GPIO口的复用

void ETH_GPIO_Config(void){    GPIO_InitTypeDef GPIO_InitStructure;    /* Enable GPIOs clocks */    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|                           RCC_AHB1Periph_GPIOB|                           RCC_AHB1Periph_GPIOC,                           ENABLE);     //我们只用到了A,B,C三种引脚,所以修改成只使能A,B,C三个的时钟  /* Enable SYSCFG clock */  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); //使能SYSCFG外设时钟  /* Configure MCO (PA8) */  //配置PA8(做为MCO功能)输出时钟信号  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;    GPIO_Init(GPIOA, &GPIO_InitStructure);                /* MII/RMII Media interface selection --------------------------------------*/#ifdef MII_MODE #ifdef PHY_CLOCK_MCO  RCC_MCO1Config(RCC_MCO1Source_HSE, RCC_MCO1Div_1); //在PA8引脚上输出25MHZ的时钟信号 #endif /* PHY_CLOCK_MCO */  SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_MII);  //与PHY芯片通讯选择MII模式#elif defined RMII_MODE  //这里要修改宏定义,注释MII_MODE,取消注释RMII_MODE,选择RMII接口模式与PHY芯片进行通讯   RCC_MCO1Config(RCC_MCO1Source_PLLCLK,RCC_MCO1Div_2); //添加时钟函数,在PA8引脚上输出50MHZ时钟信号  SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII); //与PHY芯片通讯选择RMII模式#endif/* Ethernet pins configuration ************************************************/   /*        ETH_MDIO -------------------------> PA2        ETH_MDC --------------------------> PC1        ETH_RMII_REF_CLK------------------> PA1        ETH_RMII_CRS_DV ------------------> PA7        ETH_RMII_RXD0 --------------------> PC4        ETH_RMII_RXD1 --------------------> PC5        ETH_RMII_TX_EN -------------------> PB11        ETH_RMII_TXD0 --------------------> PB12        ETH_RMII_TXD1 --------------------> PB13                                                  */  //修改下面所有对GPIO的初始化为对应RMII接口GPIO的初始化,而RMII所用到的引脚在上面的列表中,共9个引脚  /* Configure PA1, PA2 and PA7 */  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_7;  GPIO_Init(GPIOA, &GPIO_InitStructure);  GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH);  GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH);  GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH);  /* Configure PB11,PB12 and PB13 */  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;  GPIO_Init(GPIOB, &GPIO_InitStructure);  GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_ETH);     GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_ETH);  GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_ETH);  /* Configure PC1, PC4 and PC5 */  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5;  GPIO_Init(GPIOC, &GPIO_InitStructure);  GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH);  GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH);  GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

总结修改之前,先做一下RMII接口相关引脚的功课:

  • ETH_MDIO ————————> PA2
  • ETH_MDC ————————–> PC1
  • ETH_RMII_REF_CLK—————> PA1
  • ETH_RMII_CRS_DV —————> PA7
  • ETH_RMII_RXD0 ——————> PC4
  • ETH_RMII_RXD1 ——————> PC5
  • ETH_RMII_TX_EN —————–> PB11
  • ETH_RMII_TXD0 ——————> PB12
  • ETH_RMII_TXD1 ——————> PB13

修改总结:

  1. 修改GPIO时钟使能函数 RCC_AHB1PeriphClockCmd() ,因为只用到了ABC三个引脚,所以修改成只对A,B,C三个引脚进行时钟使能
  2. 修改宏定义,因为用的是RMII接口,所以要注释掉MII_MODE的宏定义,取消注释RMII_MODE的宏定义,这两个宏定义在main.h文件的79行和87行
  3. 添加配置PHY时钟函数 RCC_MCO1Config() ,添加在 #elif defined RMII_MODE 的下面即可
  4. 修改GPIO口初始化成RMII接口的GPIO,这里包括了对GPIOA,GPIOB,GPIOC的初始化以及将三个GPIO口的复用成RMII接口所用

接下来要来看 ETH_MACDMA_Config() 函数中的最后一个函数 ETH_Init() ,这个函数包含了所有MAC控制器相关初始化的配置,所以定位到这个函数
stm32f4xf_eth.c第416行开始:

    /* Reset Timeout counter */    timeout = 0;    /* Read the result of the auto-negotiation *///    RegValue = ETH_ReadPHYRegister(PHYAddress, PHY_SR);    /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process *///    if((RegValue & PHY_DUPLEX_STATUS) != (uint32_t)RESET)//    {      /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */      //注释掉其他所有内容,只留下下面两个函数:配置为全双工      ETH_InitStruct->ETH_Mode = ETH_Mode_FullDuplex;  //    }//    else//    {      /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation *///      ETH_InitStruct->ETH_Mode = ETH_Mode_HalfDuplex;           //    }    /* Configure the MAC with the speed fixed by the auto-negotiation process *///    if(RegValue & PHY_SPEED_STATUS)//    {        /* Set Ethernet speed to 10M following the auto-negotiation *///      ETH_InitStruct->ETH_Speed = ETH_Speed_10M; //    }//    else//    {         /* Set Ethernet speed to 100M following the auto-negotiation */       //注释掉其他所有内容,只留下下面两个函数:配置为100M以太网      ETH_InitStruct->ETH_Speed = ETH_Speed_100M;//    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

修改内容:

  1. 注释掉 stm32f4xf_eth.c 第416-441行的其他内容,只留下 ETH_InitStruct->ETH_Mode = ETH_Mode_HalfDuplex; 和 ETH_InitStruct->ETH_Speed = ETH_Speed_100M;

至此为止,代码修改结束,编译下载到板子上
如果想要修改ip地址,可以找到main.h里面的宏定义:

/*Static IP ADDRESS: IP_ADDR0.IP_ADDR1.IP_ADDR2.IP_ADDR3 */#define IP_ADDR0   192#define IP_ADDR1   168#define IP_ADDR2   0#define IP_ADDR3   10
  • 1
  • 2
  • 3
  • 4
  • 5

修改成自己想要的IP地址便可以了,接下来用pc机来ping一下


ping之前,要确定两件事:

  1. 首先确定pc机连入的网络ip地址和stm32的ip地址是不是同一个网段:


    这里192.168.0.1和192.168.0.10就处于同一个网段

  2. 其次如果是将stm32用网线接入路由器,则要确定stm32所使用的ip地址没有被占用,检测方法就是接入stm32前,先ping设定的地址,看能不能ping通,不能ping通表示没有被占用;这里是直接用网线连接stm32和pc机,所以不用担心这个问题


接下来可以用pc机ping下载好程序的stm32
win+R打开运行,输入cmd,回车
在命令行下输入ping 192.168.0.10
ping通成功,有图有真相


总结:
官方移植程序帮忙做了很多事情,可以方便使用,那么修改也不外乎这么几个地方,多多测试注意就可以成功,当能ping通,搭建好硬件软件环境之后就可以安心地一步步调用lwip的API接口函数建立服务器,客户端等等了。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
如何使用STM32CubeMX配置ETH(RMII)
【MCU实战经验】+stm32f4 + uCOS
实用的STM32之ADC步骤与技巧
STM32开发经验、Keil使用技巧与注意事项整理
STM32 LwIP测试过程简介
STM32 HAL库使用前的配置文件设置说明(stm32f1xx_hal_conf.h)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服