1 網口資源介紹
STM32F407 是 STMicroelectronics 推出的高性能 ARM Cortex-M4 微控制器,具備多種外設接口,其中包括一個 Ethernet MAC 控制器(帶 IEEE 1588 支持)。這意味著你可以使用 STM32F407 實現網絡通信功能(通過網口,即以太網口)。
1.1 STM32F407 的以太網特性
MAC 層支持:集成的以太網 MAC(ENET),支持 10/100 Mbps 全雙工/半雙工通信。
需要外部 PHY 芯片:STM32F407 只提供 MAC 控制器,需要通過 RMII 或 MII 接口 連接外部 PHY 芯片(如 LAN8720、DP83848 等)來實現物理層通信。
支持 DMA:支持以太網 DMA,提高數據吞吐效率。
支持 LWIP 協議棧:可以使用 LWIP(輕量級 IP 協議棧)來實現 TCP/IP 協議通信。
1.2 連接方式
硬件連接
PHY 芯片(如 LAN8720):通過 RMII 接口與 STM32F407 連接。
晶振要求:通常 PHY 需要 50MHz 時鐘,STM32F407 可通過 MCO 輸出時鐘。
RJ45 接口:連接外部網絡,部分模塊集成了變壓器和 PHY。
接口引腳(RMII 模式),常用引腳如下:
對應電路圖
1.3 常見應用
-
TCP/UDP 通信
-
遠程控制設備
-
嵌入式 Web 服務器(通過 LWIP + HTTPD)
-
Modbus-TCP、MQTT 等協議實現
2 代碼初始化流程
2.1 配置 GPIO 引腳
使用 GPIO_InitTypeDef,設置 RMII 所需引腳為 復用功能 + 高速 + 無上下拉。
void ETH_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;/* Enable GPIOs clocks */RCC_AHB1PeriphClockCmd(ETH_MDIO_GPIO_CLK | ETH_MDC_GPIO_CLK |ETH_RMII_REF_CLK_GPIO_CLK | ETH_RMII_CRS_DV_GPIO_CLK |ETH_RMII_RXD0_GPIO_CLK | ETH_RMII_RXD1_GPIO_CLK |ETH_RMII_TX_EN_GPIO_CLK | ETH_RMII_TXD0_GPIO_CLK |ETH_RMII_TXD1_GPIO_CLK | ETH_NRST_GPIO_CLK , ENABLE);/* Enable SYSCFG clock */RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); /* MII/RMII Media interface selection --------------------------------------*/
#ifdef MII_MODE /* Mode MII with STM324xx-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);
#elif defined RMII_MODE /* Mode RMII with STM324xx-EVAL */SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII);
#endif/* Ethernet pins configuration ************************************************//*ETH_MDIO -------------------------> PA2ETH_MDC --------------------------> PC1ETH_MII_RX_CLK/ETH_RMII_REF_CLK---> PA1ETH_MII_RX_DV/ETH_RMII_CRS_DV ----> PA7ETH_MII_RXD0/ETH_RMII_RXD0 -------> PC4ETH_MII_RXD1/ETH_RMII_RXD1 -------> PC5ETH_MII_TX_EN/ETH_RMII_TX_EN -----> PB11ETH_MII_TXD0/ETH_RMII_TXD0 -------> PG13ETH_MII_TXD1/ETH_RMII_TXD1 -------> PG14ETH_NRST -------------------------> PI1*/GPIO_InitStructure.GPIO_Pin = ETH_NRST_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(ETH_NRST_PORT, &GPIO_InitStructure);ETH_NRST_PIN_LOW();_eth_delay_(LAN8720A_RESET_DELAY);ETH_NRST_PIN_HIGH();_eth_delay_(LAN8720A_RESET_DELAY);/* Configure ETH_MDIO */GPIO_InitStructure.GPIO_Pin = ETH_MDIO_PIN;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(ETH_MDIO_PORT, &GPIO_InitStructure);GPIO_PinAFConfig(ETH_MDIO_PORT, ETH_MDIO_SOURCE, ETH_MDIO_AF);/* Configure ETH_MDC */GPIO_InitStructure.GPIO_Pin = ETH_MDC_PIN;GPIO_Init(ETH_MDC_PORT, &GPIO_InitStructure);GPIO_PinAFConfig(ETH_MDC_PORT, ETH_MDC_SOURCE, ETH_MDC_AF);/* Configure ETH_RMII_REF_CLK */GPIO_InitStructure.GPIO_Pin = ETH_RMII_REF_CLK_PIN;GPIO_Init(ETH_RMII_REF_CLK_PORT, &GPIO_InitStructure);GPIO_PinAFConfig(ETH_RMII_REF_CLK_PORT, ETH_RMII_REF_CLK_SOURCE, ETH_RMII_REF_CLK_AF);/* Configure ETH_RMII_CRS_DV */GPIO_InitStructure.GPIO_Pin = ETH_RMII_CRS_DV_PIN;GPIO_Init(ETH_RMII_CRS_DV_PORT, &GPIO_InitStructure);GPIO_PinAFConfig(ETH_RMII_CRS_DV_PORT, ETH_RMII_CRS_DV_SOURCE, ETH_RMII_CRS_DV_AF);/* Configure ETH_RMII_RXD0 */GPIO_InitStructure.GPIO_Pin = ETH_RMII_RXD0_PIN;GPIO_Init(ETH_RMII_RXD0_PORT, &GPIO_InitStructure);GPIO_PinAFConfig(ETH_RMII_RXD0_PORT, ETH_RMII_RXD0_SOURCE, ETH_RMII_RXD0_AF);/* Configure ETH_RMII_RXD1 */GPIO_InitStructure.GPIO_Pin = ETH_RMII_RXD1_PIN;GPIO_Init(ETH_RMII_RXD1_PORT, &GPIO_InitStructure);GPIO_PinAFConfig(ETH_RMII_RXD1_PORT, ETH_RMII_RXD1_SOURCE, ETH_RMII_RXD1_AF);/* Configure ETH_RMII_TX_EN */GPIO_InitStructure.GPIO_Pin = ETH_RMII_TX_EN_PIN;GPIO_Init(ETH_RMII_TX_EN_PORT, &GPIO_InitStructure);GPIO_PinAFConfig(ETH_RMII_TX_EN_PORT, ETH_RMII_TX_EN_SOURCE, ETH_RMII_TX_EN_AF);/* Configure ETH_RMII_TXD0 */GPIO_InitStructure.GPIO_Pin = ETH_RMII_TXD0_PIN;GPIO_Init(ETH_RMII_TXD0_PORT, &GPIO_InitStructure);GPIO_PinAFConfig(ETH_RMII_TXD0_PORT, ETH_RMII_TXD0_SOURCE, ETH_RMII_TXD0_AF);/* Configure ETH_RMII_TXD1 */GPIO_InitStructure.GPIO_Pin = ETH_RMII_TXD1_PIN;GPIO_Init(ETH_RMII_TXD1_PORT, &GPIO_InitStructure);GPIO_PinAFConfig(ETH_RMII_TXD1_PORT, ETH_RMII_TXD1_SOURCE, ETH_RMII_TXD1_AF);
}
2.2 MAC 寄存器配置
static void ETH_MACDMA_Config(void)
{/* Enable ETHERNET clock */RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | RCC_AHB1Periph_ETH_MAC_Tx |RCC_AHB1Periph_ETH_MAC_Rx, ENABLE);/* Reset ETHERNET on AHB Bus */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 *//*------------------------ MAC -----------------------------------*//* 開啟網絡自適應功能 */ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;
// ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Disable;
// ETH_InitStructure.ETH_Speed = ETH_Speed_10M;
// ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex; /* 關閉反饋 */ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;/* 關閉重傳功能 */ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable;/* 關閉自動去除PDA/CRC功能 */ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;/* 關閉接收所有的幀 */ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable;/* 允許接收所有廣播幀 */ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;/* 關閉混合模式的地址過濾 */ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;/* 對于組播地址使用完美地址過濾 */ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;/* 對單播地址使用完美地址過濾 */ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
#ifdef CHECKSUM_BY_HARDWARE/* 開啟ipv4和TCP/UDP/ICMP的幀校驗和卸載 */ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable;
#endif/*------------------------ DMA -----------------------------------*/ /* 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 *//*當我們使用幀校驗和卸載功能的時候,一定要使能存儲轉發模式,存儲轉發模式中要保證整個幀存儲在FIFO中,這樣MAC能插入/識別出幀校驗值,當真校驗正確的時候DMA就可以處理幀,否則就丟棄掉該幀*//* 開啟丟棄TCP/IP錯誤幀 */ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable;/* 開啟接收數據的存儲轉發模式 */ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;/* 開啟發送數據的存儲轉發模式 */ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;/* 禁止轉發錯誤幀 */ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;/* 不轉發過小的好幀 */ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable;/* 打開處理第二幀功能 */ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable;/* 開啟DMA傳輸的地址對齊功能 */ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;/* 開啟固定突發功能 */ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable;/* DMA發送的最大突發長度為32個節拍 */ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat;/*DMA接收的最大突發長度為32個節拍 */ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat;ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1;/* Configure Ethernet *//* 配置ETH */EthStatus = ETH_Init(Ð_InitStructure, ETHERNET_PHY_ADDRESS);
}