起因

《硬件篇》第一个模块:运动控制卡的电路与嵌入式实现。插补实战篇立的七项寄存器合同、驱动篇补的配置面三项和回填清单——这些纸面上的乙方承诺,这篇落成 GD32F4+FPGA 的真实电路。软件侧"合同先行"的干法在这里验收:硬件照合同实现,两边对着同一份文档写,合同的形状决定了电路的形状。

立项时的想法是"MCU 管协议解析、FPGA 管高频脉冲播放",落电路时这句话被修正了——协议面被拆成两半:配置和管理面归 GD32F4,数据面直通 FPGA。原因是 PCIe 的事务时序和 83kHz 的脉冲节拍都容不得"先进 MCU 再转发"的一跳,能直通的全直通,MCU 退到慢路上去管自检、看门狗和出厂维护。这个分工的完整账在第三节。

动手画卡之前还有一笔更大的账要算清楚:运动控制卡这个品类在市场上四十年的形态演化——ISA、PCI、PCIe、实时总线/外置控制器四代。不知道谱系的来路,就不知道自己在谱系上的位置,这是写这篇的第一件事。

一、形态谱系:四代形态,各代的约束

形态 当前状态 代表 这代的约束
1980s ISA 插卡 基本退出新品 泓格等已发停产通知,只剩备件/二手翻新/少数长周期工控底板 并口总线简单直接,但槽位供给先死——主板不带 ISA 了
1990s PCI 插卡 维护型现货 研华 PCI-1245/1245E/1265/1285、固高 GT/GE/GTS(有 PCI 或 PCI/PCIe 版) 5V 3.3V 信令兼容坑;新工控机 PCI 槽越来越少,装得上卡找不到槽
2000s~今 PCIe 插卡 当前 PC-Based 主流 凌华 PCIe-8338(标称 64 轴)、固高 GVN/GSN/GEN、雷赛 DMC5000(标称 256 轴) 轴数天花板被主机侧实时性锁住;高端转向 EtherCAT/gLink 实时总线替代纯脉冲
2010s~今 独立/外置控制器 选择最多、增长最快 雷赛三分(DMC 插卡/EMC 外置/PAC 产线)、固高、正运动、台达、汇川、倍福 CX、欧姆龙 NJ/NX、三菱 iQ-R Motion、西门子 SIMOTION/SINAMICS Ethernet/EtherCAT/USB/串口上联,机柜外或设备侧独立运行——不再依附工控机

谱系的叙事轴不是"更快",是约束的接力:ISA 死于槽位供给(总线本身没坏,主板先不带了);PCI 死于同一把刀加 5V 兼容的暗坑(老卡插新槽烧接口的事故是那代人的集体记忆);PCIe 至今活着,但它把轴数做上去之后撞到新墙——脉冲都在卡上生成,多卡协同、远端io、柜外部署都要求卡和驱动器之间换成总线,于是高端滑向 EtherCAT 类实时总线;独立控制器则干脆把"PC"从必选项里划掉,控制器自己就是计算机。四代的共同底色是形态跟着部署方式走:装机柜、装设备侧、还是长在生产线上,比每秒多少脉冲更能决定形态。

我们在谱系上的位置是清醒的:自研 PCIe 脉冲卡是第一种卡形态立项篇的多卡口径),同性能档位上市售卡三五千块能买到——自研的收益不在单卡成本,在三点:接口完全按模式环合同定制(市售卡的寄存器表各玩各的,适配层得一家一家写)、安全链路(断丝/急停在卡端同拍封脉冲)可以做到我们要求的深度、以及这是把插补/调度/驱动三篇的口径焊在一块板子上的学习闭环。等哪天产能逻辑要求上 EtherCAT,卡适配层下面换一个分支,上面的软件一行不动——形态是可替换的,合同才是资产

二、为什么是 GD32F4+FPGA,账从带宽起

驱动篇算过那笔关键带宽账:模式环 83kHz×1B=83KB/s。PCIe x1 一条 lane 理论 250MB/s,我们用掉千分之三。这笔账松开了整个选型的手——运动控制卡的 PCIe 接口难点从来不在带宽在时延和护栏:补货中断到主机的时间要稳、underrun 时的斜坡停要硬件自己会、DIR 建立时间要硬件保证。这决定了主器件的选型方向:要一块能自己跑时序逻辑的可编程硬件,FPGA 入场;GD32F4 则承担不需要纳秒级、但需要"懂协议、能自检、有串口"的那部分管理活。

三、卡上分工:数据面归 FPGA,管理面归 GD32F4

把起因里那句修正后的分工摆开:

