Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 
 

54 KiB

PLSR 方案设计书

文档版本:V1.0 Rev.C
需求基线:PLSR需求规格统计_V1.3.md Rev.B
目标平台:XDM-60T4-E / STM32F407IG / uC/OS-II
编制日期:2026-08-05
文档状态:设计基线;标记为“待上板验证”的项目在验证完成前不得关闭

目录

  1. 概述
    1. 项目背景
    2. 定义
  2. 系统概述
    1. 需求概述
    2. 系统结构图
    3. 功能模块列表
  3. 功能模块设计
    1. PLSR运动控制核心模块设计
    2. 参数解析与任务提交模块设计
    3. 路径解释与段调度模块设计
    4. 速度规划模块设计
    5. 高速脉冲输出模块设计
    6. 状态机与命令模块设计
    7. 输出资源管理模块设计
    8. 软元件与通信适配模块设计
    9. 位置、当量与持久化模块设计
    10. 诊断与自测模块设计
  4. 数据结构设计
    1. 数据结构设计
    2. 数据结构与程序的关系
  5. 错误处理设计
    1. 错误处理设计描述
    2. 错误输出信息
  6. 参考资料

1 概述

1.1 项目背景

本项目在现有 XDM-60T4-E 控制器工程中实现 PLSR 定位控制功能。控制器采用
STM32F407IG、12 MHz 外部晶振、168 MHz 系统时钟和 uC/OS-II,现有工程已经具备
USART1 Modbus RTU、USB Device、Backup SRAM 和基本任务调度能力,但尚未实现高速脉冲、
路径解释、速度规划及轴状态管理。

PLSR V1.0 对标信捷 XD/XL 系列 PLC 的 PLSR 逻辑模型,保留 PLSR S0 S1 S2 D
S0 多段数据、S1 用户参数、S2 K0~K4 参数组、D 输出端口以及固定 HSD/SFD/SM/SD/I
软元件语义。在此基础上增加四轴独立运行、CW/CCW、64 位内部位置、参数原子提交、命令防重、
诊断和 Backup SRAM 检查点等能力。

本文说明系统如何实现需求,重点覆盖:

  • 总体软硬件架构;
  • OS 任务与硬件中断的职责边界;
  • PULSE/DIR、AB 相和 CW/CCW 输出;
  • S0/S1/S2/D 解析与运行快照;
  • 多段路径、等待、跳转和段事件;
  • 加减速、动态调频、位置及累计;
  • 固定软元件、保存、错误和诊断。

V1.0 不实现多轴直线或圆弧插补、闭环位置修正、电子凸轮、龙门同步、完整机械回零和
安全认证急停。

1.2 定义

名称 定义
PLSR 多段脉冲定位指令,逻辑调用形式为 PLSR S0 S1 S2 D
S0 动态首地址指定的路径数据块,保存总段数及各段频率、脉冲数、等待和跳转
S1 动态首地址指定的用户参数块,保存相对/绝对模式和起始段
S2 K0~K4 运动参数套组,保存默认速度、速度限制、曲线、补偿、FOLLOW和刷新周期
D 输出资源操作数,兼容语义下选择 Y0~Y3,本项目对应 Q0~Q3 高速资源
PULSE/DIR 一个端口输出脉冲,另一个端口输出方向电平
AB 相 两路相差四分之一周期的正交输出,通过相位先后表示方向
CW/CCW 正向和反向分别使用独立脉冲端口,两个端口不得同时输出
指令脉冲 PULSE/DIR 的一个上升沿、CW/CCW 的一个完整脉冲或 AB 相的一个完整四状态周期
控制刷新周期 速度规划器更新目标频率的周期,只允许 0.1 ms 或 1 ms
脉冲周期 由当前输出频率决定的物理波形周期,与 OS Tick 和控制刷新周期不同
运行快照 START 接受后为轴生成的不可变 S0/S1/S2/D 执行副本
BUSY 轴存在已接受但尚未终止的任务,包括运动、WAIT和PAUSED
PULSE_ACTIVE 当前物理脉冲正在输出
DONE 当前任务正常完成并锁存;STOP或ERROR不得置位
当量 通过每转脉冲数和每转移动量将工程单位换算为指令脉冲
固定软元件 信捷规定地址和含义的 HSD、SFD、SM、SD、I 数据
动态数据地址 调用者在允许数据区内为 S0、S1 选择的连续首地址

2 系统概述

2.1 需求概述

2.1.1 功能范围

系统应实现四个独立逻辑轴。PULSE/DIR 可同时运行四轴;AB 相和 CW/CCW 使用 Q0/Q1、
Q2/Q3 固定点对,最多同时运行两轴。四轴之间不做插补,各轴独立启动、停止、调频、定位和查询。

主要功能如下:

类别 V1.0功能
输出方式 PULSE/DIR、AB相、CW/CCW
轴数 四轴独立;AB/CW/CCW最多两轴
频率 1~100 kHz保证范围;100001~200000 Hz经板测后作为非保证扩展
脉冲数量 完整有符号32位;0表示跳过当前段
定位 相对定位、绝对定位、设置/清零当前位置
路径 1~100段,支持等待、ACT、EXT和动态跳转
曲线 无加减速、直线、S形、正弦
段衔接 完成方式、后续方式
控制 START、STOP、PAUSE、RESUME、保存、清零、自测
刷新周期 S2配置0.1 ms或1 ms,OS Tick保持1 ms
保存 Flash固定配置、Backup SRAM动态检查点
对标 固定HSD/SFD/SM/SD/I地址及S0/S1动态首地址语义

2.1.2 性能和安全目标

  • 正常完成时脉冲数量误差为 0;
  • 输出目标占空比为 50%;
  • 当前段目标频率修改应在配置的控制刷新周期内开始应用;
  • 四轴 100 kHz 并发时不得丢脉冲、重复脉冲或串轴;
  • Modbus和USB压力不得改变运动结果;
  • 上电、复位、HardFault和看门狗复位期间输出保持安全无效;
  • 运行参数使用快照或原子访问,禁止读取半更新数据;
  • 异常复位后不得自动续跑,并清除绝对位置有效标志;
  • 软件急停没有独立硬件切断回路,不得宣称安全认证急停。

2.1.3 工程基线与约束

项目 现状/约束 方案处理
MCU STM32F407IG,168 MHz 保持现有时钟配置
OS uC/OS-II,Tick为1 ms 不提高OS Tick
Modbus USART1+DMA,任务轮询 作为调用与监控适配层
USB OTG FS中断当前优先级0 调低到运动中断之后,建议优先级6
PLSR定时器 当前未初始化 新增TIM6控制基准、TIM9/TIM12硬件计数及TIM10/11/13/14脉冲输出
Modbus历史 代码仍写入1000起始历史区 删除历史写入,释放给S0/S1动态数据池
Backup SRAM 已完成基础初始化 扩展为带版本和CRC的双检查点
急停 无外部硬件切断 仅实现软件立即关闭和状态锁存

2.2 系统结构图

PLSR系统结构图

图 2-1 PLSR系统结构图

