STM32H743 SOEM EtherCAT主站源码及配套CUBE工程
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 驱动 的完整工作流程进行逐层拆解,帮助开发者快速理解:
- 驱动在整个 SOEM 中的位置与职责
- 上电 → 链路建立 → EtherCAT 报文收发 的完整调用链
- 关键寄存器配置与状态机切换
- 移植/调试时常踩的坑与定位技巧
一、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 的集成要点
- 初始化时机
– 板级初始化阶段就调用LAN8742_Init,确保 SOEM 第一次发包前链路已 up
– 若使用 FreeRTOS,可创建 PHY 监控任务(周期 100 ms),链路丢失时点亮红灯并尝试重新协商
- 中断模式(可选)
LAN8742 支持 Link-Change-Interrupt,引脚可接 STM32 外部中断线。
在链路变化 ISR 中置位事件,主循环再调用LAN8742_GetLinkState即可,避免轮询。
- 寄存器位宽注意
– 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 晶振波形;替换网线排除接触不良 |
六、小结
- LAN8742 驱动是 SOEM 链路层健壮性的第一道关;链路未 ready 时,SOEM 任何帧都发不出去,表现就是 “no slave found”。
- 驱动本身已高度封装,用户只需 注册 IO 接口 + 调用 Init/GetLinkState 即可。
- 真正容易踩坑的是 初始化时机 与 中断优先级(若启用 Link-Change-IRQ)。务必在 SOEM 扫描前确保链路 up,否则所有后续逻辑都无法展开。
掌握以上要点,即可在 STM32H743 平台(或其他 Cortex-M7)上快速、稳定地把 SOEM 主站跑到 OPERATIONAL 状态,为后续伺服适配、分布时钟、PDO 交换打下坚实基础。

更多推荐
所有评论(0)