FPGA(数据面) GD32F4(管理面)
职责 PCIe 端点、BAR 寄存器窗口、模式环 DMA 取批、PACE 变频、四轴 PUL/DIR 生成、POS 计数、输入滤波、MSI 发生 上电自检、心跳看门狗、ID/VER 组装、维护串口、出厂测试、FPGA 配置 flash 管理
时序预算 12µs 节拍(83kHz)、µs 级护栏 100ms 级心跳、秒级自检
失效后果 它坏=卡坏 它坏=卡保守停(失效安全方向)

心跳看门狗是管理面存在的最大理由,也是安全链在硬件侧的延长线:主机每 100ms 写一次卡上的 scratch 寄存器(显式心跳,不能用 PAT_WPTR 活动代替——静止待机是合法状态,写指针本来就不动);GD32F4 盯这个节拍,超时就封脉冲。主机蓝屏、内核 panic、任务卡死——软件侧的一切死法,都在 100ms 内被一颗 MCU 拦在"脉冲已经停了"的安全态。这个设计把"主机是不可信组件"从架构口头禅变成电路事实,和放电模块断联兜底停高频是同一个哲学:本地策略永远兜底

GD32F4 与 FPGA 之间走本地总线(并口/SPI),管理面消息量极小,不抢数据面的路。两个时钟域——PCIe 参考钟和脉冲域自己的低抖动晶振——之间的数据交接用异步 FIFO/握手做 CDC(跨时钟域);脉冲域的晶振抖动规格就是实时验证篇FPGA 时间戳对账的对端,这是一条要写进手册回填清单的指标。

四、PCIe 端点:三条路和一笔取舍

把"卡怎么说上 PCIe"单独拎出来,因为这是选型分歧最大的一格:

路线 A:FPGA 集成 PCIe 硬核(Xilinx 7 系 Artix 档起步、国产带硬核型号)。PHY 和链路层是免费但闭源的厂商 IP——零依赖纪律在这里的落地方式是进 SBOM 盘点合规篇的流水线同款处理),不是拒绝使用。事务层自己写或用厂商骨架裁剪,寄存器窗口+DMA 引擎的规模都不大。

路线 B:桥片 + MCU。PCIe 转本地总线的桥(PEX8311 一类,或国产 CH36x 系列这类用于采集卡的廉价方案)+ GD32F4 本地总线直挂——83KB/s 的带宽账让这条路完全够用,开发量最小。代价在护栏:underrun 斜坡、DIR 建立时间、POS 四轴同拍锁存这些要硬件时序的活,MCU 定时器勉强能凑但边界模糊。

路线 C:开源 PCIe 端点软核。审计上最干净,工程量最大,链路层兼容性自担风险。

定稿取 A,B 记档为备胎。理由回到第二节的账:护栏要的是在硬件里而不是在软件里凑——underrun 的斜坡停、方向翻转的建立延迟、四轴快照的原子性,这三件事天然是 FPGA 的母语,是 MCU 的绕路。备胎 B 的存在本身还多送一层保险:万一 A 的 IP 供应链出问题,寄存器合同不变,换 B 实现对驱动篇是无感的——适配层的红利在硬件侧又兑现一次。

五、脉冲输出与开关量输入

输出侧:四轴 PUL/DIR 经 RS-422 差分驱动器(AM26C31 一类)出卡,5V 差分对——这是运动控制卡输出侧的行业通用接口,电机篇的三坑里讲过对端:驱动器一侧是光耦,慢光耦 TLP521 吃不下高频、要 6N137 这类快光耦,而卡这侧差分输出的沿速率和电平在几十年的接口传统里早已和驱动器侧光耦配套。FPGA 的 3.3V LVCMOS 电平够不着 5V 差分的规矩,中间的驱动器芯片就是电平与驱动的双重翻译。

输入侧:限位、回零、断丝、急停这路开关量按 24V 工业电平进来,光耦隔离(这路信号慢,TLP521 反而是对的选择——便宜、耐造),后级 RC 滤波加施密特整形消抖,时间常数毫秒级——机械开关抖 10ms,滤波把它吃干净,FPGA 再看就是干净边沿。断丝/急停这两个输入除了走 STAT 通路,还有驱动篇立的独立硬件路:输入变化在卡端同拍封脉冲并发 0xF0 MSI——这条路的延迟预算是 FPGA 一个时钟周期,不是任何软件。手轮输入不在这块卡上,在电机控制模块,那里的账不同。

六、FPGA 固件:模式环播放器与它的护栏