图中蓝色表示控制与数据流,橙色表示硬实时及物理输出路径,绿色表示固定软元件、持久化和诊断等
数据服务。为方便纯文本环境阅读,结构关系同时保留如下文字版本。

┌──────────────────────────────────────────────────────────┐
│ PLC调用 / Modbus RTU / 内部测试接口                       │
└───────────────────────────┬──────────────────────────────┘
                            │
┌───────────────────────────▼──────────────────────────────┐
│ 命令与软元件适配:调用上升沿、命令序号、状态快照          │
└───────────────────────────┬──────────────────────────────┘
                            │
┌───────────────────────────▼──────────────────────────────┐
│ 参数提交:读取S0/S1/S2/D、完整校验、资源申请、运行快照    │
└───────────────────────────┬──────────────────────────────┘
                            │
┌───────────────────────────▼──────────────────────────────┐
│ 四轴运动内核:状态机、路径解释、速度规划、位置与段事件     │
└───────────────┬───────────────────────────┬──────────────┘
                │                           │
┌───────────────▼──────────────┐  ┌─────────▼──────────────┐
│ OS任务控制面                  │  │ 定时器/EXTI实时面       │
│ 命令、段切换、等待、保存      │  │ 脉冲、调频、尾停、限位  │
└───────────────┬──────────────┘  └─────────┬──────────────┘
                │                           │
                └─────────────┬─────────────┘
                              │
┌─────────────────────────────▼────────────────────────────┐
│ STM32F407板级层:TIM6、TIM9/12、TIM10/11/13/14、GPIO、EXTI│
└─────────────────────────────┬────────────────────────────┘
                              │
                         Q0~Q3 / DIR
                              │
                         伺服驱动器

系统划分为控制面和实时面:

执行域 运行位置 负责内容 禁止内容
控制面 PlsrTask 命令、校验、快照、状态机慢路径、等待、段切换、保存和发布 逐脉冲翻转GPIO
实时面 TIM/EXTI中断 硬件累计、软件兜底计数、尾脉冲、速度刷新、限位和EXT锁存 阻塞、动态内存、Flash、通信解析、OS等待

2.3 功能模块列表

编号 模块 建议源文件 主要职责
M01 PLSR运动控制核心 plsr_core.c 四轴对象、任务入口、事件分派和模块协调
M02 参数解析与任务提交 plsr_parser.c S0/S1/S2/D读取、校验、快照和提交
M03 路径解释与段调度 plsr_path.c 段进入、等待、跳转、零段和段事件
M04 速度规划 plsr_profile.c 三种曲线、短距离、衔接和动态调频
M05 高速脉冲输出 plsr_hal_f407.c PWM、TIM9/TIM12硬件累计、软件计数兜底、AB配对和安全关闭
M06 状态机与命令 plsr_state.cplsr_command.c 合法状态转换、命令幂等和优先级
M07 输出资源管理 plsr_resource.c 高速点、DIR点及TIM9/TIM12计数资源的原子申请和释放
M08 软元件与通信适配 plsr_device.c HSD/SFD/SM/SD/I、S0/S1及Modbus边界
M09 位置、当量与持久化 plsr_position.cplsr_persist.c 64位位置、换算、限位、Flash和Backup SRAM
M10 诊断与自测 plsr_diag.c 错误映射、分频记录、性能统计和自测

建议工程目录:

PLSR/
  Inc/
    plsr.h
    plsr_types.h
    plsr_device.h
    plsr_hal.h
  Src/
    plsr_core.c
    plsr_parser.c
    plsr_path.c
    plsr_profile.c
    plsr_hal_f407.c
    plsr_state.c
    plsr_command.c
    plsr_resource.c
    plsr_device.c
    plsr_position.c
    plsr_persist.c
    plsr_diag.c

3 功能模块设计

3.1 PLSR运动控制核心模块设计

3.1.1 模块功能描述

运动控制核心静态创建四个 PlsrAxis 对象,负责初始化各子模块、运行 PlsrTask、接收中断事件、
调用状态机、协调段调度和发布状态。模块不直接解释 Modbus 帧,也不直接操作 Flash 或具体 GPIO。

OS任务建议如下:

任务 建议优先级 触发方式 职责
PlsrTask 4 事件唤醒,最长1 ms巡检 命令、路径慢处理、等待、状态发布和保存请求
现有Modbus任务 5 1 ms轮询 通信收发和协议解析
测试任务 6及以后 按需 非实时测试和日志

中断优先级首次配置建议如下,最终值通过 uC/OS-II 端口约束和上板测试冻结:

抢占优先级 中断 用途
1 硬限位EXTI 锁存限位并禁止继续越界输出
2 TIM9/TIM12、TIM10/11/13/14 硬件计数完成、软件兜底计数、参数边界和尾脉冲关闭
3 TIM6 0.1 ms速度控制基准
4 EXT输入EXTI 路径切段边沿锁存
5 USART1、DMA2 现有Modbus通信
6 USB OTG FS 从当前优先级0调低
15 SysTick 现有1 ms OS Tick

实时中断不调用 OS API,只设置原子事件位。PlsrTask 获取事件后按急停、限位、立即停止、
减速停止、暂停和正常事件的顺序处理。

3.1.2 模块输入输出接口说明

PlsrResult Plsr_Init(void);
void       Plsr_Task(void *argument);
PlsrResult Plsr_Submit(const PlsrCall *call, uint32_t sequence);
PlsrResult Plsr_Command(const PlsrCommand *command);
bool       Plsr_GetStatus(uint8_t axis, PlsrStatus *status);
void       Plsr_IsrPost(uint8_t axis, uint32_t event_mask);

输入为调用参数、控制命令和硬件事件;输出为提交结果、状态快照、固定软元件状态和持久化请求。

3.1.3 流程图

PLSR单轴完整执行流程图

图 3-1 PLSR单轴完整执行流程图

系统启动
  -> 输出置安全状态
  -> 初始化设备访问、资源和持久化
  -> 初始化四轴对象
  -> 初始化定时器和EXTI
  -> 自检
  -> 全部成功:进入IDLE
  -> 任一失败:保持输出关闭并发布初始化错误

PlsrTask循环
  -> 读取ISR事件
  -> 按优先级处理停止和限位
  -> 处理命令
  -> 推进各轴状态机
  -> 处理等待和段跳转
  -> 发布一致状态
  -> 执行非实时保存请求

3.2 参数解析与任务提交模块设计

3.2.1 模块功能描述

该模块把 PLSR S0 S1 S2 D 转换为可执行任务。START 只在启动信号上升沿或新命令序号时接受。
模块先完整校验,再原子申请资源,最后生成运行快照;任何失败都不得影响正在运行的合法任务。

S0校验内容:

  • 总段数为1~100;
  • 末地址 S0 + N*10 + 9 使用检查过的64位运算;
  • 保留字为0;
  • 双字低字在低地址、高字在下一地址;
  • 频率、脉冲数、等待编码、变量来源和跳转来源合法;
  • 数据块位于允许的数据区;
  • S0与S1不重叠。

