標籤:
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(Ð_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(Ð_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.未完待續
2.3 stm32移植lwip常見問題和解決方式