数据面固件的心脏是模式环播放器,一屏伪码看清主干(SpinalHDL/Verilog 同构):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
每 PACE 周期(分频器从变频字重载):
    if PAT_CNT == 0 and CTRL.RUN:
        进入 underrun 斜坡:变频字按固定斜率递减到 0,STAT.UNDERRUN 置位
    else:
        tick = 环[读指针];读指针+1;PAT_CNT-1
        若本 tick 的步进方向与上一 tick 不同:        // DIR 建立时间护栏
            冻结 PUL 输出 5µs 再发沿                 // 方向先稳,脉冲后到
        按位图位生成四轴 PUL 沿;POS 计数器随沿加减
    if PAT_CNT < 水位: 发补货 MSI(向量 0xD0)
写 LATCH 门铃: 四轴 POS 同拍快照进影子寄存器

三个护栏各值一段:underrun 斜坡替软件挡住"高速断流必丢步"(驱动篇第五节的账);DIR 建立时间电机篇接口三坑里最阴的那个(方向翻转瞬间发脉冲,驱动器还没认对新方向)从手册注意事项变成硬件常量;POS 同拍快照给对账一个真正的"同一瞬间"。PACE 变频字是单寄存器写,0xD0 变频落进来即改播放频率不动几何——合同语义在电路里的样子。MSI 发生器按驱动篇的向量表发:补货 0xD0、常规 0x2X、安全 0xF0、门铃 0x2Y。

七、GD32F4 固件:管理面的 Rust

MCU 固件沿用全系统的纯 Rust 零依赖纪律(cortex-m 运行时和器件支持包按 MIT/Apache 许可 vendor 进来,或直接寄存器裸写,量不大)。除了第三节的看门狗,管理面还有三件活:上电自检(RAM/配置回读/时钟锁定,自检不过不给 FPGA 加载使能,ID/VER 里留自检位);ID/VER 组装——所以合同的第一个寄存器背后站着的是这颗 MCU 的自检结论,出厂值与固件版本在这读;维护串口——出厂测试协议和 FPGA 配置 flash 的烧写管理,产线工装的语言。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
/// 管理面主循环(伪码):看门狗是第一公民
loop {
    if heartbeat.fresh(100_000) {          // 100ms 内有 scratch 写入
        pulse_guard.release();             // 允许 FPGA 数据面按 CTRL 运行
    } else {
        pulse_guard.force_stop();          // 封脉冲,失效安全方向
        log_local(Event::HostLost);
    }
    selftest.tick();
    maintain_uart.poll();                  // 出厂测试/固件烧写
}

八、调试工装:让卡自己会说话

第一版卡的调试不靠祈祷,靠工装:回环自测——PUL 输出经跳线回环到板上的计数输入,固件自发自收,脉冲数、频率、建立时间全在卡内对账,不接驱动器就能验;每轴一颗脉冲指示 LED,低速时肉眼可见节拍,高速时亮度随占空比——老电子工程师的把戏,便宜且有效;示波器量 PUL 脉宽与 DIR 建立时间(拿空走 83kHz的上限档量,裕量一目了然);逻辑分析仪抓输入消抖。工装的最后一步是对着驱动篇的回填清单逐项出数——手册是测出来的,不是抄出来的,九项回填每项在工装上过一遍,合同两侧的偏差就地清零。

总结

实战清单:形态谱系四代(ISA 死于槽位/PCI 死于槽位加 5V 坑/PCIe 主流但高端滑向实时总线/外置增长最快,叙事轴=形态跟着部署方式走);自研定位(合同定制+安全链深度+学习闭环,市售卡是备选不是对手);分工(FPGA 数据面:端点/环/节拍/护栏;GD32F4 管理面:自检/心跳看门狗/维护串口,主机失联 100ms 封脉冲=安全链硬件延长线);PCIe 三路(硬核定稿、桥片备胎、开源记录,护栏是 FPGA 母语 MCU 绕路,换路合同不变);IO 电路(输出 AM26C31 差分配驱动器侧 6N137、输入 24V 光耦+RC+施密特、断丝急停独立硬路封脉冲);FPGA 固件(播放器+underrun 斜坡+DIR 5µs 建立+POS 同拍快照+四向量 MSI);GD32F4 固件 Rust 零依赖(看门狗第一公民/自检不过不加载/维护串口管产线);调试工装(回环自测/脉冲 LED/示波器量裕量/回填清单逐项出数)。跑通标志:裸卡回环自测 83kHz 档脉冲数零误差;断主机心跳 100ms 封脉冲可复现且上电自检位正确;示波器验证方向翻转后 PUL 沿不早于 5µs;压空模式环触发 underrun 斜坡、斜率与电机篇加减速档对得上;装机后驱动篇跑通标志全绿——合同两个乙方对完账。

下一篇还是电路:独立高频放电模块——斩波投切拓扑、µs 级定时、采样与硬件封波,下位机三模块里功率最大、干扰最强的一块。

参考链接