S1只包含定位模式和起始段。S2只允许K0~K4,并校验默认速度、最高速度、起止频率、曲线、
FOLLOW、补偿和刷新周期。D按输出模式检查Y0~Y3或Y0/Y2固定点对。

3.2.2 模块输入输出接口说明

PlsrResult PlsrParser_BuildSnapshot(
    const PlsrCall *call,
    PlsrJobSnapshot *snapshot,
    PlsrErrorDetail *detail);

PlsrResult PlsrParser_ReadLiveFrequency(
    const PlsrJobSnapshot *snapshot,
    uint16_t segment,
    uint32_t *frequency_hz);

输入为 S0/S1 首地址、S2选择值、D及输出配置;输出为完整快照或带错误数据块号的失败结果。

3.2.3 流程图

收到START
  -> 检查上升沿/命令序号
  -> 检查轴状态
  -> 读取S0总段数并计算边界
  -> 读取并校验全部S0段
  -> 读取并校验S1
  -> 读取并校验S2和D
  -> 检查绝对位置、限位和组合参数
  -> 原子申请输出资源
  -> 生成不可变运行快照
  -> 成功返回运动核心

任一步失败
  -> 回滚已申请资源
  -> 保持输出无效
  -> 返回兼容码和增强错误

运行期间仅允许重新读取当前段目标频率。S0其它字段、S1、S2、D和资源绑定均使用快照;非法动态
频率写入被忽略,继续使用最近合法值并发布诊断。

3.3 路径解释与段调度模块设计

3.3.1 模块功能描述

路径模块负责1~100段的进入、执行完成条件、等待、动态跳转和段事件。相对模式把段脉冲数解释为
本段位移;绝对模式把它解释为目标坐标,并用目标坐标减当前逻辑位置求实际输出位移。

零值判断顺序固定为:

  1. 先检查脉冲数量;
  2. 脉冲数为0时不输出,产生零段事件并跳转;
  3. 脉冲数非0且频率为0时才使用S2默认速度;
  4. 默认速度不合法时拒绝执行。

等待条件处理如下:

编码 条件 模块处理
H00 脉冲完成 输出完成后立即跳转
H01 Wait时间 完成后计时;0按1 ms
H02 Wait信号 完成后判断X/M/HM,未有效则保持WAIT
H03 ACT时间 段开始计时;时间到放弃剩余脉冲,脉冲先完则等到时间
H04 EXT信号 新上升沿到达时放弃剩余脉冲;脉冲先完仍等待新边沿
H05 EXT或脉冲完成 原子锁存先到原因,先到者决定跳转

快照保存变量来源类型和编号,Wait/ACT数值、Wait信号和动态跳转值在实际求值时读取,以保留信捷
动态变量语义。跳转值0表示顺序执行,1~N表示指定段,自跳表示有意无限循环。

3.3.2 模块输入输出接口说明

PlsrResult PlsrPath_Enter(PlsrAxis *axis, uint16_t segment);
PlsrResult PlsrPath_OnOutputDone(PlsrAxis *axis);
PlsrResult PlsrPath_OnExt(PlsrAxis *axis, uint32_t edge_sequence);
PlsrResult PlsrPath_PollWait(PlsrAxis *axis, uint64_t now_ms);

输出包括下一段请求、正常完成请求、停止剩余脉冲请求和段事件。

3.3.3 流程图

进入段
  -> 检查段号
  -> 计算相对位移或绝对位移
  -> 位移为0:不输出并生成段事件
  -> 位移非0:解析方向和目标频率
  -> 启动输出/ACT/EXT监视
  -> 等待脉冲完成或条件事件
  -> 锁存段结束原因
  -> 产生I6000~I6399对应事件
  -> 求动态跳转值
  -> 下一段 / WAIT / COMPLETED / ERROR

每次任务调度最多连续处理100次无脉冲跳转,达到上限后主动让出CPU,避免无限循环阻塞系统。

3.4 速度规划模块设计

3.4.1 模块功能描述

速度规划模块根据S2、段目标、剩余脉冲和下一段速度生成当前控制频率。TIM6提供10 kHz控制基准;
0.1 ms轴每次更新,1 ms轴每10次更新。无运行轴时关闭TIM6。

内部采用定点数:频率使用Q32.32,归一化曲线进度使用Q1.31,时间使用整数微秒,禁止在控制中断
使用浮点三角函数。

三种曲线定义为:

直线:g(u) = u
S形: g(u) = 3u² - 2u³
正弦:g(u) = (1 - cos(πu)) / 2

f(u) = f_start + (f_end - f_start) * g(u)

正弦函数使用只读查找表和线性插值。距离不足时通过有界二分求解峰值频率,自动形成三角或短距离
曲线;无法满足起止速度和脉冲数时返回参数冲突。

完成方式在当前段脉冲结束后再改变到下一段速度;后续方式在当前段内预留变速脉冲,使段边界时已达到
下一段入口速度。反向段必须先减速到0再切换方向或相序。

S2最高速度为0或超出硬件开放范围时拒绝启动。起始、目标和终止速度超过合法最高速度时限幅并发布
SPEED_CLAMPED。FOLLOW性能范围为1~100,前馈补偿范围为0~100;具体运算公式在编码前按
信捷手册相应参数定义冻结,禁止自行发明含义。

3.4.2 模块输入输出接口说明

PlsrResult PlsrProfile_Prepare(
    const PlsrSegmentRuntime *segment,
    const PlsrS2Snapshot *s2,
    PlsrProfile *profile);

void PlsrProfile_ControlTick(PlsrProfile *profile, uint32_t elapsed_us);
void PlsrProfile_SetTarget(PlsrProfile *profile, uint32_t target_hz);

输入为当前频率、目标频率、起止频率、加减速时间、曲线、剩余脉冲和衔接方式;输出为当前命令频率
和待提交的定时器分频参数。

3.4.3 流程图

准备段曲线
  -> 校验S2和目标速度
  -> 计算加速/减速所需脉冲
  -> 距离足够:生成完整曲线
  -> 距离不足:求解短距离峰值
  -> 每0.1/1 ms推进定点曲线
  -> 计算当前命令频率
  -> 限幅并生成诊断
  -> 计算待提交PSC/ARR/CCR
  -> 脉冲模块在安全周期边界应用

运行中目标频率修改不改变剩余脉冲数。规划器在配置刷新周期内接收并开始过渡,物理周期参数在最近的
安全周期边界切换;低频时不得为了刷新指标截断一个完整脉冲。

3.5 高速脉冲输出模块设计

3.5.1 模块功能描述

高速输出模块使用硬件定时器维持脉冲边沿,OS不参与逐脉冲翻转。

PLSR高速脉冲与硬件计数架构图

图 3-2 PLSR高速脉冲与硬件计数架构图

逻辑点 MCU引脚 定时器通道 定时器时钟
Q0/Y0 PF6 TIM10_CH1 168 MHz
Q1/Y1 PF8 TIM13_CH1 84 MHz
Q2/Y2 PF7 TIM11_CH1 168 MHz
Q3/Y3 PF9 TIM14_CH1 84 MHz
3.5.1.1 混合计数架构

