2.3 stm32移植lwip常见问题和解决方式

1.PHY初始化
  一般来说,stm32外部驱动PHY芯片有两种连接方式,MII和RMII总线,这个与硬件设计有关,不过stm32芯片一般都支持这两种总线连接方式,因为RMII总线在传输效果不变的情况下占用接口更少,因此一般推荐RMII方式.
  以DP83848芯片为例:
  技术分享
从上面可以看出RMII总线对应的输入时钟要设置为50MHZ, 当然这与你原理图的布线有,连接PHY芯片X1接口对应GPIO接口的外设区域时钟就要设定为该值,考虑到挂在同区域外设的时钟要求,为了方便设计,对于stm32f207vet6(我用的芯片),将系统时钟从120MHz改为100MHz,该区域外设时钟设置为1/2即可。对于stm32f107vc则需要通过PLL3将该区域外设时钟拉高到50Mhz。
目前来说大部分人对于stm32驱动的移植都是直接把官方例程拿过来用,很少有人去探讨每一项配置的含义,一般情况当然不会出问题,但遇到复杂情况就很难说了,因此我建议还是对照参考手册仔细研读每一项,自己定制,stm32芯片对ETH的操作还是很有讲究的。
其实默认驱动有一个最大的问题,那就是在启动的时候如果没有插网线,就会启动失败而不能够正常工作,如果仔细研读过官方库的函数,就可以很简单解决这个问题,下面我就把我整理的驱动部分函数和注释写上来,希望有帮助。
 ETH_DeInit();

  /* Software reset */
  ETH_SoftwareReset();

  /* Wait for software reset */
  while (ETH_GetSoftwareResetStatus() == SET);

  /* ETHERNET Configuration---------------------------------------------*/
  /* Call ETH_StructInit if you don‘t like to configure all ETH_InitStructure parameter */
  ETH_StructInit(&ETH_InitStructure);

  /* Fill ETH_InitStructure parametrs */
  /*------------------------ ETH_MACCR-----------------------------------*/
    //参数是否自动配置,选择disable需要自动配置默写参数(auto模式在网线没插上时会导致超时,初始化失败)
   ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Disable;
    ETH_InitStructure.ETH_Watchdog = ETH_Watchdog_Disable;                            //关闭看门狗定时器,允许接收超长帧
    ETH_InitStructure.ETH_Jabber = ETH_Jabber_Disable;                                //关闭jabber定时器,允许发送超长帧
    ETH_InitStructure.ETH_InterFrameGap = ETH_InterFrameGap_40Bit;                //发送帧间间隙
    ETH_InitStructure.ETH_Speed = ETH_Speed_100M;                                     //快速以太网速度
    ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;                    //不启用自循环模式
    ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;                                 //全双工模式
  
    /*自动填充/CRC剥离处理不执行,转发所有帧*/
    ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;   
#if CHECKSUM_BY_HARDWARE
   ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable; //IPV4头文件硬件校验
#endif

    /*------------------------ ETH_MACFFR----------------------------------*/
   ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable;                                   //MAC过滤只接受通过源目的地址的数据
    ETH_InitStructure.ETH_SourceAddrFilter = ETH_SourceAddrFilter_Normal_Enable;                 //MAC过滤源地址错误帧?
    ETH_InitStructure.ETH_PassControlFrames = ETH_PassControlFrames_BlockAll;                    //MAC不转发任何控制帧
    ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;        //接收广播帧
    ETH_InitStructure.ETH_DestinationAddrFilter = ETH_DestinationAddrFilter_Normal;              //目的地址过滤结果正常
    ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;                         //混杂模式,启用帧过滤
    ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;             //过滤器正常工作,不传送控制帧
    ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;                 //单播帧目的地址完美过滤

   /*------------------------   DMA  ETH_DMAOMR -----------------------------------*/  
   /* When we use the Checksum offload feature, we need to enable the Store and Forward mode: 
   the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum, 
   if the checksum is OK the DMA can handle the frame otherwise the frame is dropped */
    /*丢弃校验错误帧不执行(因为未进行硬件校验)*/
    ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Disable;
    ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Disable;              //接收数据超过阈值转发
    ETH_InitStructure.ETH_FlushReceivedFrame = ETH_FlushReceivedFrame_Enable;                 //描述符被占用和接收FIFO不可用时清空FIFO(解决堵塞)
    ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Disable;            //发送数据完整帧转发
    ETH_InitStructure.ETH_TransmitThresholdControl = ETH_TransmitThresholdControl_64Bytes;    //发送阈值为64Bytes
    ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;                //接收FIFO丢弃所有错误帧
    
    /*接收FIFO上传长度不够的好帧*/
  
ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Enable;
  ETH_InitStructure.ETH_ReceiveThresholdControl
= ETH_ReceiveThresholdControl_64Bytes; //接收阈值为64Bytes
ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable; //DMA直接发送第二个帧,不需要之前帧回复 /*------------------------ DMA ETH_DMABMR -----------------------------------*/ ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable; //传输地址对齐 ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable; //固定的突发 ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat; ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat; ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1; //发送和接收比例(上传数据时重要) 2:1 /* Configure Ethernet */ ETH_Init(&ETH_InitStructure, DP83848_PHY_ADDRESS); /* Enable the Ethernet Rx Interrupt 仅开启接收中断*/ ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R, ENABLE);

 当然这是我根据自己需求的配置,具体项目因为实际传输的不同需要个人修改也是必要的。

2.lwip中lwipopt.h文件的修改

参照上一节内容,理解才是能够修改的基础。

3.未完待续 

 

文章来自:http://www.cnblogs.com/zc110747/p/4746470.html
© 2021 jiaocheng.bubufx.com  联系我们
ICP备案:鲁ICP备09046678号-3