使用Arduino开发ESP32(06):Ethernet的使用(基于LAN8720)

使用Arduino开发ESP32(06):Ethernet的使用(基于LAN8720)文章目录目的基本说明接线定义使用步骤常用方法说明使用演示数据通讯事件响应其他说明 PHY 地址时钟通讯应用总结目的 ESP32 除了可以使用无线网络外还可以通过外接 PHY 模块来使用有线网络 Ethernet 以太网 本篇将介绍相关内容 基本说明本篇中使用常用的 PHY 芯片 LAN8720 的模块来来进行有线网络使用演示 接线定义下面是 ESP32 与 LAN8720 间 RMIIPHY 的连接定义 用于以

目的

ESP32除了可以使用无线网络外还可以通过外接PHY模块来使用有线网络(Ethernet:以太网),本篇将介绍相关内容。

基本说明

接线定义

下面是ESP32与LAN8720间RMII PHY的连接定义,用于以太网通信,下面几个针脚必须按定义连接:

GPIO RMII Signal ESP32 EMAC Function Notes
GPIO21 TX_EN EMAC_TX_EN
GPIO19 TX0 EMAC_TXD0
GPIO22 TX1 EMAC_TXD1
GPIO25 RX0 EMAC_RXD0
GPIO26 RX1 EMAC_RXD1
GPIO27 CRS_DV EMAC_RX_DRV

下面是ESP32与LAN8720间RMII PHY SMI的连接定义,用于ESP32读写LAN8720的寄存器,下面的针脚理论上可以连接到ESP32任何支持输出的针脚上:

Default Example GPIO RMII Signal Notes1 Notes2
GPIO23 MDC 输出至LAN8720 也可以使用ESP32其他输出脚
GPIO18 MDIO 双向通讯 也可以使用ESP32其他双向脚

使用步骤

  1. 引用以太网库#include
    ;
  2. 声明一个对象ETHClass myETH,默认的已经声明了一个名为ETH的对象;
  3. 使用begin()方法启动以太网连接;

常用方法说明

  • bool begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t type, eth_clock_mode_t clock_mode)
    启用以太网连接,参数说明如下:
    phy_addr:LAN8720写0或1、TLK110写31;
    power:设置ESP32某管脚,该管脚可以用来管理LAN8720供电,使能时输出高电平,失能时为低电平,写-1则不使用;
    mdc:mdc管脚编号,写-1则不使用;
    mdio:mdio管脚编号,写-1则不使用;
    type:PHY类型,ETH_PHY_LAN8720ETH_PHY_TLK110
    clock_mode:时钟模式,可选值ETH_CLOCK_GPIO0_INETH_CLOCK_GPIO0_OUTETH_CLOCK_GPIO16_OUTETH_CLOCK_GPIO17_OUT,详细介绍见后文;














  • bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000)
    设置IP地址、网关地址、子网掩码、dns地址;

  • const char * getHostname()
    获取主机名字;

  • bool setHostname(const char * hostname)
    设置主机名字;

  • bool fullDuplex()
    检查是否为全双工通讯;

  • uint8_t linkSpeed()
    获取传输速度,单位Mbps;

  • IPAddress localIP()
    获取IP地址;

  • IPAddress subnetMask()
    获取子网掩码;

  • IPAddress gatewayIP()
    获取网关地址;

  • IPAddress dnsIP(uint8_t dns_no = 0)
    获取dns服务器地址;

  • String macAddress()
    获取mac地址;

使用演示

数据通讯

使用下面代码进行以太网通讯演示:

