# PLSR 模块交接文档(2026-08-08) > 交接人:ZCode 会话(deepseek) > 接收人:Codex > 项目:信捷 XDM 兼容 PLSR 脉冲定位模块(STM32F407 + IAR EWARM 8.3 + uC/OS-II + Modbus RTU) --- ## 1. 项目概况 在 STM32F407 上实现信捷 XD/XL 系列 PLC 的 PLSR 多段脉冲定位指令,对标 XDM-60T4-E: - **指令语义**:`PLSR S0 S1 S2 D`——S0=段表(每段 10 字:频率/脉冲/等待码/跳转),S1=模式/起始段,S2=参数组(K0=HSD460-539,K1-K4=SFD950+),D=Y0-Y3 - **十态状态机**:UNINITIALIZED/IDLE/ACCEL/RUN/DECEL/WAIT/PAUSED/COMPLETED/STOPPED/ERROR - **速度规划(P2)**:Q32.32 定点,中断中无浮点,直线/S曲线/正弦三种加减速,动态调频 - **硬件(P3a)**:Q0=PF6/TIM10_CH1(AF3)、Q1=PF8/TIM13_CH1(AF9)、Q2=PF7/TIM11_CH1(AF3)、Q3=PF9/TIM14_CH1(AF9),定时器时钟 168MHz(按 RCC 实际配置计算) - **输出特性**:XDM 的 Y 输出为**集电极开路(OC/NPN 漏型)**——只有导通(≈0V)和截止(悬空)两态,无主动高电平;正向 = 低电平 = ON(手册 1-4-4 节,PDF 页 166) - **参考手册**:`Document/PLSR_document/信捷XD_XL系列PLC定位控制手册_PD02_20260510_V1.3.pdf`(1-4-2 节输出方式=OC;1-4-4 节集电极开路+负逻辑;1-4 节接线图 R=3.3K 上拉;PDF 50 页加减速斜率定义) ## 2. 代码结构与测试体系 - `PLSR/Inc|Src/`:plsr_core(状态机/命令)、plsr_job(任务快照解析/校验)、plsr_path(多段路径执行器)、plsr_profile(速度曲线 Q32.32)、plsr_hal_f407(定时器/GPIO)、plsr_persistence(Flash 存储)、plsr_self_test(上电自测)、plsr_resource、plc_device - **host 测试**:`PLSR/Test/run_host_tests.ps1`——6 套件共 **1268 项**(plc_device 180 / core 174 / job 115 / path 227 / profile 182 / hal 390),`-std=c11 -Wall -Wextra -Werror -DPLSR_HOST_TEST -lm` - **IAR 编译**:`EWARM/Modbus.ewp` 配置名 Modbus,`IarBuild.exe Modbus.ewp -build Modbus`,当前 0 错误 0 警告 ## 3. 已完成并验证的修复(勿回退!) | # | 问题 | 修复 | 验证证据 | |---|---|---|---| | 1 | 无方波(PF6 恒高 672ms) | `PlsrHwConfigurePwm` 补配 `CCMR1.OC1M=110`(PWM 模式1)+ OC1PE | 逻辑分析仪见正常方波 | | 2 | 多余脉冲 7517(理论 7500) | `CR1.ARPE=1`(ARR 预装载)+ `EGR.UG` 启动加载影子 | 多文件实测总脉冲 **7500 正好** | | 3 | 段间 14.9ms 延时 | `PlsrHwStartPulse` 仅方向变化时走 DIR_SETTLING(首次/换向/换点) | 段间 → ~2ms | | 4 | 段尾冻结收尾(段3 150Hz 平台 38 脉冲,800ms) | core tick 中 `PlsrProfileSyncPulses` 每 tick 把 profile 虚拟计数校准到 `PlsrHwGetEmittedPulses()` | 段3 800ms→520ms,减速平滑;总脉冲仍 7500 | **上板自测**:`plsr_self_test.c`——3 段(2000Hz/1000 脉冲、5000Hz/6000、1000Hz/500),K1 参数,方向点 Y4(SFD906=4),上电延时 1s 后启动,完成后可删除。 ## 4. ⚠️ 未解决问题:段首"第一周期压缩"(②) ### 现象(多文件实测稳定复现) 段2/3 起步波形:**高 50ms + 低 0.5ms → 恒定 1000Hz**(理论:10Hz 起步,第一周期 100ms:高 50ms+低 50ms,之后每 1ms +10Hz 平滑加速到目标)。时频图上表现为**折线**(陡→缓),段2 加速段从 ~1000Hz 开始(缺失 0→1000Hz 的加速)。 ### 已排除(全部有数据证据) 1. ~~PSC 写入立即生效~~ —— 快照实锤:cnt 每 1ms +653(PSC=256 正常速度),PSC 预装载行为正常(RM0090 也确认 buffered) 2. ~~divider 计算异常~~ —— 暴力扫描 1~20000Hz 无任何 (PSC, 33008) 组合;快照显示 psc/arr 全部正确 3. ~~启动参数错误~~ —— 快照 [0]:psc=256, arr=65369(10Hz), ccr=32684, cnt=0,ARPE=1(cr1=0x80),CCMR1=0x68 —— 完全正常 4. ~~job 参数映射~~ —— startSpeed=0(SFD958 默认),地址映射正确 5. ~~profile 斜率错误~~ —— slope=defaultSpeed/accelMs=10Hz/ms 正确;OS_TICKS_PER_SEC=1000u(1ms)确认 ### 关键证据链(快照:段3 启动 + 周期结束) ``` Snap[0]: reason=0, psc=256, arr=65369(10Hz), ccr=32684, cnt=0 ← 启动正常 Snap[1]: reason=2, psc=2, arr=55999(divider(1000Hz)!!), ccr=27999, cnt=67 ← 第一个更新事件 Snap[2..7]: 全部 (psc=2, arr=55999) —— 之后恒定 1000Hz ``` - 第一周期结束时 ARR 影子加载 = **divider(1000Hz)** = defaultSpeed - 波形显示第一"周期"仅 50.5ms,但 profile 理论到 1000Hz 需 99ms(10Hz/ms)——**50.5ms 内 profile 推进到 ~1000Hz 无法用 1ms 节拍解释** ### 新疑点(尚未深查) - **段间静默 ≈49ms**(段1 停止 → 段2 PWM 启动,预期 ~2ms)——"高 50ms"可能部分是"悬空被分析仪读高"(PF6 高阻),真正问题可能是"段间为什么等 49ms" - 或"影子被提前加载(33008 之谜)"——CNT 在 33008(50.5ms)回绕,但 33008 无任何代码来源 ### 下一步建议(tick 级快照已编译好,烧录即用) `PlsrHwDbgSnap[64]`:PwmBegin 重置,之后每 tick(1ms)记录 (reason, psc, arr, ccr, cnt)。用户暂停后读数组 → CNT 演化直接分辨: - CNT 正常走到 65369(100ms 回绕)→ "50.5ms"另有解释(查段间静默) - CNT 在 33008(50.5ms)回绕 → 影子提前加载实锤(查更新事件触发条件) **注意**:② 不影响脉冲总数(7500)和位置精度——可搁置,也可继续查。 ## 5. 调试基础设施(重要!) 1. **波形分析脚本** `Document/PLSR_document/波形/plot_waveform.py`: - 逻辑分析仪 bin 格式已破译:**16bit/采样(小端 uint16),信号在 CH0(bit0)= m[0::2]&1,采样率 100MS/s**(自动反推,窗口 5s) - 用法:`python plot_waveform.py ` → 输出时频图 + 三段结构 + 脉冲数 2. **寄存器快照**:`plsr_hal_f407.c` 中 `PlsrHwDbgSnap`(当前 64 条 tick 级,P4 后删除) 3. **豆包识图**(用户已开通视觉):火山引擎 v3 端点 `https://ark.cn-beijing.volces.com/api/v3/chat/completions`,模型 `doubao-seed-2-1-pro-260628`(支持图片),key 见 `~/.zcode/v2/config.json` provider `87847afb...`。**读 IAR Watch 截图数字用它,比 GLM 准** 4. **教训**:GLM 识图(glm_vision.py,glm-4v-flash)数字字段会错位(如 reason 读出 256)——**关键数值务必用豆包或人工确认** ## 6. 待办路线(原计划) - **P3b**:四轴并发(当前只有单轴验证)、AB 相输出(F407 裸定时器无 DMA/主从,需 OC 中断移相)、TIM6 10kHz 节拍、NVIC 优先级表 - **P4**:位置闭环(HSD 累计/掉电保存/SD 发布/I 事件/限位/齿隙/检查点)——② 建议在 P4 上板调试时一并处理 - **P3.5**:Modbus 最小映射(真实联调) - 位置/方向极性、绝对定位(DRVA)语义完善 ## 7. 给 Codex 的提示 1. 先跑 `PLSR/Test/run_host_tests.ps1`(1268 项全绿)和 IAR 编译确认基线 2. 第 4 节的 ② 若继续查:优先用 tick 级快照拿 CNT 演化,一次定位;若搁置,不影响 P4 推进 3. 上板验证流程:烧录 → 逻辑分析仪抓 PF6(飞线到 MCU 引脚,勿接 24V 端子排)→ `plot_waveform.py` 分析 4. 自测固件含调试快照代码(标记"P4 后删除"),正式版需移除