RM0090 Rev.22 第19.4.2节表101的TIM9/TIM12内部触发连接提供以下通路:

硬件计数器 触发选择 内部计数来源 对应输出
TIM9 ITR2 TIM10_OC Q0
TIM9 ITR3 TIM11_OC Q2
TIM12 ITR2 TIM13_OC Q1
TIM12 ITR3 TIM14_OC Q3

TIM9在同一时刻只能选择Q0或Q2中的一路,TIM12只能选择Q1或Q3中的一路。因此V1.0采用:

优先:TIM9/TIM12内部硬件累计
  ↓ 计数器不可达或已被其它轴占用
兜底:对应输出定时器的周期中断软件累计

计数方式在每段开始前确定并锁存到该段结束,不在脉冲活动期间切换。最多同时提供两套内部硬件
计数;四轴PULSE/DIR并发时,至少两轴硬件计数、其余轴软件计数。资源分配优先级依次为:

  1. 已运行轴持有的计数器租约不得被新任务抢占;
  2. 同一批待启动段发生竞争时,优先AB相,其次按预计软件中断负载从高到低选择;
  3. 条件仍相同时,按命令提交顺序选择;
  4. 无可用硬件计数器时自动使用软件计数,不因计数器不足拒绝合法运动。

可同时硬件计数的PULSE/DIR组合为Q0+Q1、Q0+Q3、Q2+Q1或Q2+Q3。Q0与Q2竞争TIM9,
Q1与Q3竞争TIM12。

AB相每个相位通道每完整正交周期只产生一次同类内部比较事件,因此一组AB轴只需选择其中一个相位
作为周期计数基准。两组AB轴应通过匹配分配分别使用TIM9和TIM12,例如Q0/Q1轴选Q0→TIM9,
Q2/Q3轴选Q3→TIM12。

CW/CCW只对当前实际发脉冲的方向通道计数。发生方向切换时,在完全停止的段边界重新申请相应的
TIM9或TIM12;申请失败则该段切换为软件计数,不能在脉冲活动期间改源。

定时器采用向上计数和PWM输出:

f_actual = f_timer / ((PSC + 1) * (ARR + 1))
CCR1     = (ARR + 1) / 2

分频算法选择能容纳16位ARR的最小预分频,并比较相邻合法候选,取绝对频率误差最小者;误差相同时
选择更大的ARR以保留分辨率。记录目标频率、实际频率、PSC、ARR、CCR和误差。

硬件计数模式下不为每个PWM周期开启更新中断。TIM6控制刷新先短暂禁止输出定时器的更新装载,依次
写入PSC、ARR和CCR预装载值,再恢复更新装载;完整的新参数在随后自然更新事件一次性生效。若更新
边界在短暂禁止期间到达,则延后一个完整周期生效,不能出现混合分频值或截断周期。

PULSE/DIR先设置DIR,再等待默认10 ms或配置的方向建立时间,随后启动PWM。物理上升沿计1个指令
脉冲。硬件计数时由TIM9/TIM12在外部时钟模式1下累计每周期一次的内部OC事件;软件计数时由输出
定时器自然更新事件累计。进入目标脉冲时只武装一次尾边沿处理,最后一个脉冲下降沿到达后关闭通道,
防止出现下一个多余上升沿。

CW/CCW正向只启动CW端,反向只启动CCW端,另一路始终无效。检测到双通道同时活动时立即关闭配对
输出并进入ERROR。

AB相固定配对如下:

轴归属 A相 B相 正向状态顺序
Y0 Q0/TIM10 Q1/TIM13 00→10→11→01→00
Y2 Q2/TIM11 Q3/TIM14 00→10→11→01→00

反向交换A、B领先关系。两个定时器预装四分之一周期相位差;从已分配的一个相位内部OC事件累计
完整AB周期,落后相第四次跳变完成后关闭最后一周期。一个完整四状态周期只计1个指令脉冲,四次
相位跳变不得分别计数。

3.5.1.2 16位硬件计数扩展

TIM9和TIM12均为16位计数器。计数器配置为外部时钟模式1,ARR保持为0xFFFF,每收到一次选定的
内部OC事件,CNT自动加1。软件使用“16位硬件CNT + 64位块累计”扩展完整INT32脉冲范围:

每65536个指令脉冲
  -> TIM9/TIM12产生一次更新中断
  -> 软件块累计加65536

最终低16位到达比较值
  -> 检查块累计是否已到目标高位
  -> 是:武装最终完整脉冲/AB周期的尾边沿关闭
  -> 否:清比较标志并继续硬件累计

目标低16位不为0时使用捕获比较事件判断最终余数;目标恰为65536的整数倍时,使用更新事件和块累计
判断完成,禁止把比较值0解释成启动瞬间已经完成。

100 kHz连续输出时,每个硬件计数轴的块中断频率约为100000/65536=1.53次/秒;除块中断、最终
比较和异常外,不产生逐脉冲计数中断。零脉冲段在进入硬件层前处理,绝对值计算使用64位,避免
INT32_MIN取反溢出。

TIM10/11/13/14的SMCR在寄存器表中为保留项,因此硬件计数器只能通知CPU达到目标,不能反向门控
输出定时器。最终比较事件到达后不得立即截断
活动波形,而应根据模式武装输出定时器的最终边沿:PULSE/DIR和CW/CCW在最后下降沿关闭,AB相在
第四次状态跳变后同时关闭配对通道。N=1时在启动前直接武装尾边沿。内部OC事件相位、同步延迟和
最终关闭窗口必须用逻辑分析仪确认。

四个高速定时器对应共享中断向量:

定时器 中断向量
TIM10 TIM1_UP_TIM10_IRQn
TIM11 TIM1_TRG_COM_TIM11_IRQn
TIM13 TIM8_UP_TIM13_IRQn
TIM14 TIM8_TRG_COM_TIM14_IRQn

两个硬件计数器的中断向量为:

计数器 中断向量 用途
TIM9 TIM1_BRK_TIM9_IRQn Q0/Q2硬件块计数和最终比较
TIM12 TIM8_BRK_TIM12_IRQn Q1/Q3硬件块计数和最终比较

热路径采用直接寄存器访问,不调用通用 HAL_TIM_IRQHandler()。共享中断入口先检查本定时器标志,
并为TIM1/TIM8未来用途保留分派能力。硬件计数轴关闭输出定时器的周期更新中断;软件计数轴才启用
周期更新中断。

3.5.2 模块输入输出接口说明

PlsrResult PlsrHw_Init(void);
PlsrResult PlsrHw_Configure(const PlsrHwRequest *request);
PlsrResult PlsrHw_Start(uint8_t axis, uint64_t pulses);
PlsrResult PlsrHwCounter_Configure(const PlsrCounterLease *lease, uint64_t target_pulses);
void       PlsrHwCounter_Stop(const PlsrCounterLease *lease);
void       PlsrHw_SetPendingDivider(uint8_t axis, const PlsrDivider *divider);
void       PlsrHw_RequestTailStop(uint8_t axis);
void       PlsrHw_ForceSafe(uint32_t resource_mask);