#include  
     //引用以使用ETH #include  
      #define ETH_ADDR 1 #define ETH_POWER_PIN -1 #define ETH_MDC_PIN 23 #define ETH_MDIO_PIN 18 #define ETH_TYPE ETH_PHY_LAN8720 #define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT WiFiUDP Udp; //创建UDP对象 unsigned int localUdpPort = 2333; //本地端口号 void setup() { 
    Serial.begin(); Serial.println(); ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE); //启用ETH while(!((uint32_t)ETH.localIP())) //等待获取到IP { 
    } Serial.println("Connected"); Serial.print("IP Address:"); Serial.println(ETH.localIP()); Udp.begin(localUdpPort); //启用UDP监听以接收数据 } void loop() { 
    int packetSize = Udp.parsePacket(); //获取当前队首数据包长度 if (packetSize) //如果有数据可用 { 
    char buf[packetSize]; Udp.read(buf, packetSize); //读取当前包数据 Serial.println(); Serial.print("Received: "); Serial.println(buf); Serial.print("From IP: "); Serial.println(Udp.remoteIP()); Serial.print("From Port: "); Serial.println(Udp.remotePort()); Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //准备发送数据 Udp.print("Received: "); //复制数据到发送缓存 Udp.write((const uint8_t*)buf, packetSize); //复制数据到发送缓存 Udp.endPacket(); //发送数据 } } 

在这里插入图片描述
上面例子中启用以太网等待获取到IP,然后用UDP进行了通讯测试;

事件响应

使用下面代码进行以太网事件演示:

#include  
     //引用以使用ETH #define ETH_ADDR 1 #define ETH_POWER_PIN -1 #define ETH_MDC_PIN 23 #define ETH_MDIO_PIN 18 #define ETH_TYPE ETH_PHY_LAN8720 #define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT void printETHInfo(void) //打印基本信息 { 
    Serial.print("ETH MAC: "); Serial.print(ETH.macAddress()); Serial.print(", IPv4: "); Serial.print(ETH.localIP()); if (ETH.fullDuplex()) { 
    Serial.print(", FULL_DUPLEX"); } Serial.print(", "); Serial.print(ETH.linkSpeed()); Serial.println("Mbps"); } void WiFiEvent(WiFiEvent_t event) { 
    switch (event) { 
    case SYSTEM_EVENT_ETH_START: //启动ETH成功 Serial.println("ETH Started"); break; case SYSTEM_EVENT_ETH_CONNECTED: //接入网络 Serial.println("ETH Connected"); break; case SYSTEM_EVENT_ETH_GOT_IP: //获得IP Serial.println("ETH GOT IP"); printETHInfo(); break; case SYSTEM_EVENT_ETH_DISCONNECTED: //失去连接 Serial.println("ETH Disconnected"); break; case SYSTEM_EVENT_ETH_STOP: //关闭 Serial.println("ETH Stopped"); break; default: break; } } void setup() { 
    Serial.begin(); Serial.println(); WiFi.onEvent(WiFiEvent); //注册事件 ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE); //启用ETH } void loop() { 
    delay(10000); esp_eth_disable(); //关闭eth } 

在这里插入图片描述
上面演示时在获取到IP地址后我将网线拔了,手动触发了SYSTEM_EVENT_ETH_DISCONNECTED事件;
有事件的话其实上个例子中while(!((uint32_t)ETH.localIP())){} //等待获取到IP这句就可以用事件来处理了;




其他说明

PHY地址

PHY地址LAN8720写0或1、TLK110写31,LAN8720使用0还是1由芯片复位时RXER引脚电平决定,当该引脚接下拉电阻或者浮空(芯片内部下拉)时,地址就为0,当引脚接上拉电阻时地址为1;
上文使用的模块电路中RXER脚外接了上拉电阻,所以地址写1;

时钟

理论上LAN8720和ESP32需要有同一个时钟源用于以太网通讯,ESP32提供了四种方式来处理时钟:

Mode GPIO Pin Signal name Notes
external GPIO0 EMAC_TX_CLK Input of 50MHz PHY clock
internal GPIO0 CLK_OUT1 Output of 50MHz APLL clock. Signal quality might be an issue.
internal GPIO16 EMAC_CLK_OUT Output of 50MHz APLL clock.
internal GPIO17 EMAC_CLK_180 Inverted output of 50MHz APLL clock. Found to be best suitable for LAN8720 with long signal lines.

通讯应用

除UDP外,Ethernet也可以使用WiFiClient和WiFiServer等通讯功能;

总结

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/207832.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午12:59
下一篇 2026年3月19日 下午1:00


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号