ESP32-S3 + W5500 SPI 以太网模块:LAN8720 为什么不亮灯,有线网络怎么快速跑通
【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32
一块 LAN8720,上电之后黑灯
先说现场:模块上电,链路灯不亮,串口反复刷出 PHY 探测失败的日志。换线、重刷固件、甚至换了块板子,结果一样。😤 后来才发现根本不是批次质量的问题——你手里的 ESP32-S3,压根没有以太网 MAC。RMII PHY 在它身上找不到"对端",灯不亮是结构性的正常现象。换成 W5500 SPI 以太网模块之后,同一块板子当天下午就通了网。
为什么 S3 点不亮 RMII 的灯
很多教程里的 LAN8720 接法,照抄的是原版 ESP32 或 ESP32-Ethernet-Kit 的方案:那两颗 SoC 片内带以太网 MAC,RMII 几根信号线一接就能收帧。ESP32-S3 走的是 Wi-Fi/蓝牙产品线,以太网 MAC 被整体裁掉了。PHY 的引脚线接得再齐,芯片内部也没有协议引擎去接住这些帧。
所以 S3 上做有线网络,思路要换:把协议栈整个外包给 W5500。它片内自带完整的 TCP/IP 栈,支持 10/100Mbps,还有 32KB 收发缓冲。ESP32-S3 退化成"读寄存器的",通过 SPI 和它对话——主控负担轻,接线也少。
两条路线,一张表看明白
| 对比项 | RMII 直连(LAN8720 等) | SPI 外挂(W5500) |
|---|---|---|
| 对 SoC 的要求 | 必须有以太网 MAC,ESP32-S3 不满足 | 只需 SPI + GPIO,S3 完全支持 |
| 协议栈位置 | 主控跑,占用 CPU | W5500 片内硬/软栈,主控几乎零负担 |
| 速率上限 | 100Mbps | 100Mbps(实际受 SPI 时钟约束) |
| 收发缓冲 | 主控内存 | 片内 32KB |
| 接线复杂度 | RMII 多信号线,时序敏感 | 4 根 SPI + CS/INT/RST,容错高 |
最快接线方法:5 根线搞定
接线前先看板子上哪些引脚空闲。下面这套编号来自官方示例的默认配置;ESP32 的 GPIO matrix 允许把 SPI 重映射到任意引脚,避开 flash/PSRAM 占用的脚即可。
| W5500 引脚 | 接到 ESP32-S3 | 作用 |
|---|---|---|
| SCK | GPIO14 | SPI 时钟 |
| MISO | GPIO12 | 从出主入,W5500 读数据 |
| MOSI | GPIO13 | 主出从入,W5500 写数据 |
| CS | GPIO15 | 片选 |
| INT | GPIO4 | 中断通知,可不接 |
| RST | GPIO5 | 硬件复位,强烈建议接 |
其中 INT 是"有则更好":没接中断线时,Ethernet 库会自动改用轮询方式检查 W5500 状态,配合setPollPeriod()设置轮询周期,功能不受影响。
跑通第一帧:最小初始化示例
第 1 步,在 Arduino IDE 的 Boards Manager 里搜索 esp32 安装板卡包,选中对应 ESP32-S3 的开发板。
第 2 步,新建工程,包含ETH.h和SPI.h。 第 3 步,SPI.begin之后调用ETH.begin,把 PHY 类型、CS、INT、RST 和 SPI 对象传进去。 第 4 步,打开串口监视器(115200),看到ETH Connected并打印出 IP,第一帧就算通了。 第 5 步,发一个 HTTP GET 验证整条链路。
#include <ETH.h> #include <SPI.h> void setup() { Serial.begin(115200); SPI.begin(14, 12, 13); // SCK, MISO, MOSI ETH.begin(ETH_PHY_W5500, 1, 15, 4, 5, SPI); // CS, INT, RST } void loop() { // 打印 ETH.localIP() 或发起网络连接 }完整事件处理和双网卡写法可参考 ETH_W5500_Arduino_SPI,头文件注释里还有 SPI 引脚与轮询的相关定义,见 ETH.h。
调优、避坑与 FAQ
默认 SPI 频率是 20MHz(ETH_PHY_SPI_FREQ_MHZ)。这个速率下总线理论带宽约 160Mbit/s,考虑协议开销后跑 60~80Mbps 稳定传输不难,但确实够不到 100Mbps 满速。想提速就调高 SPI 时钟,前提是模块和走线扛得住。
几个高频坑位:
- 上电拿不到 IP:先查 RST。不少模块出厂时 RST 悬空,W5500 停在半死状态,不接到 MCU 上做一次复位,后面排查全是白费。
- 速度上不去 100M:正常现象,先调 SPI 时钟,再看单次收发的数据块大小。
- INT 没接会不会挂:不会,
setPollPeriod()在begin()之前调用即可。 - SPI 引脚和屏幕、PSRAM 撞车:S3 带 PSRAM 的板子先查内存占用的引脚,把 SPI 重映射到另一组。
- 想挂两块 W5500:可以。同一条 SPI 总线挂两个片选,示例里的
ETH1实例就是这么做的,Wi-Fi 转以太网桥接也是顺手的延伸方向。
先烧一遍上面的最小示例,盯着串口等到 IP 出现,再谈上层服务——这是最省时间的顺序。
【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考