输入为模式、方向、频率、脉冲数量、方向点和极性;输出为周期完成事件、实际计数、分频诊断和硬件错误。

3.5.3 流程图

启动硬件输出
  -> 输出保持无效
  -> 配置GPIO复用和安全电平
  -> 装载PSC/ARR/CCR并清状态标志
  -> PULSE/DIR设置方向并等待建立时间
  -> AB装载配对相位 / CW选择单通道
  -> 尝试申请并配置TIM9/TIM12硬件计数
       成功:关闭逐周期计数中断
       失败:启用输出定时器软件周期计数
  -> 使能通道和定时器
  -> 硬件持续输出
  -> 硬件模式:每65536脉冲更新块累计
     软件模式:周期ISR更新剩余量
  -> TIM6通过预装载安全更新分频
  -> 进入最后一个脉冲/AB周期
  -> 比较事件完成尾边沿
  -> 关闭输出并通知运动核心

TIM10/11/13/14没有重复计数寄存器,TIM9/TIM12内部连接又只能覆盖两路。四轴100 kHz时,若两路
硬件计数、两路软件计数,最坏约为每秒200,000次软件周期事件,加TIM6的10,000次控制事件和少量
硬件块中断。完整功能开发前必须完成两种计数模式原型,测量ISR最坏执行时间、CPU占用、计数模式
切换、USB/Modbus压力、尾脉冲和AB相位;未通过不得宣称四轴100 kHz验收完成。

3.6 状态机与命令模块设计

3.6.1 模块功能描述

每轴状态固定为:

UNINITIALIZED、IDLE、ACCEL、RUN、DECEL、WAIT、PAUSED、
COMPLETED、STOPPED、ERROR

PLSR单轴状态机与命令优先级图

图 3-3 PLSR单轴状态机与命令优先级图

主要合法转换如下:

当前状态 事件 下一状态
UNINITIALIZED 初始化成功 IDLE
IDLE/COMPLETED/STOPPED START成功 ACCEL、RUN、WAIT或COMPLETED
ACCEL/RUN 需要减速 DECEL
运动状态 等待条件未满足 WAIT
运动状态 PAUSE且减速完成 PAUSED
PAUSED RESUME ACCEL或RUN
运行类状态 路径正常结束 COMPLETED
非终止状态 STOP完成 STOPPED
可运行状态 不可恢复错误 ERROR
ERROR RESET_ERROR成功 IDLE

未列出的转换由统一入口拒绝并记录非法转换。DONE只在正常完成时置1,下一次START成功接受时清零;
STOP和ERROR不得置DONE。WAIT和PAUSED期间BUSY为1、PULSE_ACTIVE为0。

支持START、STOP_DECEL、STOP_IMMEDIATE、PAUSE、RESUME、SET_POSITION、CLEAR_POSITION、
CLEAR_TOTAL、SAVE_CONFIG、LOAD_CONFIG、RESET_ERROR和SELF_TEST。每轴保存最近命令序号与结果,
相同序号重发只返回上次结果,不重复执行。

3.6.2 模块输入输出接口说明

PlsrResult PlsrState_Transition(
    PlsrAxis *axis,
    PlsrState target,
    PlsrTransitionReason reason);

PlsrResult PlsrCommand_Execute(
    PlsrAxis *axis,
    const PlsrCommand *command);

3.6.3 流程图

收到命令
  -> 比较命令序号
  -> 重复序号:返回上次结果
  -> 检查当前状态是否允许
  -> 按命令执行动作
  -> 通过唯一状态转换入口改变状态
  -> 保存序号、结果和停止原因
  -> 发布BUSY/PULSE_ACTIVE/DONE/WAIT/ERROR

事件优先级固定为:软件急停 > 硬限位 > STOP_IMMEDIATE > STOP_DECEL > PAUSE > 正常运行。
高优先级原因锁存后,低优先级命令不得覆盖。

3.7 输出资源管理模块设计

3.7.1 模块功能描述

资源管理器维护高速资源Q0~Q3、普通输出资源Q0~Q7/Q10~Q17/Q20,以及内部硬件计数器
TIM9/TIM12的占用位图。高速输出和DIR资源属于运动必需资源;硬件计数器属于优化资源,申请失败时
允许使用软件计数兜底。

模式 D允许值 高速资源 DIR资源
PULSE/DIR Y0~Y3 D对应的一个Q点 一个未占用有效输出点
AB相 Y0或Y2 Q0/Q1或Q2/Q3
CW/CCW Y0或Y2 Q0/Q1或Q2/Q3

硬件计数资源规则:

脉冲来源 可申请计数器 冲突组
Q0/TIM10 TIM9 ITR2 与Q2互斥
Q2/TIM11 TIM9 ITR3 与Q0互斥
Q1/TIM13 TIM12 ITR2 与Q3互斥
Q3/TIM14 TIM12 ITR3 与Q1互斥

单轴或两轴运行时优先选择能全部硬件计数的组合。四轴运行时,资源管理器分别从Q0/Q2组和Q1/Q3组
选择一个轴使用硬件计数。既有运行租约不被抢占;同批竞争时按AB模式、预计中断负载和提交顺序选择。
计数器租约只在段停止边界申请或释放;任务运行期间如果某段不能获得计数器,则该段使用软件计数。

方向点板级映射如下:

PLC点 MCU引脚 PLC点 MCU引脚
Q0 PF6 Q10 PG7
Q1 PF8 Q11 PG6
Q2 PF7 Q12 PH9
Q3 PF9 Q13 PH8
Q4 PI8 Q14 PH7
Q5 PE6 Q15 PH6
Q6 PE5 Q16 PF11
Q7 PE4 Q17 PB0
Q20 PH5

完整申请掩码在短临界区内一次判断和占用,禁止逐点申请后失败而留下半组资源。运行期间模式、D、
配对关系、方向点和极性锁定。正常完成、STOP和ERROR统一通过幂等清理入口释放资源。

3.7.2 模块输入输出接口说明

PlsrResult PlsrResource_Reserve(
    uint8_t owner_axis,
    const PlsrResourceRequest *request,
    PlsrResourceLease *lease);

void PlsrResource_Release(PlsrResourceLease *lease);
PlsrCountMode PlsrResource_SelectCounter(
    uint8_t owner_axis,
    uint8_t pulse_source,
    PlsrCounterLease *counter_lease);

3.7.3 流程图

构造完整资源掩码
  -> 检查模式与D
  -> 检查高速点和DIR点合法性
  -> 进入短临界区
  -> 任一冲突:退出并返回RESOURCE_CONFLICT
  -> 无冲突:一次性占用全部资源
  -> 尝试申请TIM9/TIM12计数优化资源
       成功:锁存硬件计数租约
       失败:锁存软件计数模式
  -> 配置硬件
  -> 配置失败:安全关闭并回滚
  -> 任务终止:安全关闭并幂等释放

3.8 软元件与通信适配模块设计

3.8.1 模块功能描述

HSD、SFD、SM、SD、I、S0和S1是逻辑软元件命名空间,不等同于“Modbus通信地址表”。
PLSR内核通过统一设备接口访问逻辑软元件,Modbus只负责字节序、影子写入、命令序号和提交响应。

