告别网络依赖!用QGIS 3.28把谷歌卫星地图“搬”到本地硬盘的保姆级教程
2026/4/17 17:57:21
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 快速上手”,而是一份代码级移植工程日志:
阅读前你需要:
Drivers/BSP/Components/lan8742/ ├── lan8742.c // 本文主角:PHY 状态机 + 算法 ├── lan8742.h // 寄存器掩码 + 状态枚举 ├── lan8742_conf_template.h // 用户裁剪:中断引脚、调试等级 └── readme_lan8742_porting.md // 官方没给,本文补齐 Middlewares/Third_Party/SOEM/ ├── nicdrv.c // 调用 LAN8742_GetLinkState() ├── ethercatmain.c // 周期性调用 nicdrv ├── ethercatdc.c // 需要 PHY 先 up,否则 DC 校准直接失败 └── osal_stm32h7.c // 1 ms 基准,与 PHY 中断联动| 函数簇 | 典型函数 | 行数 | 关键算法 | 复杂度 |
|---|---|---|---|---|
| 探测 | LAN8742_Init() | 120 | 自适应地址探测+异常隔离 | O(32) |
| 链路 | GetLinkState() | 180 | 三阶状态机+双采样消抖 | O(1) |
| 中断 | EnableIT() | 60 | 读-改-写屏蔽算法 | O(1) |
| 节能 | PowerDown() | 40 | IEEE 802.3 Clause 22 掉电序列 | O(1) |
| 回环 | Loopback() | 30 | 远端回环用于自测 | O(1) |
| 注入 | RegisterBusIO() | 20 | 依赖倒置方便单元测试 | O(1) |
| 信号 | STM32H743 引脚 | LAN8742 引脚 | 上拉/下拉 | 备注 |
|---|---|---|---|---|
| MDC | PC1 | 23 | 1.5 kΩ→3V3 | 频率 ≤ 2.5 MHz |
| MDIO | PA2 | 24 | 1.5 kΩ→3V3 | 开漏,需上拉 |
| nRST | PG3 | 18 | 10 kΩ→3V3 | ≥ 10 ms 低电平 |
| nINT | PG2 | 14 | 10 kΩ→3V3 | 可选,中断模式 |
| RMIIREFCLK | PA1 | 25 | 50 MHz | 晶振或 MCU 输出 |
/* 文件:test_mdio.c */ void test_mdio_basic(void) { uint32_t id1, id2; HAL_ETH_ReadPHYRegister(&heth, 0x02, &id1); HAL_ETH_ReadPHYRegister(&heth, 0x03, &id2); uint32_t oui = (id1<<6) | (id2>>10); configASSERT(oui == 0x0007C0); /* Microchip OUI */ }HALRCCGPIOACLKENABLE()for (addr = 0; addr <= LAN8742_MAX_DEV_ADDR; addr++) { /* 1. 异常隔离:若 MDIO 被其他 PHY 拉低,返回 -5 */ if (pObj->IO.ReadReg(addr, LAN8742_SMR, ®) < 0) continue; /* 2. 位运算:SMR[4:0] 必须等于 addr,否则是高阻态 */ if ((reg & LAN8742_SMR_PHY_ADDR) == addr) break; } if (addr > 31) return LAN8742_STATUS_ADDRESS_ERROR;start 01 addr <5-bit> 10时,只有 addr 匹配的 PHY 会驱动 MDIO,其余高阻/* 第一次读 */ if (pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval) < 0) return LAN8742_STATUS_READ_ERROR; /* 第二次读:消抖 */ if (pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval) < 0) return LAN8742_STATUS_READ_ERROR; if ((readval & LAN8742_BSR_LINK_STATUS) == 0) return LAN8742_STATUS_LINK_DOWN;LAN8742_EnableIT(&lan8742, LAN8742_LINK_DOWN_IT);LAN8742_ClearIT()清中断void HAL_GPIO_EXTI_Callback(uint16_t pin) { if (pin == PHY_INT_PIN) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; xEventGroupSetBitsFromISR(xPhyEvent, PHY_INT_OCCURRED, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } }GetLinkState()放到 SOEM 主任务,避免在 ISR 里做 MDIO 读osal.c产生 1 ms 周期,但链路 ready是启动条件ec_configdc()直接返回错误,后续所有 DC 校准失效/* 在链路 up 后,再次写 BCR 关闭半双工 */ uint32_t bcr = 0; LAN8742_ReadReg(&lan8742, LAN8742_BCR, &bcr); bcr &= ~LAN8742_BCR_DUPLEX_MODE; /* 清半双工 */ bcr |= LAN8742_BCR_DUPLEX_MODE; /* 置全双工 */ LAN8742_WriteReg(&lan8742, LAN8742_BCR, bcr);| 指标 | 实测值(H743@400 MHz) | 测试脚本 |
|---|---|---|
| 地址探测耗时 | 0.82 ms | DWT_CYCCNT差分 |
| 链路 UP→DOWN 延迟 | 230 µs | 示波器量 nINT→LED |
| 中断模式 CPU 占用 | 0.2 % | ITM 事件计数 |
| 轮询模式 CPU 占用 | 3.1 % | 同上 |
LAN8742RegisterBusIO()注入HALETH_ReadPHYRegister()ecconfiginit()之前完成LAN8742_Init()EXTI13,NVIC 优先级 < ETH 全局中断openocd -f interface/stlink.cfg -f target/stm32h7x.cfg -c \ "init; dump_image mdio.raw 0x58003000 0x100; exit" sigrok-cli -i mdio.raw -P mdio:clk=PC1:data=PA2 -o mdio.pdfLAN8742 只有 600 行,却浓缩了IEEE 802.3 Clause 22、自协商状态机、中断消抖、时间戳对齐等经典算法。
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系列驱动器使用,或提供想适配的驱动器型号。
当你能把“链路未 ready”定位到BSR 寄存器第 2 bit 两次采样为 0时,SOEM 的报错就不再是黑盒,而是可推导的物理现象。
从 bit 到帧,从帧到伺服,一切皆有迹可循。