我们使用的是sergeykharenko/ch182 • v0.0.1 • ESP Component Registry 这个组件库首先感谢作者的开源提供该组件库感谢乐鑫及沁恒官方提供的技术支持。下面是原理图部分该芯片数据手册CH182D -PDF数据手册-参考资料-立创商城下面是软件驱动部分首先我们创建一个空项目我这里以ESP32-P4为例。打开控制台输入idf.py add-dependency sergeykharenko/ch182^0.0.1运行后可以发现自动新建了一个idf_component.yml文件并且发现这个组件已经加入下面我们编译一下可以看到这个组件已经被我们引入进来。编写main.c文件/* * CH182D以太网驱动主程序 * 基于用户引脚配置的ETH_2 (RMII接口) * CH182D 输出 REFCLK 到 ESP32-P4 */ #include stdio.h #include string.h #include freertos/FreeRTOS.h #include freertos/task.h #include esp_netif.h #include esp_eth.h #include esp_eth_phy_ch182.h #include esp_event.h #include esp_log.h #include driver/gpio.h #include sdkconfig.h // ETH_2 配置 (RMII, 使用CH182D PHY) #define ETH0_RMII_RXD1_GPIO 47 #define ETH0_RMII_RXD0_GPIO 46 #define ETH0_RMII_CRS_DV_GPIO 45 #define ETH0_RMII_CLK_GPIO 44 #define ETH0_RMII_TXD1_GPIO 42 #define ETH0_RMII_TXD0_GPIO 41 #define ETH0_RMII_TX_EN_GPIO 40 #define ETH0_MDIO_GPIO 22 #define ETH0_MDC_GPIO 23 #define ETH0_RST_GPIO 33 #define ETH0_PHY_ADDR 1 static const char *TAG eth_main; // 以太网句柄 static esp_eth_handle_t s_eth_handle NULL; // 获取IP地址事件处理 static void got_ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { ip_event_got_ip_t *event (ip_event_got_ip_t *) event_data; const esp_netif_ip_info_t *ip_info event-ip_info; ESP_LOGI(TAG, ); ESP_LOGI(TAG, Ethernet Got IP Address); ESP_LOGI(TAG, ~~~~~~~~~~~); ESP_LOGI(TAG, IP: IPSTR, IP2STR(ip_info-ip)); ESP_LOGI(TAG, MASK: IPSTR, IP2STR(ip_info-netmask)); ESP_LOGI(TAG, GATEWAY: IPSTR, IP2STR(ip_info-gw)); ESP_LOGI(TAG, ~~~~~~~~~~~); ESP_LOGI(TAG, ); } /** * brief 初始化以太网接口 */ static esp_err_t eth0_init(esp_eth_handle_t *eth_handle) { esp_err_t ret ESP_OK; // 配置RMII引脚 (ESP32-P4) eth_esp32_emac_config_t esp32_emac_config ETH_ESP32_EMAC_DEFAULT_CONFIG(); // 设置SMI (MDIO/MDC) 引脚 esp32_emac_config.smi_gpio.mdc_num ETH0_MDC_GPIO; esp32_emac_config.smi_gpio.mdio_num ETH0_MDIO_GPIO; // 设置RMII数据引脚 esp32_emac_config.emac_dataif_gpio.rmii.tx_en_num ETH0_RMII_TX_EN_GPIO; esp32_emac_config.emac_dataif_gpio.rmii.txd0_num ETH0_RMII_TXD0_GPIO; esp32_emac_config.emac_dataif_gpio.rmii.txd1_num ETH0_RMII_TXD1_GPIO; esp32_emac_config.emac_dataif_gpio.rmii.crs_dv_num ETH0_RMII_CRS_DV_GPIO; esp32_emac_config.emac_dataif_gpio.rmii.rxd0_num ETH0_RMII_RXD0_GPIO; esp32_emac_config.emac_dataif_gpio.rmii.rxd1_num ETH0_RMII_RXD1_GPIO; // 设置RMII时钟配置 - CH182D 输出 REFCLK 到 ESP32-P4 esp32_emac_config.clock_config.rmii.clock_mode EMAC_CLK_EXT_IN; esp32_emac_config.clock_config.rmii.clock_gpio ETH0_RMII_CLK_GPIO; // 配置MAC eth_mac_config_t mac_config ETH_MAC_DEFAULT_CONFIG(); // 配置PHY eth_phy_config_t phy_config ETH_PHY_DEFAULT_CONFIG(); phy_config.phy_addr ETH0_PHY_ADDR; phy_config.reset_gpio_num ETH0_RST_GPIO; // phy_config.post_hw_reset_delay_ms 100; // 如果出现硬件重启超时导致芯片重启的情况试一下硬件复位后等待100ms // 使用CH182 PHY驱动 - CH182D输出REFCLK esp_eth_phy_t *phy esp_eth_phy_new_ch182(phy_config); // 创建MAC实例 esp_eth_mac_t *mac esp_eth_mac_new_esp32(esp32_emac_config, mac_config); // 创建以太网驱动实例 esp_eth_config_t eth_config ETH_DEFAULT_CONFIG(mac, phy); ret esp_eth_driver_install(eth_config, eth_handle); if (ret ! ESP_OK) { ESP_LOGE(TAG, Failed to install Ethernet driver: %s, esp_err_to_name(ret)); return ret; } ESP_LOGI(TAG, Ethernet driver initialized successfully); ESP_LOGI(TAG, PHY: CH182D at address %d, ETH0_PHY_ADDR); ESP_LOGI(TAG, Interface: RMII); ESP_LOGI(TAG, Clock: CH182D OUT - ESP32-P4 IN); ESP_LOGI(TAG, SMI: MDCGPIO%d, MDIOGPIO%d, ETH0_MDC_GPIO, ETH0_MDIO_GPIO); ESP_LOGI(TAG, RX: RXD0GPIO%d, RXD1GPIO%d, CRS_DVGPIO%d, ETH0_RMII_RXD0_GPIO, ETH0_RMII_RXD1_GPIO, ETH0_RMII_CRS_DV_GPIO); ESP_LOGI(TAG, TX: TXD0GPIO%d, TXD1GPIO%d, TX_ENGPIO%d, ETH0_RMII_TXD0_GPIO, ETH0_RMII_TXD1_GPIO, ETH0_RMII_TX_EN_GPIO); ESP_LOGI(TAG, CLK: GPIO%d (input from CH182D), ETH0_RMII_CLK_GPIO); ESP_LOGI(TAG, RST: GPIO%d, ETH0_RST_GPIO); return ESP_OK; } /** * brief 以太网事件处理函数 */ static void eth0_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { switch (event_id) { case ETHERNET_EVENT_CONNECTED: ESP_LOGI(TAG, Ethernet Link Up); break; case ETHERNET_EVENT_DISCONNECTED: ESP_LOGW(TAG, Ethernet Link Down); break; case ETHERNET_EVENT_START: ESP_LOGI(TAG, Ethernet Started); break; case ETHERNET_EVENT_STOP: ESP_LOGI(TAG, Ethernet Stopped); break; default: break; } } void app_main(void) { ESP_LOGI(TAG, ); ESP_LOGI(TAG, CH182D Ethernet Driver); ESP_LOGI(TAG, ); ESP_LOGI(TAG, ); // 初始化TCP/IP网络接口 ESP_ERROR_CHECK(esp_netif_init()); // 创建默认事件循环 ESP_ERROR_CHECK(esp_event_loop_create_default()); // 创建默认的以太网网络接口 esp_netif_config_t cfg ESP_NETIF_DEFAULT_ETH(); esp_netif_t *eth_netif esp_netif_new(cfg); // 注册事件处理器 ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler, NULL)); ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, eth0_event_handler, NULL)); // 初始化以太网驱动 ESP_ERROR_CHECK(eth0_init(s_eth_handle)); // 将以太网驱动附加到TCP/IP协议栈 ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(s_eth_handle))); // 启动以太网驱动 ESP_LOGI(TAG, Starting Ethernet driver...); ESP_ERROR_CHECK(esp_eth_start(s_eth_handle)); ESP_LOGI(TAG, ); ESP_LOGI(TAG, Waiting for IP address...); ESP_LOGI(TAG, ); // 主循环 - 保持运行 while (1) { vTaskDelay(pdMS_TO_TICKS(5000)); } }编译运行即可但运行时发现LINK指示灯在网线插入前闪烁插入后不闪烁ACT指示灯指示正常我看到组件中ch182.h文件中ETH_DEFAULT_LED_MODE可以更换指示灯模式但我全都试了一边发现并没有正确的模式。各位大佬如果看出哪里有问题请在评论区说一下。注意事项硬件方面需要注意的是如果CH182D外接晶振并且由CH182D提供RMII_CLK的话RXD0引脚不要接上拉电阻这个在数据手册中有体现。并且TX RX这些引脚也不需要接上拉这些在CH182D内部已接上拉、下拉。在终端中引入组件时报错无法将“idf.py”项识别为 cmdlet、函数、脚本文件或可运行解决办法是打开的这个ESP-IDF Terminal 这个终端才能正常运行。烧录中报错A fatal error occurred: bootloader/bootloader.bin requires chip revision in range [v3.1 - v3.99] (this chip is revision v1.3). Use --force to flash anyway.解决办法将menuconfig中Chip revision改为V1.0 , 改完保存重新编译下载。