固定地址只采用 PLSR地址映射.md

类别 固定范围
K0配置 HSD460~539
公共参数及K1~K4 SFD900~1419
累计状态 HSD0~15
运行/方向标志 SM1000/1001、1020/1021、1040/1041、1060/1061
实时状态 SD1000~1011、1020~1031、1040~1051、1060~1071
段事件 I6000~6399
动态数据 S0、S1

固定字段使用显式描述表保存地址、位宽、有符号性、读写属性、合法范围、所属轴和持久化类别,不得通过
自拟轴块改变信捷地址。保留字段仍占原地址,未实现字段不得挪作项目扩展。

32/64位状态采用版本化快照发布。Modbus断开不产生STOP;非法通信参数不得改变正在运行的任务。
本设计书不新增PLSR全局通信地址区,也不恢复已删除的Modbus历史功能。

3.8.2 模块输入输出接口说明

bool PlsrDevice_Read(DeviceRef ref, int64_t *value);
bool PlsrDevice_Write(DeviceRef ref, int64_t value);
bool PlsrDevice_ReadBlock(DeviceRef first, uint16_t words, uint16_t *buffer);
void PlsrDevice_PublishAxis(uint8_t axis, const PlsrStatus *status);
void PlsrDevice_TriggerSegmentEvent(uint8_t axis, uint16_t segment);

3.8.3 流程图

外部读写请求
  -> 解析逻辑软元件类型和地址
  -> 检查位宽、权限和范围
  -> 参数写入影子区
  -> COMMIT时调用PLSR业务校验
  -> 成功:切换版本并返回序号/结果
  -> 失败:保持原有效参数

状态读取
  -> 读取版本号
  -> 复制完整状态
  -> 再读版本号
  -> 前后相同且为稳定版本:返回
  -> 否则重试

3.9 位置、当量与持久化模块设计

3.9.1 模块功能描述

每轴内部维护64位逻辑位置、本次任务累计、总累计和物理输出诊断计数,以及独立的
position_valid。高速ISR只更新当前块计数;任务在块边界、段边界或检查点时合并64位数据。

发布HSD固定32位累计前检查INT32范围。超出范围时保持最近合法发布值,锁存
COUNTER_OVERFLOW,不得回绕或静默截断。

当量换算按每转指令脉冲数和每转移动量形成有理数比例,计算前约分并检查溢出,每轴保存换算余数,
避免连续多段累计舍入漂移。任一分母为0时返回兼容错误码2。

软限位按逻辑位置和预计停止距离判断:禁止向越界方向启动,允许运动离开已触发限位;运动中触发默认
减速停止。方向反转时插入内部齿隙补偿子段,补偿脉冲不计入用户段、逻辑位置或HSD,但计入物理输出
诊断。

固定配置使用Flash A/B双槽:

magic | format_version | payload_length | sequence | payload | CRC32

动态K0、64位位置、累计、有效标志和最近诊断保存到有VBAT维持的Backup SRAM双检查点。
正常完成、正常停止、设置/清零位置和清累计后立即保存;运行中初始按10 ms及段边界保存诊断检查点。
异常复位或上次BUSY时清除 position_valid,任何情况都不自动恢复未完成路径。

3.9.2 模块输入输出接口说明

PlsrResult PlsrPosition_Set(uint8_t axis, int64_t position);
PlsrResult PlsrPosition_Clear(uint8_t axis);
PlsrResult PlsrPosition_ConvertToPulse(uint8_t axis, int64_t value, int64_t *pulse);
PlsrResult PlsrPersist_SaveConfig(void);
PlsrResult PlsrPersist_LoadConfig(void);
void       PlsrPersist_SaveCheckpoint(uint32_t reason);

3.9.3 流程图

脉冲块完成
  -> 原子交换当前块计数
  -> 检查64位加法溢出
  -> 更新逻辑位置和累计
  -> 检查软限位
  -> 检查HSD32位发布范围
  -> 更新状态快照
  -> 达到检查点条件:更新Backup SRAM

上电恢复
  -> 输出保持安全
  -> 读取复位原因
  -> 校验Flash和Backup SRAM版本/CRC
  -> 恢复允许的配置与诊断
  -> 异常复位或上次BUSY:清position_valid
  -> 清全部运行资源
  -> 禁止自动启动

3.10 诊断与自测模块设计

3.10.1 模块功能描述

诊断模块记录每轴目标/实际频率、PSC/ARR/CCR、当前计数模式、TIM9/TIM12块累计、软件脉冲数、
物理边沿诊断值、当前段、停止原因、状态机非法转换、资源冲突和ISR执行周期。

SELF_TEST 分为两级:

  • 默认不输出自测:地址表、S0/S1边界、跳转、分频、状态机、计数和CRC;
  • 输出自测:需要明确测试授权,仅在断开执行机构或采取防护后输出指定低频波形。

3.10.2 模块输入输出接口说明

void       PlsrDiag_RecordError(uint8_t axis, PlsrError error, const PlsrErrorDetail *detail);
void       PlsrDiag_RecordDivider(uint8_t axis, const PlsrDivider *divider);
void       PlsrDiag_RecordIsrCycles(uint8_t axis, uint32_t cycles);
PlsrResult PlsrDiag_SelfTest(uint32_t test_mask, bool allow_output);

3.10.3 流程图

收到SELF_TEST
  -> 检查所有轴非BUSY
  -> 执行静态地址和配置检查
  -> 执行分频、路径、计数和状态机检查
  -> 是否请求输出测试
       否:汇总结果
       是:检查显式授权和安全条件
           -> 输出受限测试波形
           -> 自动安全关闭
  -> 发布逐项结果和首个失败原因

4 数据结构设计

4.1 数据结构设计

4.1.1 基本枚举

typedef enum {
    PLSR_STATE_UNINITIALIZED,
    PLSR_STATE_IDLE,
    PLSR_STATE_ACCEL,
    PLSR_STATE_RUN,
    PLSR_STATE_DECEL,
    PLSR_STATE_WAIT,
    PLSR_STATE_PAUSED,
    PLSR_STATE_COMPLETED,
    PLSR_STATE_STOPPED,
    PLSR_STATE_ERROR
} PlsrState;

typedef enum {
    PLSR_OUTPUT_PULSE_DIR = 0,
    PLSR_OUTPUT_AB        = 1,
    PLSR_OUTPUT_CW_CCW    = 2
} PlsrOutputMode;

typedef enum {
    PLSR_POSITION_RELATIVE = 0,
    PLSR_POSITION_ABSOLUTE = 1
} PlsrPositionMode;

typedef enum {
    PLSR_COUNT_SOFTWARE = 0,
    PLSR_COUNT_TIM9     = 1,
    PLSR_COUNT_TIM12    = 2
} PlsrCountMode;

4.1.2 调用与命令

typedef struct {
    DeviceRef s0;
    DeviceRef s1;
    DeviceRef s2;
    uint8_t   d_axis;
} PlsrCall;

typedef struct {
    uint32_t sequence;
    uint16_t axis;
    uint16_t opcode;
    int64_t  argument;
} PlsrCommand;

