STM32H743 SOEM EtherCAT基于STM32H743芯片和SOEM的EtherCAT主站源码 提供配套CUBE工程。 SOEM协议栈使用1.3.1版本。 可配套NUCLEO-H743ZI开发板使用。 支持DC同步。 可配合汇川IS620N、三洋RS3、赛孚德ASD620B、埃斯顿ProNet、迈信EP3E、台达A2-E、伟创SD700、松下A5B/A6B和欧姆龙G5系列驱动器使用,或提供想适配的驱动器型号。

SOEM(Simple Open EtherCAT Master)是一套精简、开源的 EtherCAT 主站协议栈。本文以 STM32H743 平台为例,结合 SOEM-1.3.1 源码,对 LAN8742 以太网 PHY 驱动 的完整工作流程进行逐层拆解,帮助开发者快速理解:

  1. 驱动在整个 SOEM 中的位置与职责
  2. 上电 → 链路建立 → EtherCAT 报文收发 的完整调用链
  3. 关键寄存器配置与状态机切换
  4. 移植/调试时常踩的坑与定位技巧

一、LAN8742 在 SOEM 架构中的角色

┌-----------------┐
│ 应用层          │  simple_test.c
├-----------------┤
│ EtherCAT 协议栈 │  SOEM(ethercatmain / ethercatbase ...)
├-----------------┤
│ 网卡驱动        │  nicdrv.c  (ecx_outframe / ecx_recvpkt)
├-----------------┤
│ PHY 驱动        │  lan8742.c (本文主角)
├-----------------┤
│ 硬件            │  STM32H743 + LAN8742
└-----------------┘
  • 职责边界
    – LAN8742 驱动仅负责 PHY 芯片自身的初始化、链路状态检测、中断配置
    MAC 层(STM32 ETH 外设)由 ST 官方 HAL 处理;帧收发由 nicdrv.c 完成
    – SOEM 通过 ec_slave[] 结构感知链路,对 PHY 透明

二、初始化流程(代码级时序)

以下代码路径基于 SOEM 官方 demo 适配到 STM32H743 的工程:

main()
 └─ ec_config_init()          // 1. 扫描总线,识别从站
     └─ ecx_outframe()        // 2. 第一次发送广播帧 → 需要网卡/PHY 已就绪
         └─ ETH_HAL_Transmit()// 3. 最终调用 ST HAL

问题:第一次调用 ecx_outframe 时,PHY 可能还没链路 up,会导致 发送超时接收不到任何报文,SOEM 报 “no slave found”。

STM32H743 SOEM EtherCAT基于STM32H743芯片和SOEM的EtherCAT主站源码 提供配套CUBE工程。 SOEM协议栈使用1.3.1版本。 可配套NUCLEO-H743ZI开发板使用。 支持DC同步。 可配合汇川IS620N、三洋RS3、赛孚德ASD620B、埃斯顿ProNet、迈信EP3E、台达A2-E、伟创SD700、松下A5B/A6B和欧姆龙G5系列驱动器使用,或提供想适配的驱动器型号。

解决:在 ecconfiginit 之前,必须完成 LAN8742 初始化 + 链路检测;SOEM 原生代码没有显式调用,需要用户在板级初始化阶段主动完成。


三、LAN8742 驱动源码拆解

3.1 对象模型

typedef struct {
    uint32_t            DevAddr;      // 实际扫描到的 PHY 地址(0~31)
    uint32_t            Is_Initialized;
    lan8742_IOCtx_t     IO;          // 底层读写钩子
    void               *pData;        // 私有扩展
} lan8742_Object_t;
  • DevAddr 由驱动在初始化时 自动探测,无需用户指定
  • IO 成员 需要用户在调用 LAN8742_RegisterBusIO 时填充 HAL 层函数指针,实现真正的 MDIO 读写

3.2 初始化细粒度流程

LAN8742_Init()
├─ 1. 探测地址(0~31)
│   ├─ 读 LAN8742_SMR (0x12) 寄存器
│   └─ 比对 (reg & LAN8742_SMR_PHY_ADDR) == addr
├─ 2. 软件复位
│   ├─ 写 LAN8742_BCR_SOFT_RESET
│   └─ 轮询 500 ms 直到复位完成
├─ 3. 等待 2 s 自协商(固件要求)
└─ 4. 置 Is_Initialized = 1

关键寄存器

寄存器 地址 作用
BCR 0x00 复位、自协商使能、速率/双工
BSR 0x01 链路状态、自协商完成
PHYSCSR 0x1F 实际协商速率(10/100 M,全/半双工)

3.3 链路状态查询(SOEM 调用点)

SOEM 主循环会周期性调用:

int32_t LAN8742_GetLinkState(&lan8742);

返回值:

宏定义 含义
LAN8742STATUSLINK_DOWN 1 未连接
LAN8742STATUS100MBITS_FULLDUPLEX 2 百兆全双工
LAN8742STATUSAUTONEGO_NOTDONE 6 协商中

应用示例

simple_test.c 主循环加入:

while (1) {
    int32_t ls = LAN8742_GetLinkState(&lan8742);
    if (ls == LAN8742_STATUS_LINK_DOWN) {
        LED_RED_ON();
    } else {
        LED_GREEN_ON();
    }
    /* 继续 SOEM 业务 */
    ec_statecheck(0, EC_STATE_OPERATIONAL, 50000);
}

四、与 SOEM 的集成要点

  1. 初始化时机
    板级初始化阶段就调用 LAN8742_Init,确保 SOEM 第一次发包前链路已 up
    – 若使用 FreeRTOS,可创建 PHY 监控任务(周期 100 ms),链路丢失时点亮红灯并尝试重新协商
  1. 中断模式(可选)
    LAN8742 支持 Link-Change-Interrupt,引脚可接 STM32 外部中断线。
    在链路变化 ISR 中置位事件,主循环再调用 LAN8742_GetLinkState 即可,避免轮询。
  1. 寄存器位宽注意
    – LAN8742 寄存器均为 16 bit,但 STM32 HAL 的 HALETHReadPHYRegister 返回 uint32_t
    – 驱动内部已做掩码处理,用户无需二次屏蔽

五、调试/移植速查表

现象 可能原因 定位手段
扫描不到从站 PHY 地址探测失败 检查 MDIO 线路、确认复位脚、打印 lan8742.DevAddr
链路一直 DOWN 自协商关闭/强制速率不匹配 读 BCR 寄存器,看是否置位 AUTONEGO_EN
发帧成功但收不到 RX 时钟、引脚复用错误 示波器量 RMII RXD0/1、CRSDV;检查 HALETH_Init 返回值
运行一段时间掉线 晶振温漂、电源噪声 用示波器量 50 MHz 晶振波形;替换网线排除接触不良

六、小结

  1. LAN8742 驱动是 SOEM 链路层健壮性的第一道关;链路未 ready 时,SOEM 任何帧都发不出去,表现就是 “no slave found”。
  2. 驱动本身已高度封装,用户只需 注册 IO 接口 + 调用 Init/GetLinkState 即可。
  3. 真正容易踩坑的是 初始化时机中断优先级(若启用 Link-Change-IRQ)。务必在 SOEM 扫描前确保链路 up,否则所有后续逻辑都无法展开。

掌握以上要点,即可在 STM32H743 平台(或其他 Cortex-M7)上快速、稳定地把 SOEM 主站跑到 OPERATIONAL 状态,为后续伺服适配、分布时钟、PDO 交换打下坚实基础。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