资讯详情

STM32中ETH驱动配置注意事项dp83848, ip101alf, ip101gr, RTL8201,LAN8720

1.MII/RMII/SMI接口连接与配置 SMI又称网站管理接口,用于网站管理接口cpu与外置PHY芯片通信,配置相关参数,包括MDC和MDIO两个管脚(CPU上面有相应的引脚,当然是普通的GPIO口模拟SMI管理也是可行的,但是按照固定的时间顺序写入和读取数据)。 MII和RMII则是是两种不同的以太网数据传输接口,因为RMII在使用较少接口的情况下MII其中功效相同MII如下图所示: 在这里插入图片描述 特别注意:RMII模式下REF_CLK要连接CPU的MCO引脚,且MCO输出时钟应为50MHz。 说说我最近遇到的。stm32在MII该模型无法正常接收数据,后来发现是STM的MII_ER脚被配置成以太网引脚,但实际悬挂(没有连接到PHY),导致stm32认为接收错误,丢失接收数据。 解决办法: 如果硬件没有完成设计,MII_ER最好正确连接PHY指定端口可提前过滤mac子层检测到的错误包。 如果硬件设计已经完成,且出错,那么就取消MII_ER引脚的配置可以(结果是错误过滤少,问题不大) 2.PHY初始化 一般来说,stm32外部驱动PHY芯片有两种连接方式,MII和RMII总线,这与硬件设计有关,但stm32芯片通常支持这两种总线连接方式,因为RMII当传输效果不变时,总线占用的接口较少,因此一般推荐RMII方式. 以DP83848芯片为例: 从上面可以看出RMII总线对应的输入时钟应设置为50MHZ, 当然,这与你原理图的布线有关,连接PHY芯片X1接口对应GPIO接口外设区域的时钟应设置为值, 考虑到挂在同一区域外设的时钟要求.为方便设计,对stm32f207vet6(我用的芯片)将系统时钟从120开始MHz改为100MHz,该区域的外设时钟可设置为1/2。 对于stm32f107vc则需要通过PLL3将MCO将端口时钟高到50Mhz输出到phy。目前,大多数人都是对的stm32驱动移植直接使用官方例程, 但我建议还是对照参考手册仔细研读每一项,自己配置ETH参数,因为stm32芯片集成的MAC配置对数据的接收和发送有很大的影响。

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默认参数需要自动配置    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-Tx Interrupt*/ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R | ETH_DMA_IT_T                    , ENABLE);

特别注意:以太网底层部分我主要遇到的bug有两个

 (1).启动时需要插上网线,否则启动后以太网工作不正常     问题原因:
ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable; //开启PHY的自适应

如果开启了自适应(默认代码是Enable,这就是坑的地方),ETH_Init中会有下面一段

do
{ 
       
  timeout++;
} while (!(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & PHY_Linked_Status) && (timeout < PHY_READ_TO));

 /* Return ERROR in case of timeout */
if(timeout == PHY_READ_TO)
{ 
       
    return ETH_ERROR;
}

也就是说一段时间没有读到link状态,就跳出ETH的配置函数了,这也就导致了stm的eth模块直接没有初始化(phy即使配置失败或者不配置也会根据外部引脚有默认的配置), 然而stm的官方库却直接跳出,不得不说是很严重的bug。

解决办法: 将ETH_AutoNegotiation_Enable改为ETH_AutoNegotiation_Disable, 根据实际情况配置即可。

(2) 网络有丢包和卡顿

这个问题其实是上述问题解决后衍生的问题,因为产品更换过几次phy,用的同一套驱动,结果有的工作正常,有的虽然能工作,但又大数量的丢包。

后来测试发现,更换phy后,不同phy的设置寄存器有差异, 出问题的写入出错,而默认配置与stm32内部不一致,导致丢包。解决问题发现如果不细致维护ETH_Init这个库函数中读写寄存器部分,适配PHY在软件上解决很麻烦,不过在对比了几家phy的说明书后,通过硬件修改配置引脚高低,可以轻松完成stm32与PHY的适配。

解决办法: 完全注释掉ETH_Init中与phy相关的配置,通过外部引脚硬件完成与stm适配,目前测试有dp83848, ip101alf, ip101gr, RTL8201等phy芯片都完美运行。

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

参见http://www.cnblogs.com/zc110747/p/4739588.html设置

标签: 502100alf连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台