STM32F2标准库LWIP移植教程

说在前面

        由于工作原因,从接触LWIP开始就是用的 CubeMX+HAL库。每次用起来都很方便,但也出现了一个问题:当没有CubeMX时就不知到该如何实现LWIP,于是有了这个突然的想法:学习LWIP标准库移植,在学习LWIP移植的同时还能学一下标准库的使用(其实就是找不到HAL库移植的教程和资料)。

        注:本次的测试平台是  STM32F207 + DP83848

一、STM32标准库LWIP例程源码下载:    

        进入ST官网,首先点击放大镜图案,之后点击产品后的小三角形弹出类别选择框,选择类别为“工具与软件”,最后在搜索框里输入“LWIP”后回车

         输入回车后会进入以下页面,找到F2的LWIP演示例程后下载(下载时需要登录ST账号,没有的自行注册一个吧),如下图所示:

二、LWIP移植

解压以后可以看到里面有“_htmresc”、“Libraries”、“Project”、“Utilities”这4个文件夹和“Release_Notes.html”这个文件。接下来开始进入移植工作,我们就以裸机实现tcp_echo_client这个例程为例进行移植,步骤如下:

        1、新建一个文件夹,命名为“tcp_echo_client”,里面分别新建“Libraries”、“MDK-ARM”、“USER”这3个文件夹。

        2、将例程源码中“Libraries”文件夹复制到“tcp_echo_client”根目录,之后再对复制过来的“Libraries”中的“CMSIS”文件夹进行处理:

                a.将“CMSIS -> CM3 -> CoreSupport”里面的两个文件剪切到“CMSIS”根目录;

             b.将“CMSIS -> CM3 -> DeviceSupport -> ST -> STM32F2xx -> startup -> arm”里面的“startup_stm32f2xx.s”文件剪切到“tcp_echo_client”里的“MDK-ARM”中;

                c.将“CMSIS -> CM3 -> DeviceSupport -> ST -> STM32F2xx”里面的1个C文件和2个H文件剪切到“CMSIS”根目录;

                d.删除“CMSIS”根目录中除了刚才剪切出来的5个文件其余文件/文件夹。

        3、将例程源码中“Utilities -> Third_Party”的“lwip_v1.3.2”文件夹复制到“tcp_echo_client”的根目录。

        4、将例程源码中“Project -> Standalone -> tcp_echo_client”里的“src”、“inc”两个文件夹复制到自己“tcp_echo_client -> USER”中,“src”文件夹只保留“main.c”、“netconf.c”、“stm32f2x7_eth_bsp.c”、“stm32f2xx_it.c”四个文件,“inc”文件夹删除“serial_debug.h”和“tcp_echoclient.h”这2个文件。

        5、打开MDK5,新建“tcp_echo_client”工程,工程路径选择“tcp_echo_client -> MDK-ARM”,芯片选择STM32F207ZGTx,驱动文件后面手动添加。

      6、点击MDK上面的红白绿三色品字形方块按钮打开工程树,将工程树名称设置为“tcp_echo_client”,之后在下面建立“StartUP”、“CORE”、“Driver”、“STM32F2x7_ETH_Driver”、“USER”、“LWIP”几个文件夹。

        7、按下图所示添加文件到依次对应的文件夹。

        8、MDK设置(点击上面的魔术棒按钮进入):

                Tagget选项卡:勾上“Use MicroLIB”

                C/C++选项卡:

                        Define栏输入:“USE_STDPERIPH_DRIVER,STM32F207ZG”两条处理宏

                        编译路径:按下图添加

        9、代码修改(解决代码中现在的bug):

                main.h文件:  注销:“#define USE_LCD”

                main.h文件:

                        注销:#include "serial_debug.h"

                        注销 “LCD_LED_BUTTON_Init”这个函数及其在开头的声明;

                        注销main函数中的语句:LCD_LED_BUTTON_Init();

                stm32f2x7_eth_bsp.h文件:

                        注销 #include "stm322xg_eval.h"

                        注销 #include "stm322xg_eval_lcd.h"

                stm32f2xx_it.c文件:

                        注销:#include "tcp_echoclient.h"

                        注销“EXTI15_10_IRQHandler”函数中的第一个if语句;

                stm32f2x7_eth_bsp.c文件:

                        注销“ETH_BSP_Config”函数中以下语句:

                                if (EthInitStatus == 0)

                                {

                                          LCD_SetTextColor(Red);

                                          LCD_DisplayStringLine(Line5, (uint8_t*)"   Ethernet Init   ");

                                          LCD_DisplayStringLine(Line6, (uint8_t*)"      failed      ");

                                          while(1);

                                }

        10、根据板子IO修改IO初始化代码(以我手上的板子为例,修改后的代码如下):

void ETH_GPIO_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  
  /* Enable GPIOs clocks */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |
                         RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOI |
                         RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_GPIOH |
                         RCC_AHB1Periph_GPIOF, ENABLE);

  /* Enable SYSCFG clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);  
  
  /* MII/RMII Media interface selection --------------------------------------*/
#ifdef MII_MODE /* Mode MII with STM322xG-EVAL  */

 #ifdef PHY_CLOCK_MCO

  /* Output HSE clock (25MHz) on MCO pin (PA8) to clock the PHY */
  RCC_MCO1Config(RCC_MCO1Source_HSE, RCC_MCO1Div_1);
 #endif /* PHY_CLOCK_MCO */

  SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_MII);
  
/* Ethernet pins configuration ************************************************/
    /**ETH GPIO Configuration
    PA0/WKUP     ------> ETH_CRS
    PA1     ------> ETH_RX_CLK
    PA2     ------> ETH_MDIO
    PA3     ------> ETH_COL
    PA7     ------> ETH_RX_DV        
    PB0     ------> ETH_RXD2
    PB1     ------> ETH_RXD3
    PB8     ------> ETH_TXD3        
    PB11     ------> ETH_TX_EN
    PB12     ------> ETH_TXD0
    PB13     ------> ETH_TXD1    
    PC1     ------> ETH_MDC
    PC2     ------> ETH_TXD2
    PC3     ------> ETH_TX_CLK
    PC4     ------> ETH_RXD0
    PC5     ------> ETH_RXD1    
     */

  /* Configure MCO (PA8) */
  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);

  /* Configure PA0 PA1, PA2 PA3 and PA7 */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_7;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_ETH);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_ETH);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH);

  /* Configure PB0 PB1 PB8 PB11 PB12 and PB13 */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_ETH);	
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_ETH);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_ETH);	
  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, PC2, PC3, PC4 and PC5 */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_ETH);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource3, GPIO_AF_ETH);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH);  
  
  
#elif defined RMII_MODE  /* Mode RMII with STM322xG-EVAL */

  SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII);

#endif


}

修改完成后编译下载测试,网络已经通了

三、优化 

        使用硬件复位替代软件复位

                先编写一个ETH_Hard_RESET函数,同时添加声明在文件开头,代码如下:

void ETH_Hard_RESET(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE);

  /* Configure  (PC9) */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//中等速度
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;  //上拉
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_RESET);
  Delay(20);
  GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_SET);
  Delay(50);    
}

       将”ETH_Hard_RESET“函数在”ETH_BSP_Config“函数开头调用;

       注销“ETH_MACDMA_Config”函数中的“ETH_SoftwareReset();“语句;

修改完成后编译下载测试,网络也是通的。

-------------------------------------此记到此结束!希望能对大家有所帮助

        

  • 13
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值