4.1.3 段快照

typedef struct {
    uint32_t target_frequency_hz;
    int32_t  pulse_or_position;
    uint16_t wait_word;
    int32_t  wait_argument;
    uint16_t jump_word;
    int32_t  jump_argument;
} PlsrSegmentSnapshot;

四轴各保留最多100段的紧凑快照。快照同时保存当前段频率源地址,专供受控动态调频;其它字段不得
通过源地址重新读取。

4.1.4 任务快照

typedef struct {
    uint16_t segment_count;
    uint16_t start_segment;
    PlsrPositionMode position_mode;
    PlsrOutputMode   output_mode;
    uint8_t          d_axis;
    PlsrS2Snapshot   s2;
    PlsrResourceLease resources;
    PlsrSegmentSnapshot segments[PLSR_MAX_SEGMENTS];
} PlsrJobSnapshot;

硬件计数租约作为输出资源租约的一部分:

typedef struct {
    PlsrCountMode mode;
    uint8_t owner_axis;
    uint8_t pulse_source;
    uint8_t trigger_select;
    bool valid;
} PlsrCounterLease;

TIM9和TIM12各只能存在一个有效租约。软件计数模式不占用硬件计数租约。

4.1.5 轴运行对象

typedef struct {
    PlsrState state;
    PlsrJobSnapshot job;
    PlsrSegmentRuntime segment;
    PlsrProfile profile;
    PlsrPulseFastContext pulse_fast;
    int64_t logical_position;
    int64_t task_pulses;
    int64_t total_pulses;
    uint64_t physical_edges;
    bool position_valid;
    uint32_t event_flags;
    uint32_t event_sequence;
    uint32_t last_command_sequence;
    PlsrCommandResult last_command_result;
    PlsrError error;
    PlsrStatusPublish publish;
} PlsrAxis;

4.1.6 ISR快速上下文

typedef struct {
    volatile uint32_t remaining_in_block;
    volatile uint32_t completed_in_block;
    volatile uint32_t hardware_wrap_count;
    volatile uint32_t pending_event;
    volatile uint8_t  divider_pending;
    volatile uint8_t  tail_stop_armed;
    PlsrCountMode count_mode;
    uint8_t pulse_source;
    uint16_t final_compare;
    uint64_t target_pulses;
    PlsrDivider active_divider;
    PlsrDivider pending_divider;
} PlsrPulseFastContext;

硬件计数模式下,hardware_wrap_count与TIM9/TIM12当前CNT组成完整累计;软件计数模式下使用
remaining_in_block逐周期递减。count_mode在段活动期间只读,只有输出完全停止后才允许改变。
快速上下文只保存ISR固定时间内需要的数据,不放置S0数组、Flash缓存和复杂状态对象。

4.1.7 对外状态

typedef struct {
    uint32_t version;
    PlsrState state;
    uint16_t current_segment;
    uint16_t total_segments;
    int8_t direction;
    uint8_t busy;
    uint8_t pulse_active;
    uint8_t done;
    uint32_t command_frequency_hz;
    uint32_t actual_frequency_hz;
    PlsrCountMode count_mode;
    uint32_t hardware_counter_value;
    int64_t segment_sent;
    int64_t segment_remaining;
    int64_t logical_position;
    int64_t task_pulses;
    int64_t total_pulses;
    PlsrError error;
    uint32_t stop_reason;
    uint32_t version_end;
} PlsrStatus;

4.1.8 固定软元件描述

typedef struct {
    PlsrDeviceType type;
    uint16_t address;
    uint8_t width_words;
    uint8_t axis;
    uint8_t access;
    uint8_t persistence;
    int64_t minimum;
    int64_t maximum;
} PlsrDeviceDescriptor;

描述表必须覆盖HSD460~539、SFD900~1419、HSD0~15、固定SM、固定SD和I6000~6399,
并通过静态断言检查重复地址、位宽和轴归属。

4.2 数据结构与程序的关系

4.2.1 数据流关系

PLSR数据流关系图

图 4-1 PLSR数据流关系图

图中蓝色表示配置和运动数据,橙色表示硬实时数据及中断事件,绿色表示持久化数据,紫色表示命令与
状态接口。为方便纯文本环境阅读,保留如下简化关系。

S0/S1/S2/D逻辑软元件
        |
        v
PlsrParser_BuildSnapshot
        |
        v
PlsrJobSnapshot ----------> PlsrPath / PlsrProfile
        |                         |
        v                         v
PlsrAxis状态机 <---------- ISR事件和块计数
        |
        +----> PlsrStatusPublish ----> HSD/SM/SD/I与Modbus读取
        |
        +----> Flash / Backup SRAM检查点

4.2.2 数据所有权

数据 唯一写者 读取者 一致性方法
ISR快速计数 TIM9/TIM12块ISR或输出定时器兜底ISR TIM6 ISR、PlsrTask 计数模式锁存、32位原子交换
速度规划状态 TIM6 ISR 脉冲ISR、PlsrTask 待提交双缓冲
状态机和路径游标 PlsrTask 状态发布 单写者
输出资源位图 资源管理器 PlsrTask、诊断 短临界区
64位位置累计 PlsrTask 状态读取、保存 顺序锁/短临界区
对外状态影子 状态发布器 Modbus、内部API 版本号前后校验
固定配置镜像 参数模块 保存和设备访问 影子+COMMIT

通信层禁止直接写 PlsrAxisvolatile只保证访问可见性,不代替原子性、临界区和内存屏障。

4.2.3 中断事件数据

每轴使用32位事件字:

bit0  PULSE_BLOCK_DONE
bit1  SEGMENT_OUTPUT_DONE
bit2  LIMIT_POSITIVE
bit3  LIMIT_NEGATIVE
bit4  EXT_RISING
bit5  STOP_IMMEDIATE_DONE
bit6  TIMER_FAULT
bit7  COUNTER_FAULT
bit8  HW_COUNTER_WRAP
bit9  HW_COUNTER_TARGET

可合并事件采用原子置位;不能丢失的段事件另带单调递增序号。临界区内禁止遍历100段、除法、CRC、
Flash操作或通信发送,并使用DWT周期计数器测量最坏执行时间。

4.2.4 固定运行状态发布

HSD累计 SM标志 SD实时状态 段事件
Y0 HSD0~3 SM1000、SM1001 SD1000~1011 I6000~6099
Y1 HSD4~7 SM1020、SM1021 SD1020~1031 I6100~6199
Y2 HSD8~11 SM1040、SM1041 SD1040~1051 I6200~6299
Y3 HSD12~15 SM1060、SM1061 SD1060~1071 I6300~6399

双字采用低地址低16位、下一地址高16位。第N段事件使用轴事件基址加 N-1,跳转目标不得改变原段
事件地址。

5 错误处理设计

5.1 错误处理设计描述

5.1.1 错误分层

层级 示例 处理
告警 SPEED_CLAMPED 记录并继续运行
启动拒绝 参数越界、资源冲突、位置无效 不启动、不占资源、不破坏其它轴
轴错误 计数异常、定时器异常、动态跳转越界 安全停止该轴、释放资源并锁存ERROR
全局严重错误 HardFault、共享数据破坏 关闭全部高速输出并锁存全局故障

错误处理统一遵循:先禁止新脉冲,再锁存原因,再发布状态,最后在任务上下文执行资源释放和允许的
检查点保存。错误清除只回到IDLE,不自动恢复未完成任务。

5.1.2 安全输出

以下时机调用统一 PlsrHw_ForceSafe()

  • 上电及PLSR初始化前;
  • START硬件配置失败;
  • STOP_IMMEDIATE尾脉冲完成;
  • 定时器、计数或互斥严重错误;
  • HardFault、MemManage、BusFault、UsageFault;
  • 看门狗复位后的早期初始化。

安全关闭直接关闭TIM10/11/13/14通道和计数器,并把相关GPIO恢复为配置的安全无效电平。
故障处理函数不得写Flash。

5.1.3 参数与运行错误

  • 参数错误在START前尽量全部发现;
  • 运行中非法目标频率不破坏当前合法运动,保留最近合法目标并发布诊断;
  • 动态等待或跳转变量在运行时越界时进入ERROR;
  • 剩余量下溢、TIM9/TIM12硬件累计与输出诊断不一致、定时器意外停止或AB/CW/CCW互斥破坏时
    立即关闭输出;
  • 兼容32位累计溢出时不得截断或回绕;
  • 限位触发按正负方向发布兼容码,并禁止继续向越界方向启动;
  • 多次STOP_IMMEDIATE按幂等命令处理。

5.1.4 设计风险与关闭条件

编号 风险 处理及关闭条件
RISK-01 四轴100 kHz仍有两轴可能采用软件计数,最坏约200k周期事件/秒 分别验证两硬件+两软件计数组合,记录ISR最坏周期、CPU占用和通信压力结果
RISK-02 TIM9/TIM12只能累计,不能反向自动关闭输出源 最终比较只武装尾边沿,逐数量边界验证无额外或窄脉冲
RISK-03 AB配对定时器时钟分别为168/84 MHz 全频段测量两组AB频率、相位及方向
RISK-04 USB当前中断优先级0 调低优先级并完成USB压力测试
RISK-05 输出电路极性和可靠带宽待实测 测量Q0~Q3带载波形后冻结参数
RISK-06 0.1 ms曲线计算量 定点化和预计算,DWT实测最坏执行时间小于周期预算
RISK-07 16位通信写入造成32位动态频率撕裂 使用影子+COMMIT版本和内核二次校验
RISK-08 Backup SRAM不能保证掉电瞬间零误差 异常复位清position_valid,并记录恢复等级
RISK-09 现有历史写入破坏S0/S1数据 删除历史写入并完成全地址越界测试
RISK-10 信捷保留字段被扩展复用 固定描述表、静态断言和对标矩阵评审
RISK-11 FOLLOW公式尚未在需求中展开 编码前按手册冻结公式和测试向量
RISK-12 TIM9/TIM12内部OC事件相位和跨时钟域同步延迟 测量Q0~Q3的计数对应边沿、首脉冲、末脉冲和动态调频后累计一致性

5.2 错误输出信息

5.2.1 信捷兼容错误码

兼容码 含义 处理
1 脉冲数据段配置错误 拒绝启动,错误块号写SD的B+11
2 每转脉冲数或每转移动量为0 拒绝启动
3 S2参数块号错误 拒绝启动
4 脉冲参数块号或范围错误 拒绝启动
5 正限位触发 减速停止并禁止继续正向启动
6 负限位触发 减速停止并禁止继续反向启动
15 FOLLOW性能不在1~100 拒绝启动
16 FOLLOW前馈不在0~100 拒绝启动
26 控制块或高速资源分配失败 拒绝启动或进入ERROR

5.2.2 项目增强错误

错误 含义 级别
DEFAULT_SPEED_INVALID 段频率0但S2默认速度非法 启动拒绝/轴错误
SEGMENT_OVERFLOW 路径段数超过100 启动拒绝
OUTPUT_MODE_INVALID 输出模式或D组合非法 启动拒绝
RESOURCE_CONFLICT 脉冲点或DIR点冲突 启动拒绝
PARAMETER_LOCKED 运行中修改锁定参数 写入拒绝
DONE_STATE_ERROR DONE状态转换异常 轴错误
SPEED_CLAMPED 速度被S2最高速度限幅 告警
POSITION_INVALID 绝对定位前位置无效 启动拒绝
COUNTER_OVERFLOW 内部或兼容累计溢出 轴错误
ILLEGAL_TRANSITION 非法状态机转换 轴错误
TIMER_FAULT 定时器初始化或运行异常 轴/全局错误
PULSE_COUNT_MISMATCH 软件计数与诊断计数不一致 轴错误
HW_COUNTER_FAULT TIM9/TIM12计数器意外停止、越权或累计不一致 轴错误
HW_COUNTER_FALLBACK 硬件计数器不可用,当前段使用软件计数 诊断提示,不终止任务

5.2.3 错误信息结构

typedef struct {
    PlsrError error;
    uint16_t compatible_code;
    uint8_t axis;
    uint16_t segment;
    uint16_t bad_block;
    uint32_t command_sequence;
    uint32_t stop_reason;
    uint32_t detail_a;
    uint32_t detail_b;
    uint64_t timestamp;
} PlsrErrorDetail;

错误信息通过增强状态接口发布;兼容码和错误块号同时写入固定SD字段。相同错误重复发生可增加计数,
但不得覆盖更高优先级停止原因。

5.2.4 验证要求

验证阶段 内容 合格条件
V1 Q0~Q3固定频率与安全电平 引脚、极性、频率、占空比正确
V2 TIM9/TIM12单轴硬件计数及软件兜底计数 两种模式数量误差均为0,无窄脉冲和多余边沿
V3 四轴100 kHz并发,两硬件计数+两软件计数 计数误差0,轴间无串扰,CPU和ISR数据可接受
V4 两组AB及CW/CCW 计数器分配、相序、周期、互斥和数量正确
V5 0.1/1 ms曲线与调频 响应、曲线和段边界正确
V6 多段、等待、跳转和事件 与S0语义一致
V7 STOP、PAUSE、限位和错误 优先级、尾脉冲和终态正确
V8 Modbus/USB压力及长稳 不影响脉冲和状态一致性
V9 Flash、Backup SRAM和复位 CRC有效、不自动续跑、位置有效性正确

测试记录应包含固件版本、参数快照、接线、测量设备、原始波形、实际边沿数、方向建立时间、AB相位、
ISR平均/最坏周期、CPU占用和结论。

6 参考资料

  1. PLSR需求规格统计_V1.3.md
  2. PLSR地址映射.md
  3. PLSR信捷对标追踪矩阵.md
  4. 实现PLSR指令.pdf
  5. 信捷XD/XL系列PLC定位控制手册
  6. STM32F4xx参考手册 RM0090 Rev.22
  7. 当前工程 CoreModbusMiddlewaresUSB_DEVICEEWARM 目录