From 31e9874a1971b6622a7cb7861028850c6a63fa1b Mon Sep 17 00:00:00 2001 From: ywh <2227158009@qq.com> Date: Tue, 4 Aug 2026 21:07:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=99=E4=BA=86=E4=BA=9B=E9=9C=80=E6=B1=82?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Core/Src/main.c | 6 +- .../PLSR_document/PLSR_Modbus通信协议.md | 657 ++++++++++++++ .../PLSR信捷对标追踪矩阵.md | 120 +++ Document/PLSR_document/PLSR地址映射.md | 50 ++ .../PLSR_document/PLSR需求确认清单.md | 524 +++++++++++ .../PLSR_document/PLSR需求规格统计.md | 823 +++++++++++------- Document/PLSR_document/设计方案书.doc | Bin 0 -> 28365 bytes Document/PLSR_document/需求规格书.docx | Bin 0 -> 32324 bytes 8 files changed, 1844 insertions(+), 336 deletions(-) create mode 100644 Document/PLSR_document/PLSR_Modbus通信协议.md create mode 100644 Document/PLSR_document/PLSR信捷对标追踪矩阵.md create mode 100644 Document/PLSR_document/PLSR地址映射.md create mode 100644 Document/PLSR_document/PLSR需求确认清单.md create mode 100644 Document/PLSR_document/设计方案书.doc create mode 100644 Document/PLSR_document/需求规格书.docx diff --git a/Core/Src/main.c b/Core/Src/main.c index 62a942a..95a89a1 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -76,7 +76,7 @@ static void AppTaskStart(void *pArg) * 初始化函数会立即启动USART1的DMA空闲接收 */ (void)ModbusSlaveInit(&huart1, MODBUS_SLAVE_DEFAULT_ADDRESS); - ModbusRetainedRegistersLoad(); + //ModbusRetainedRegistersLoad(); while (1) { /* @@ -100,13 +100,13 @@ static void AppTaskStart(void *pArg) // (void)ModbusSlaveSetHoldingRegister( // 非法数据值计数 // D6, (uint16_t)ModbusSlaveStatistics.illegalValueCount); - HistorySaveToRegisters(); + // HistorySaveToRegisters(); /* * 每1ms轮询一次, */ ModbusSlavePoll(); - ModbusRetainedRegistersPoll(); + // ModbusRetainedRegistersPoll(); if (ModbusSlaveIsConnected(MODBUS_CONNECTION_TIMEOUT_MS) != 0U) { diff --git a/Document/PLSR_document/PLSR_Modbus通信协议.md b/Document/PLSR_document/PLSR_Modbus通信协议.md new file mode 100644 index 0000000..d5142c1 --- /dev/null +++ b/Document/PLSR_document/PLSR_Modbus通信协议.md @@ -0,0 +1,657 @@ +# PLSR Modbus通信协议 + +> 协议版本:V1.0 +> 地址表修订:R5 +> 目标平台:XDM-60T4-E +> 对标依据:[信捷XD/XL系列PLC定位控制手册](./信捷XD_XL系列PLC定位控制手册_PD02_20260510_V1.3.pdf) +> 对应需求:[PLSR需求规格统计.md](./PLSR需求规格统计.md) +> +> R5变更:取消Modbus通信历史区;S0、S1改为在1000~9199数据池中运行时指定首地址 +> 的动态数据块;其余PLSR参数和状态固定映射到Modbus保持寄存器。取消固定S0槽和 +> 每轴内嵌S1数据。 +> R4变更:已定义固定字段的PLSR地址标记为已占用;仅未定义字段的扩展区保持保留。 +> R3变更:区分工程已占用地址和PLSR推荐预留地址。 +> R2变更:区分可选操作数、固定相对布局和信捷固定软元件地址;增加Y0~Y3公共参数、 +> K0~K4参数组及运行状态地址与本项目Modbus字段的逐项对应表。 + +## 1. 地址和数据约定 + +### 1.1 地址表示 + +本文所有地址均为Modbus PDU中的**零基地址**。例如: + +| 本文地址 | 传统4xxxx写法 | +|---:|---:| +| 200 | 40201 | +| 5160 | 45161 | + +上位机如果使用“地址从1开始”显示,应在本文地址基础上加1。代码、报文和测试用例 +统一使用本文零基地址,禁止直接把`40201`作为PDU地址发送。 + +### 1.2 字节序和字序 + +- 单个16位寄存器使用Modbus大端字节序。 +- 32位数据占两个寄存器,高16位在前、低16位在后。 +- 64位数据占四个寄存器,从最高16位到最低16位依次排列。 +- 有符号数采用二进制补码。 +- 写入32位或64位命令参数时必须使用功能码`0x10`一次写完,禁止拆成多个`0x06`后立即触发。 + +示例:32位数`0x12345678`从地址A开始保存为: + +```text +A+0 = 0x1234 +A+1 = 0x5678 +``` + +### 1.3 访问权限 + +| 标记 | 含义 | +|---|---| +| RO | 只读,主站写入应返回非法数据地址或非法数据值 | +| RW-S | 影子参数可读写,COMMIT成功后才进入运行配置 | +| RW-L | 运行时可读写,按字段定义立即或在控制周期内生效 | +| WO-T | 只写触发字段;写入后产生一次命令处理 | +| RES | 保留,读回0,写入拒绝 | + +当前工程的通用Modbus数组尚未实施字段级读写权限。接入PLSR时必须增加地址权限校验, +不能仅依赖文档约束上位机。 + +### 1.4 原子提交规则 + +1. 每轴保存S0、S1动态数据块首地址;S2、D和公共参数使用固定地址影子区。 +2. 主站写完某轴配置后,发送`COMMIT_AXIS`命令。 +3. 从站完整检查段数、输出冲突、频率、跳转、限位和参数范围。 +4. 校验成功后原子复制到该轴运行配置,并更新`ACTIVE_GENERATION`。 +5. 校验失败时运行配置保持不变,返回错误码和错误数据块号。 +6. 已启动任务不受后续影子参数写入影响;运行中调频使用`SET_TARGET_FREQUENCY`命令。 +7. COMMIT成功后轴使用S0、S1、S2和D的私有不可变运行快照;修改原动态数据块不得 + 影响已经提交或已经启动的任务。 + +### 1.5 信捷地址与本项目地址的关系 + +本协议区分三类地址,不得混为一谈: + +1. **可选操作数地址**:信捷PLSR的S0、S1由用户在指令中指定。本项目用每轴固定的 + `S0_BASE_ADDRESS`和`S1_BASE_ADDRESS`保存其运行时首地址;S0、S1数据本身不固定。 + D在本项目中选择Q输出点,S2通过`SELECTED_S2`选择K0~K4。 +2. **固定相对偏移**:S0头部、每段10字、S1两个双字以及S2套组内部字段的相对 + 布局固定。本项目保持这些功能布局。 +3. **固定绝对软元件地址**:信捷为Y0~Y3固定分配SFD、HSD、SD和SM地址。本项目不把 + 这些编号直接作为Modbus PDU地址,而是在第4章提供确定的一一对应关系。 + +因此,“对标信捷固定地址”表示每个信捷字段都能唯一映射到本项目字段并保持等效语义, +不表示主站可以把`SFD900`直接当作Modbus地址900访问。若后续需要兼容信捷软元件编号, +应增加独立的地址转换层;已经实施并冻结的Modbus PDU地址不得直接改义。 + +## 2. 现有占用和推荐预留方案 + +工程标准Modbus保持寄存器范围为0~9999。下表中的数值全部是**本项目Modbus PDU +零基地址**,不是信捷SFD、HSD或SD软元件编号。信捷不同类型的软元件拥有彼此独立的 +编号空间,例如SFD和SD可以出现相同编号,不能直接合并到一个Modbus保持寄存器空间。 + +当前占用情况及推荐预留方案如下: + +| Modbus保持寄存器范围 | 数量 | 当前状态 | 推荐用途 | 信捷PLSR对应关系 | 所有者/建议使用者 | +|---:|---:|---|---|---|---| +| 0~199 | 79 | 保留 | 无 | 无 | 待定 | +| 200~255 | 56 | 保留 | PLSR全局信息、命令和应答 | 指令调用与诊断增强;信捷无同地址区 | PLSR | +| 256~895 | 640 | 已占用 | 四轴S0/S1基址、D、S2和实时状态 | S0/S1为动态操作数;其余对应Y0~Y3固定参数和状态,详见4.1~4.4 | PLSR | +| 896~999 | 104 | 保留 | 推荐作为PLSR动态数据块描述符或近期扩展区 | 无固定信捷地址 | 待定 | +| 1000~9199 | 8200 | 已占用 | S0/S1动态数据池,运行时指定各数据块首地址 | 对应信捷可动态指定首地址的S0和S1数据块 | PLSR | +| 9200~9999 | 800 | 保留 | 推荐用于PLSR后续扩展或事件历史,也可在地址冻结前另行分配 | 无 | 待定 | + +标为“已占用”的范围已经确定具体字段或数据结构,其他模块不得覆盖,即使对应代码尚未 +全部实现,也应视为地址协议已经占位。标为“保留”的范围没有确定字段,推荐用途不构成 +占用;正式分配前仍可调整,但必须更新本地址表修订号并完成全工程冲突检查。 + +本表规定“已确定的数据放在本项目哪个Modbus地址”;第4章解决“该字段对应信捷哪个固定 +软元件地址”。两张表必须结合使用。V1.0不提供把`SFD900`直接解释为PDU地址900的 +物理地址兼容模式。 + +## 3. 全局信息、命令和应答:200~255 + +| 地址 | 名称 | 类型 | 权限 | 说明 | +|---:|---|---|---|---| +| 200 | PROTOCOL_MAGIC_0 | U16 | RO | 固定`0x504C`,ASCII `PL` | +| 201 | PROTOCOL_MAGIC_1 | U16 | RO | 固定`0x5352`,ASCII `SR` | +| 202 | PROTOCOL_VERSION_MAJOR | U16 | RO | 主版本,V1为1 | +| 203 | PROTOCOL_VERSION_MINOR | U16 | RO | 次版本 | +| 204 | ADDRESS_MAP_REVISION | U16 | RO | 地址表修订R5为5 | +| 205 | AXIS_COUNT | U16 | RO | 固定4 | +| 206 | MAX_SEGMENTS | U16 | RO | 固定100 | +| 207 | CAPABILITY_FLAGS | U16 | RO | 能力标志,见3.1 | +| 208~209 | GUARANTEED_MAX_HZ | U32 | RO | 100000 | +| 210~211 | EXTENDED_MAX_HZ | U32 | RO | 200000,非保证扩展区 | +| 212 | REFRESH_CAPABILITIES | U16 | RO | bit0=1 ms,bit1=0.1 ms | +| 213 | GLOBAL_STATUS | U16 | RO | 全局状态标志 | +| 214~215 | RESERVED | - | RES | 保留 | +| 216 | CMD_CODE | U16 | RW-L | 命令码,见3.2 | +| 217 | CMD_AXIS | U16 | RW-L | 0~3;`0xFFFF`表示允许的全轴命令 | +| 218 | CMD_FLAGS | U16 | RW-L | 命令选项 | +| 219 | CMD_RESERVED | - | RES | 保留 | +| 220~223 | CMD_ARG0 | U64/I64 | RW-L | 命令参数0 | +| 224~227 | CMD_ARG1 | U64/I64 | RW-L | 命令参数1 | +| 228~229 | CMD_ARG2 | U32/I32 | RW-L | 命令参数2 | +| 230 | CMD_PAYLOAD_GENERATION | U16 | RW-L | 期望使用的影子参数代号 | +| 231 | CMD_SEQUENCE | U16 | WO-T | **最后写入**;新序号触发一次命令 | +| 232 | ACK_SEQUENCE | U16 | RO | 最近处理完成的命令序号 | +| 233 | CMD_RESULT | U16 | RO | 处理结果,见3.3 | +| 234 | CMD_ERROR_CODE | U16 | RO | 错误码 | +| 235 | CMD_ERROR_DETAIL | U16 | RO | 错误字段或数据块号 | +| 236~239 | ACK_DATA | U64 | RO | 命令返回数据 | +| 240 | GLOBAL_SHADOW_GENERATION | U16 | RO | 最近收到的全局影子代号 | +| 241 | GLOBAL_ACTIVE_GENERATION | U16 | RO | 已生效的全局配置代号 | +| 242 | LAST_EVENT_SEQUENCE | U16 | RO | 全局最近事件序号 | +| 243 | LAST_EVENT_AXIS | U16 | RO | 最近事件轴号 | +| 244 | LAST_EVENT_SEGMENT | U16 | RO | 最近事件段号,1~100 | +| 245 | LAST_EVENT_REASON | U16 | RO | 最近事件原因 | +| 246 | SELF_TEST_STATUS | U16 | RO | 自测状态 | +| 247 | SELF_TEST_ERROR | U16 | RO | 自测错误 | +| 248~255 | RESERVED | - | RES | 保留 | + +### 3.1 CAPABILITY_FLAGS + +| 位 | 含义 | +|---:|---| +| 0 | PULSE/DIR | +| 1 | AB相x4计数 | +| 2 | 四轴独立运行 | +| 3 | 100段路径 | +| 4 | 相对定位 | +| 5 | 绝对定位 | +| 6 | 软限位 | +| 7 | 齿隙补偿 | +| 8 | FOLLOW参数 | +| 9 | 工程单位换算 | +| 10 | 0.1 ms刷新 | +| 11 | Backup SRAM检查点 | +| 12 | 命令序号防重 | +| 13~15 | 保留 | + +### 3.2 CMD_CODE + +| 值 | 命令 | CMD_ARG0 | 说明 | +|---:|---|---|---| +| 0 | NOP | - | 不执行 | +| 1 | COMMIT_AXIS | - | 校验指定轴的S0/S1动态块及S2/D固定参数,并创建运行快照 | +| 2 | START | - | 异步启动指定轴 | +| 3 | STOP_DECEL | - | 指定轴减速停止;轴`0xFFFF`表示全部轴 | +| 4 | STOP_IMMEDIATE | - | 指定轴立即停止;轴`0xFFFF`表示全部轴 | +| 5 | PAUSE | - | 减速暂停 | +| 6 | RESUME | - | 继续暂停任务 | +| 7 | SET_POSITION | I64位置 | 设置逻辑当前位置并置`position_valid` | +| 8 | CLEAR_POSITION | - | 当前位置清零并置有效 | +| 9 | CLEAR_TOTAL | - | 清零累计输出脉冲 | +| 10 | SAVE_CONFIG | - | 固定配置保存到Flash | +| 11 | LOAD_CONFIG | - | 加载已保存固定配置,不自动启动 | +| 12 | RESET_ERROR | - | 清除可恢复错误 | +| 13 | SELF_TEST | 测试掩码 | 执行内部自测 | +| 14 | SET_TARGET_FREQUENCY | U32频率 | 运行中调频,在S2刷新周期内开始生效 | +| 15 | CLEAR_EVENT | - | 确认并清除最近事件锁存 | + +### 3.3 CMD_RESULT + +| 值 | 名称 | 含义 | +|---:|---|---| +| 0 | IDLE | 尚未处理命令 | +| 1 | ACCEPTED | 已接受,异步执行中 | +| 2 | SUCCESS | 执行成功 | +| 3 | REJECTED | 命令被拒绝,查看错误码 | +| 4 | DUPLICATE | 相同序号,未重复执行并返回上次结果 | + +`CMD_SEQUENCE`为16位循环序号。主站发送新命令时递增,通信重试必须保持原序号。 +从站缓存最近序号及完整结果;相同序号不得再次产生运动。 + +## 4. 每轴固定块:256~895 + +每轴占160个保持寄存器: + +```text +AXIS_BASE(axis) = 256 + axis × 160,axis取0~3 +``` + +| 轴 | AXIS_BASE | 范围 | +|---:|---:|---:| +| 0 | 256 | 256~415 | +| 1 | 416 | 416~575 | +| 2 | 576 | 576~735 | +| 3 | 736 | 736~895 | + +### 4.1 信捷固定地址逐轴对应 + +下表给出信捷Y0~Y3固定软元件区与本项目轴块的唯一对应关系。信捷使用Y点名称, +本项目板级输出使用Q点名称;表中的Y0~Y3表示信捷对标轴序号,不等于本项目Q点编码。 + +| 本项目轴 | 信捷脉冲轴D | 本项目轴块 | 信捷公共参数 | 信捷K0动态参数 | 信捷K1 | 信捷K2 | 信捷K3 | 信捷K4 | +|---:|---|---:|---|---|---|---|---|---| +| 0 | Y0 | 256~415 | SFD900~943 | HSD460~479 | SFD950~969 | SFD970~989 | SFD990~1009 | SFD1010~1029 | +| 1 | Y1 | 416~575 | SFD1030~1073 | HSD480~499 | SFD1080~1099 | SFD1100~1119 | SFD1120~1139 | SFD1140~1159 | +| 2 | Y2 | 576~735 | SFD1160~1203 | HSD500~519 | SFD1210~1229 | SFD1230~1249 | SFD1250~1269 | SFD1270~1289 | +| 3 | Y3 | 736~895 | SFD1290~1333 | HSD520~539 | SFD1340~1359 | SFD1360~1379 | SFD1380~1399 | SFD1400~1419 | + +信捷固定运行状态地址与本项目实时状态区对应如下: + +| 本项目轴 | 信捷运行标志 | 信捷方向标志 | 信捷实时SD区 | 信捷累计脉冲 | 本项目实时状态区 | +|---:|---|---|---|---|---:| +| 0 | SM1000 | SM1001 | SD1000~1011 | HSD0~1 | 384~415 | +| 1 | SM1020 | SM1021 | SD1020~1031 | HSD4~5 | 544~575 | +| 2 | SM1040 | SM1041 | SD1040~1051 | HSD8~9 | 704~735 | +| 3 | SM1060 | SM1061 | SD1060~1071 | HSD12~13 | 864~895 | + +信捷段事件中断号固定为Y0对应`I6000~I6099`、Y1对应`I6100~I6199`、Y2对应 +`I6200~I6299`、Y3对应`I6300~I6399`。本项目不复用PLC中断号,而通过 +`SEGMENT_EVENT_SEQUENCE`、`SEGMENT_EVENT_NUMBER`和`SEGMENT_EVENT_REASON`发布等效事件。 + +常用起始地址速查: + +| 轴 | S0/S1动态基址配置 | D/公共参数 | S2-K0 | 实时状态 | +|---:|---:|---:|---:|---:| +| 0 | 256 | 272 | 304 | 384 | +| 1 | 416 | 432 | 464 | 544 | +| 2 | 576 | 592 | 624 | 704 | +| 3 | 736 | 752 | 784 | 864 | + +### 4.2 S0/S1动态基址和选择信息:AXIS_BASE+0~15 + +| 偏移 | 名称 | 类型 | 权限 | 说明 | +|---:|---|---|---|---| +| +0 | S0_BASE_ADDRESS | U16 | RW-S | S0数据块在1000~9199动态池中的零基首地址 | +| +1 | S0_WORD_COUNT | U16 | RW-S | S0实际占用字数,必须等于`10+段数×10` | +| +2 | S1_BASE_ADDRESS | U16 | RW-S | S1数据块在1000~9199动态池中的零基首地址 | +| +3 | SELECTED_S2 | U16 | RW-S | 选择固定参数套组K0~K4,取值0~4 | +| +4 | AXIS_SHADOW_GENERATION | U16 | RW-S | 主站写完S0、S1和轴参数后最后递增 | +| +5 | AXIS_ACTIVE_GENERATION | U16 | RO | 最近成功COMMIT的代号 | +| +6 | AXIS_CONFIG_STATUS | U16 | RO | bit0影子完整,bit1活动配置有效,bit2影子已修改 | +| +7 | EXPECTED_S0_CRC16 | U16 | RW-S | COMMIT时核对S0数据块CRC16,防止写入中途启动 | +| +8 | EXPECTED_S1_CRC16 | U16 | RW-S | COMMIT时核对S1的4个字 | +| +9 | OPERAND_FLAGS | U16 | RW-S | 当前必须为0,保留动态数据块属性扩展 | +| +10 | ACTIVE_S0_BASE_ADDRESS | U16 | RO | 最近成功COMMIT快照的S0来源首地址 | +| +11 | ACTIVE_S1_BASE_ADDRESS | U16 | RO | 最近成功COMMIT快照的S1来源首地址 | +| +12~+15 | RESERVED | - | RES | 保留 | + +`AXIS_BASE+0~15`只保存操作数地址、固定参数组选择和原子提交信息,不保存S0、S1 +数据本体。S0和S1可以被不同轴共享;COMMIT后各轴使用私有快照,后续改写动态数据池 +不会改变已提交任务。S0和S1数据块不得重叠,活动写入也不得破坏其他轴正在提交的数据。 + +### 4.3 D及脉冲公共参数:AXIS_BASE+16~47 + +| 偏移 | 名称 | 类型 | 权限 | 说明 | +|---:|---|---|---|---| +| +16 | D_PULSE_A_POINT | U16 | RW-S | PULSE点或AB的A点,点编码见4.6 | +| +17 | D_DIR_B_POINT | U16 | RW-S | DIR点或AB的B点 | +| +18 | D_OUTPUT_MODE | U16 | RW-S | 0=PULSE/DIR,1=AB相 | +| +19 | PULSE_OUTPUT_POLARITY | U16 | RW-S | 0正常,1反相 | +| +20 | DIRECTION_POLARITY | U16 | RW-S | 0正逻辑,1负逻辑 | +| +21 | COUNT_EDGE | U16 | RO | PULSE/DIR固定0=物理上升沿;AB固定4=x4 | +| +22 | DIRECTION_DELAY_MS | U16 | RW-S | 默认10 ms | +| +23 | PULSE_UNIT | U16 | RW-S | 单位编码见4.5 | +| +24~+25 | PULSES_PER_REV | U32 | RW-S | 每转指令脉冲数,必须非0 | +| +26~+27 | MOVE_UNITS_PER_REV | U32 | RW-S | 每转移动量,单位为所选工程单位,必须非0 | +| +28 | SEGMENT_SEND_MODE | U16 | RW-S | 0完成方式,1后续方式 | +| +29 | SOFT_LIMIT_ENABLE | U16 | RW-S | 0关闭,1启用 | +| +30 | POS_LIMIT_INPUT | U16 | RW-S | 正限位输入点编码,`0xFFFF`无输入 | +| +31 | NEG_LIMIT_INPUT | U16 | RW-S | 负限位输入点编码,`0xFFFF`无输入 | +| +32 | LIMIT_INPUT_POLARITY | U16 | RW-S | bit0正限位、bit1负限位;0常开,1常闭 | +| +33 | COMMON_FLAGS | U16 | RW-S | 保留扩展标志,当前必须写0 | +| +34~+35 | SOFT_POSITIVE_LIMIT | I32 | RW-S | 正软限位逻辑坐标 | +| +36~+37 | SOFT_NEGATIVE_LIMIT | I32 | RW-S | 负软限位逻辑坐标 | +| +38~+39 | BACKLASH_POSITIVE | U32 | RW-S | 正向齿隙补偿量 | +| +40~+41 | BACKLASH_NEGATIVE | U32 | RW-S | 反向齿隙补偿量 | +| +42~+43 | ELECTRICAL_ORIGIN | I32 | RW-S | 电气原点位置 | +| +44 | AB_COUNT_MODE | U16 | RO | 固定4,表示x4边沿计数 | +| +45 | OUTPUT_RESOURCE_FLAGS | U16 | RO | 输出能力和占用状态 | +| +46~+47 | RESERVED | - | RES | 保留 | + +信捷公共参数地址设为`B`:Y0/Y1/Y2/Y3的`B`分别为SFD900/SFD1030/SFD1160/SFD1290。 +本项目公共字段按下表与信捷固定地址对应;无直接对应项属于本项目增强字段。 + +| 本项目偏移 | 本项目字段 | 信捷固定地址/字段 | +|---:|---|---| +| +16 | D_PULSE_A_POINT | PLSR的D操作数(Y0~Y3),不是SFD参数 | +| +17 | D_DIR_B_POINT | B+6,脉冲方向端子 | +| +18 | D_OUTPUT_MODE | B+0中的脉冲输出类型/AB相配置 | +| +19 | PULSE_OUTPUT_POLARITY | B+0中的脉冲输出逻辑 | +| +20 | DIRECTION_POLARITY | B+0中的方向逻辑 | +| +21、+44 | COUNT_EDGE、AB_COUNT_MODE | 本项目固定语义,信捷无独立参数地址 | +| +22 | DIRECTION_DELAY_MS | B+7 | +| +23 | PULSE_UNIT | B+0中的脉冲单位字段 | +| +24~+25 | PULSES_PER_REV | B+2~B+3 | +| +26~+27 | MOVE_UNITS_PER_REV | B+4~B+5 | +| +28 | SEGMENT_SEND_MODE | B+1 | +| +29 | SOFT_LIMIT_ENABLE | B+0中的软限位使能位 | +| +30~+31 | POS/NEG_LIMIT_INPUT | B+15的高、低字节 | +| +32 | LIMIT_INPUT_POLARITY | B+12中的限位端子极性位 | +| +34~+35 | SOFT_POSITIVE_LIMIT | B+20~B+21 | +| +36~+37 | SOFT_NEGATIVE_LIMIT | B+22~B+23 | +| +38~+39 | BACKLASH_POSITIVE | B+8 | +| +40~+41 | BACKLASH_NEGATIVE | B+9 | +| +42~+43 | ELECTRICAL_ORIGIN | B+10~B+11 | +| +45 | OUTPUT_RESOURCE_FLAGS | 本项目资源冲突检查增强字段 | + +### 4.4 S2参数套组:AXIS_BASE+48~127 + +每轴有5套S2,每套16个寄存器: + +```text +S2_BASE(axis, set) = AXIS_BASE(axis) + 48 + set × 16 +set取0~4 +``` + +| 相对S2偏移 | 名称 | 类型 | 权限 | 说明 | +|---:|---|---|---|---| +| +0~+1 | DEFAULT_FREQUENCY_HZ | U32 | RW-S | 段频率为0时使用,同时定义加减速斜率基准 | +| +2 | ACCEL_TIME_MS | U16 | RW-S | 默认速度对应的加速时间,0表示无加速 | +| +3 | DECEL_TIME_MS | U16 | RW-S | 默认速度对应的减速时间,0表示无减速 | +| +4 | BACKLASH_TIME_MS | U16 | RW-S | 齿隙补偿加减速时间 | +| +5 | CURVE_MODE | U16 | RW-S | 0直线,1=S形,2=正弦,3保留 | +| +6~+7 | MAX_FREQUENCY_HZ | U32 | RW-S | 最高速度限制 | +| +8~+9 | START_FREQUENCY_HZ | U32 | RW-S | 任务起始速度 | +| +10~+11 | END_FREQUENCY_HZ | U32 | RW-S | 任务终止速度 | +| +12 | FOLLOW_PERFORMANCE | U16 | RW-S | 1~100 | +| +13 | FOLLOW_FEEDFORWARD | U16 | RW-S | 0~100% | +| +14 | REFRESH_PERIOD | U16 | RW-S | 0=1 ms,1=0.1 ms | +| +15 | RESERVED | - | RES | 保留 | + +S2第0套保存在Backup SRAM动态区,第1~4套属于固定配置并由`SAVE_CONFIG`保存到Flash。 + +信捷每套S2参数也采用20个软元件的固定步长,其中PLSR字段使用`P+0~P+14`, +`P+15`保留,`P+16~P+19`为ZRN参数。本项目只映射PLSR所需的前16个寄存器: + +| 本项目S2偏移 | 信捷参数组偏移 | 含义 | +|---:|---:|---| +| +0~+1 | P+0~P+1 | 默认速度/频率 | +| +2 | P+2 | 加速时间 | +| +3 | P+3 | 减速时间 | +| +4 | P+4 | 补间/补偿加减速时间 | +| +5 | P+5 | 脉冲加减速模式 | +| +6~+7 | P+6~P+7 | 最高速度 | +| +8~+9 | P+8~P+9 | 起始速度 | +| +10~+11 | P+10~P+11 | 终止速度 | +| +12 | P+12 | FOLLOW性能参数 | +| +13 | P+13 | FOLLOW前馈补偿参数 | +| +14 | P+14 | 脉冲频率刷新时间 | +| +15 | P+15 | 保留 | + +### 4.5 PULSE_UNIT编码 + +编码与信捷配置语义对应: + +| 值 | 单位 | +|---:|---| +| 0 | 脉冲个数/Hz | +| 1 | 1 μm | +| 3 | 0.01 mm | +| 5 | 0.1 mm | +| 7 | 1 mm | + +### 4.6 Q点和I点编码 + +PLC点名采用八进制风格编号,寄存器中使用连续逻辑ID,避免把Q10误解成十进制第10点: + +| ID | 输出点 | MCU | ID | 输出点 | MCU | +|---:|---|---|---:|---|---| +| 0 | Q0 | PF6 | 9 | Q11 | PG6 | +| 1 | Q1 | PF8 | 10 | Q12 | PH9 | +| 2 | Q2 | PF7 | 11 | Q13 | PH8 | +| 3 | Q3 | PF9 | 12 | Q14 | PH7 | +| 4 | Q4 | PI8 | 13 | Q15 | PH6 | +| 5 | Q5 | PE6 | 14 | Q16 | PF11 | +| 6 | Q6 | PE5 | 15 | Q17 | PB0 | +| 7 | Q7 | PE4 | 16 | Q20 | PH5 | +| 8 | Q10 | PG7 | 65535 | 无输出点 | - | + +输入点采用相同连续ID规则:I0~I7对应0~7,I10~I17对应8~15,I20对应16, +`0xFFFF`表示无输入点。具体MCU引脚由板型适配表定义。 + +### 4.7 实时状态:AXIS_BASE+128~159 + +状态读取应采用快照:从站更新所有多字字段后最后递增`SNAPSHOT_SEQUENCE`;主站读取前后 +两次序号一致时,才能认为本次状态一致。 + +| 偏移 | 名称 | 类型 | 权限 | 说明 | +|---:|---|---|---|---| +| +128 | AXIS_STATE | U16 | RO | 状态枚举见4.8 | +| +129 | AXIS_STATUS_FLAGS | U16 | RO | 方向、输出和限位等标志 | +| +130 | ERROR_CODE | U16 | RO | 当前锁存错误 | +| +131 | ERROR_DATA_BLOCK | U16 | RO | 出错字段或段号 | +| +132 | CURRENT_SEGMENT | U16 | RO | 当前段号1~100,空闲为0 | +| +133 | TOTAL_SEGMENTS | U16 | RO | 当前任务总段数 | +| +134 | ACTIVE_S2 | U16 | RO | 当前S2套组0~4 | +| +135 | LAST_STOP_REASON | U16 | RO | 完成、STOP、限位、急停或错误 | +| +136~+137 | CURRENT_FREQUENCY_HZ | U32 | RO | 当前实际指令频率 | +| +138~+139 | TARGET_FREQUENCY_HZ | U32 | RO | 当前目标频率 | +| +140~+141 | SEGMENT_EMITTED | U32 | RO | 本段已发指令脉冲/AB计数边沿 | +| +142~+143 | SEGMENT_REMAINING | U32 | RO | 本段剩余数量 | +| +144~+147 | LOGICAL_POSITION | I64 | RO | 当前逻辑位置 | +| +148~+151 | TOTAL_PULSE_COUNT | U64 | RO | 总累计输出量 | +| +152~+155 | TASK_EMITTED | U64 | RO | 本次任务累计输出量 | +| +156 | SEGMENT_EVENT_SEQUENCE | U16 | RO | 每次段事件递增 | +| +157 | SEGMENT_EVENT_NUMBER | U16 | RO | 最近事件段号 | +| +158 | SEGMENT_EVENT_REASON | U16 | RO | 完成、ACT、EXT、STOP等 | +| +159 | SNAPSHOT_SEQUENCE | U16 | RO | 状态快照序号,最后更新 | + +### 4.8 AXIS_STATE + +| 值 | 状态 | +|---:|---| +| 0 | UNINITIALIZED | +| 1 | IDLE | +| 2 | ACCEL | +| 3 | RUN | +| 4 | DECEL | +| 5 | WAIT | +| 6 | PAUSED | +| 7 | COMPLETED | +| 8 | STOPPED | +| 9 | ERROR | + +### 4.9 AXIS_STATUS_FLAGS + +| 位 | 含义 | +|---:|---| +| 0 | 指令活动,包括运动、等待和暂停 | +| 1 | 物理脉冲正在输出 | +| 2 | 正方向 | +| 3 | AB模式 | +| 4 | 位置有效 | +| 5 | 正硬限位有效 | +| 6 | 负硬限位有效 | +| 7 | 正软限位到达 | +| 8 | 负软限位到达 | +| 9 | 急停锁存 | +| 10 | 影子配置已修改但未提交 | +| 11 | 活动配置有效 | +| 12~15 | 保留 | + +### 4.10 段事件和停止原因 + +| 值 | 原因 | +|---:|---| +| 0 | NONE | +| 1 | PULSE_COMPLETE | +| 2 | WAIT_TIME_COMPLETE | +| 3 | WAIT_SIGNAL_ACTIVE | +| 4 | ACT_TIME | +| 5 | EXT_SIGNAL | +| 6 | EXT_OR_COMPLETE_BY_EXT | +| 7 | EXT_OR_COMPLETE_BY_PULSE | +| 8 | STOP_DECEL | +| 9 | STOP_IMMEDIATE | +| 10 | POS_LIMIT | +| 11 | NEG_LIMIT | +| 12 | EMERGENCY_STOP | +| 13 | ERROR | +| 14 | NORMAL_TASK_COMPLETE | + +## 5. S0/S1动态数据池:1000~9199 + +S0和S1不设置固定数据块地址。主站在1000~9199范围内自行选择不重叠的连续区域, +写入数据后,把首地址分别写入目标轴的`S0_BASE_ADDRESS`和`S1_BASE_ADDRESS`。 + +动态数据池共8200个保持寄存器,可容纳至少4个满100段的S0数据块、4个S1数据块, +并保留余量。数据池地址已经由PLSR占用,其他模块不得用于通信历史或其他功能。 + +分配必须满足: + +1. S0首地址和S1首地址均位于1000~9199。 +2. S1固定占4个寄存器;S0占用`10+段数×10`个寄存器,范围不得越过9199。 +3. 任意两个同时存在的数据块不得重叠;允许多个轴只读共享同一个完整数据块。 +4. 主站写完数据后计算CRC16,再写入轴基址、字数和期望CRC,最后递增 + `AXIS_SHADOW_GENERATION`并发送`COMMIT_AXIS`。 +5. COMMIT重新检查范围、长度、CRC和字段内容,成功后复制私有快照;CRC不一致时拒绝 + 启动并返回“动态数据块正在变化”。 + +### 5.1 S1数据块 + +S1首地址记为`S1_BASE`,由`S1_BASE_ADDRESS`指定: + +| S1偏移 | 名称 | 类型 | 权限 | 说明 | +|---:|---|---|---|---| +| +0~+1 | S1_POSITION_MODE | U32 | RW | 0相对,1绝对 | +| +2~+3 | S1_START_SEGMENT | U32 | RW | 0或1从第1段开始,2~100从指定段开始 | + +S1只包含上述两个双字字段。异步调用、命令序号、轴选择、S2选择以及S0/S1基址均不属于S1。 + +### 5.2 S0头部 + +| S0偏移 | 名称 | 类型 | 权限 | 说明 | +|---:|---|---|---|---| +| +0~+1 | SEGMENT_COUNT | U32 | RW-S | 1~100 | +| +2~+9 | RESERVED | - | RES | 对标信捷保留8个寄存器 | + +### 5.3 每段10寄存器布局 + +段号`N`取1~100: + +```text +SEGMENT_BASE(N) = S0_BASE_ADDRESS + N × 10 +``` + +| 段内偏移 | 名称 | 类型 | 权限 | 说明 | +|---:|---|---|---|---| +| +0~+1 | SEGMENT_FREQUENCY | U32 | RW-S | 0表示使用所选S2默认速度 | +| +2~+3 | SEGMENT_PULSE_COUNT | I32 | RW-S | 完整INT32范围,负数表示反向 | +| +4 | WAIT_CONFIG | U16 | RW-S | 高8位等待条件,低8位参数来源类型 | +| +5~+6 | WAIT_VALUE_OR_REFERENCE | U32 | RW-S | 常数值或变量/点编号 | +| +7 | JUMP_SOURCE_TYPE | U16 | RW-S | 低8位有效,高8位必须为0 | +| +8~+9 | JUMP_VALUE_OR_REFERENCE | U32 | RW-S | 常数段号或变量编号 | + +段1位于`S0+10`,段100位于`S0+1000`,最后占用到`S0+1009`。 + +### 5.4 WAIT_CONFIG高8位 + +| 值 | 条件 | 行为 | +|---:|---|---| +| 0 | PULSE_COMPLETE | 本段数量完成后跳转 | +| 1 | WAIT_TIME | 完成后等待指定毫秒数,0按1 ms | +| 2 | WAIT_SIGNAL | 完成后等待位信号有效 | +| 3 | ACT_TIME | 从段开始计时,到时放弃剩余脉冲并跳转 | +| 4 | EXT_SIGNAL | 输入上升沿到来时跳转;若脉冲先完成则等待边沿 | +| 5 | EXT_OR_COMPLETE | EXT边沿或脉冲完成先到者触发跳转 | + +### 5.5 WAIT_CONFIG低8位 + +| 值 | 来源 | WAIT_VALUE_OR_REFERENCE含义 | +|---:|---|---| +| 0 | CONSTANT | 直接常数 | +| 1 | HOLDING_VOLATILE | 普通保持寄存器零基地址 | +| 2 | HOLDING_BACKUP | Backup SRAM保持变量编号/地址 | +| 3 | HOLDING_FLASH | Flash固定参数编号/地址 | +| 4 | INPUT_POINT | I点逻辑ID | +| 5 | INTERNAL_COIL | 普通内部线圈零基地址 | +| 6 | RETAINED_COIL | 掉电保持内部线圈编号 | + +对于WAIT_TIME和ACT_TIME,动态数值为无符号毫秒数;对于WAIT_SIGNAL、EXT_SIGNAL和 +EXT_OR_COMPLETE,动态数值表示位或输入点。EXT条件只允许有效的外部输入来源。 + +### 5.6 JUMP_SOURCE_TYPE + +| 值 | 来源 | +|---:|---| +| 0 | CONSTANT | +| 1 | HOLDING_VOLATILE | +| 2 | HOLDING_BACKUP | +| 3 | HOLDING_FLASH | + +跳转值范围0~100: + +- 0:顺序进入下一段;最后一段为0时任务结束。 +- 1~100:跳转到指定段。 +- 等于当前段:允许有意无限循环。 + +动态跳转变量在发生段转换时读取。超出范围应进入ERROR,不得越界访问S0。 + +## 6. 线圈映射:100~163 + +为对标信捷“正在发脉冲标志”等位状态,每轴分配16个只读线圈: + +该线圈范围已经定义固定状态字段,属于PLSR已占用的线圈地址。其他模块不得覆盖;代码 +接入前仍须扫描现有线圈使用情况,若发现历史冲突,必须升级地址表修订号后整体调整。 +线圈只是兼容性只读镜像,权威状态全部位于每轴保持寄存器实时状态区;不读取线圈也能 +取得完整PLSR状态。 + +```text +AXIS_COIL_BASE(axis) = 100 + axis × 16 +``` + +| 偏移 | 名称 | 权限 | 说明 | +|---:|---|---|---| +| +0 | INSTRUCTION_ACTIVE | RO | 指令仍处于运行/等待/暂停状态 | +| +1 | PULSE_ACTIVE | RO | 当前物理脉冲正在输出 | +| +2 | COMPLETED | RO | 最近任务正常完成 | +| +3 | ERROR | RO | 轴处于错误状态 | +| +4 | WAITING | RO | 正在等待段条件 | +| +5 | PAUSED | RO | 已暂停 | +| +6 | POSITION_VALID | RO | 逻辑位置有效 | +| +7 | CONFIG_VALID | RO | 活动配置有效 | +| +8 | POS_HARD_LIMIT | RO | 正硬限位有效 | +| +9 | NEG_HARD_LIMIT | RO | 负硬限位有效 | +| +10 | POS_SOFT_LIMIT | RO | 正软限位到达 | +| +11 | NEG_SOFT_LIMIT | RO | 负软限位到达 | +| +12 | EMERGENCY_STOP | RO | 软件急停锁存 | +| +13 | SEGMENT_EVENT_TOGGLE | RO | 每次段事件翻转,便于PLC/HMI边沿检测 | +| +14 | AB_MODE_ACTIVE | RO | 当前使用AB模式 | +| +15 | RESERVED | RO | 固定0 | + +轴0线圈范围100~115,轴1为116~131,轴2为132~147,轴3为148~163。 +这些线圈必须在协议处理层拒绝功能码`0x05`和`0x0F`写入。 + +## 7. 对标信捷与本项目增强的边界 + +### 7.1 保持信捷语义 + +- S0头部、每段10寄存器布局、等待类型编码和跳转编码与信捷功能一致。 +- S1仅包含相对/绝对和起始段。 +- S0、S1由调用方在动态数据池中指定首地址,不绑定轴,也不设置固定数据块地址。 +- S2选择0~4套参数,并保留信捷速度、曲线、补偿、FOLLOW和刷新参数。 +- 段频率为0时使用S2默认速度。 +- 运行中修改目标频率在刷新周期内生效,且不改变剩余脉冲数。 + +### 7.2 地址编码边界 + +- 不把HD、HSD、SFD、SM编号直接复刻为Modbus PDU地址,但必须维持第4.1、4.3和4.4节 + 规定的一一对应关系。 +- 不复制XDPPro配置界面。 +- D通过本项目连续逻辑ID保存Q点,并通过轴号、板型映射和资源冲突检查对应信捷Y轴语义。 + +### 7.3 本项目增强 + +- 四轴独立影子参数和原子COMMIT。 +- 命令序号防止Modbus重试造成重复运动。 +- 64位逻辑位置、累计量和任务计数。 +- 独立`INSTRUCTION_ACTIVE`与`PULSE_ACTIVE`,可区分运动和等待。 +- 快照序号保证多字状态一致。 +- AB相x4计数、两轴AB以及混合输出资源检查。 + +## 8. 实现前检查 + +- [ ] 在`modbus_rtu_slave.h`中增加本地址表常量。 +- [ ] 协议处理层实施RO、RW-S、RW-L、WO-T权限。 +- [ ] 功能码`0x10`写多字数据时保持原子性。 +- [ ] CMD_SEQUENCE写入时对命令参数做一致性快照。 +- [ ] COMMIT校验四轴Q点、定时器和AB点对冲突。 +- [ ] 状态发布最后更新SNAPSHOT_SEQUENCE。 +- [ ] 测试地址边界895/896、999/1000、9199/9200和9999。 +- [ ] 测试S0/S1动态块的边界、重叠、共享、长度和CRC校验。 +- [ ] 使用四轴各100段执行读写和并发运行压力测试。 +- [ ] 按第4.1、4.3和4.4节逐项验证信捷固定地址对应关系,无遗漏、无一对多歧义。 diff --git a/Document/PLSR_document/PLSR信捷对标追踪矩阵.md b/Document/PLSR_document/PLSR信捷对标追踪矩阵.md new file mode 100644 index 0000000..6275268 --- /dev/null +++ b/Document/PLSR_document/PLSR信捷对标追踪矩阵.md @@ -0,0 +1,120 @@ +# PLSR 信捷对标追踪矩阵 + +> 矩阵版本:V1.0 Rev.B +> 基准资料:[信捷XD/XL系列PLC定位控制手册](./信捷XD_XL系列PLC定位控制手册_PD02_20260510_V1.3.pdf) +> 对应规格:[PLSR需求规格统计.md](./PLSR需求规格统计.md) +> 对标原则:信捷PLSR已有功能全部纳入,本项目增强功能允许保留;Y0~Y3的PLSR固定软元件 +> 地址按[PLSR地址映射](./PLSR地址映射.md)一比一对应。 + +状态说明: + +- `已纳入`:已写入V1.0需求。 +- `等效实现`:功能和外部行为一致,但使用本项目数据结构或Modbus接口。 +- `待实机确认`:手册语义存在歧义,需要信捷实机或厂家资料关闭。 +- `增强`:信捷手册没有强制规定,本项目额外提供。 + +## 1. 指令和参数模型 + +| 信捷功能 | 手册位置(印刷页) | 本项目要求 | 状态 | +|---|---:|---|---| +| `PLSR S0 S1 S2 D` | 49 | 保留S0/S1/S2/D逻辑模型 | 已纳入 | +| 上升沿启动且启动条件断开后继续 | 49 | START接受后锁存运行 | 等效实现 | +| STOP中断运动 | 49 | 支持减速停止和立即停止 | 增强 | +| S0为可选择首地址的脉冲数据块 | 6~17 | 运行时指定未占用保持寄存器首地址,保持信捷固定相对布局 | 一比一实现 | +| S1为可选择首地址的用户参数块 | 17~18 | 在动态数据池中指定首地址,仅含相对/绝对和起始段 | 已纳入 | +| S2选择K0~K4 | 18~24、49 | 每轴提供0~4套参数 | 已纳入 | +| D选择脉冲输出端口 | 49 | D选择轴、输出形式和输出点资源 | 增强 | + +## 2. 脉冲和定位 + +| 信捷功能 | 手册位置(印刷页) | 本项目要求 | 状态 | +|---|---:|---|---| +| 1 Hz~100 kHz | 49 | V1.0保证1 Hz~100 kHz | 已纳入 | +| 100~200 kHz非保证输出说明 | 50 | 板测后开放非保证扩展区并告警 | 已纳入 | +| 有符号32位脉冲数 | 49 | 支持完整INT32范围 | 已纳入 | +| 负数表示反向 | 49 | 有符号脉冲数量决定方向 | 已纳入 | +| 频率增减与方向无关 | 49 | 速度规划与方向符号分离 | 已纳入 | +| 段频率0使用默认速度 | 56 | 使用当前S2默认速度 | 已纳入 | +| 段脉冲数0的行为 | 56 | 实机确认连续/终止语义后冻结 | 待实机确认 | +| 相对定位 | 17、69等 | 支持相对模式 | 已纳入 | +| 绝对定位 | 17、69等 | 支持绝对模式 | 已纳入 | +| 绝对目标等于累计位置时不输出 | 50 | 零脉冲直接完成 | 已纳入 | +| 当前累计脉冲掉电保持 | 48、50 | Backup SRAM检查点和独立有效标志 | 增强 | +| 运行中修改当前段频率立即生效 | 50、56 | 在S2配置的0.1/1 ms内生效 | 已纳入 | +| 其它段参数下次启动生效 | 50 | 影子参数提交,下次任务生效 | 增强 | + +## 3. S0多段、等待和跳转 + +| 信捷功能 | 手册位置(印刷页) | 本项目要求 | 状态 | +|---|---:|---|---| +| 1~100段 | 6、51 | 每轴最多100段 | 已纳入 | +| 每段频率和有符号脉冲数 | 6 | 等效字段 | 已纳入 | +| 脉冲完成后跳段 | 7~8 | H00等效条件 | 已纳入 | +| Wait时间 | 8~9 | 完成后计时,0按1 ms,最大INT32_MAX ms | 已纳入 | +| Wait信号 | 9~11 | 完成后判断,提前有效则立即通过 | 已纳入 | +| ACT时间 | 11~13 | 从段开始计时,可中途放弃剩余脉冲 | 已纳入 | +| EXT信号 | 13~15 | 上升沿立即跳段,优先外部中断输入 | 已纳入 | +| EXT或脉冲完成 | 15~16 | 先到条件决定跳段 | 已纳入 | +| 等待参数支持常数和多种变量 | 16 | 常数、输入、内部位、普通/保持变量 | 等效实现 | +| 跳转目标支持常数或变量 | 16~17 | 常数或运行时变量,范围0~100 | 等效实现 | +| 跳转0为顺序,最后一段0为结束 | 17 | 相同语义 | 已纳入 | +| 跳转自身为无限循环 | 17 | 相同语义并提供诊断 | 增强 | +| 指定起始段,0/1均从第一段开始 | 18 | 相同语义 | 已纳入 | +| 最后一段非完成条件保持等待 | 7 | WAIT状态保持至条件或STOP | 等效实现 | + +## 4. 速度曲线和段衔接 + +| 信捷功能 | 手册位置(印刷页) | 本项目要求 | 状态 | +|---|---:|---|---| +| 完成方式 | 29~30、55 | 段完成后才向下一速度变化 | 已纳入 | +| 后续方式 | 29~30、55 | 段边界前达到下一段速度 | 已纳入 | +| 直线加减速 | 42 | 支持 | 已纳入 | +| S形加减速 | 42 | 支持 | 已纳入 | +| 正弦曲线加减速 | 42 | 支持 | 已纳入 | +| 短段自动形成三角曲线 | 55 | 自动压缩短距离曲线 | 已纳入 | +| 默认速度与加减速时间定义斜率 | 40、50 | 使用相同斜率模型 | 已纳入 | +| 起始速度和终止速度 | 43 | S2参数 | 已纳入 | +| 最高速度限制 | 22~24 | S2参数 | 已纳入 | +| 最后一段动态变频后重算曲线 | 56 | 动态修改后重算剩余曲线 | 已纳入 | + +## 5. 公共参数和输出方式 + +| 信捷功能 | 手册位置(印刷页) | 本项目要求 | 状态 | +|---|---:|---|---| +| 方向逻辑 | 25、60等 | 正/负逻辑可配置 | 已纳入 | +| 方向输出点 | 31、60等 | 从有效未占用Q点配置 | 等效实现 | +| 方向延时 | 31、41 | 默认10 ms,单位ms可配置 | 已纳入 | +| PULSE/DIR | 29、49 | 最多四轴 | 已纳入 | +| AB相输出 | 29、70等 | 最多两轴,x4边沿计数 | 增强 | +| 脉冲单位 | 28~29 | 支持脉冲模式 | 已纳入 | +| 1 μm、0.01/0.1/1 mm当量 | 28 | 内核直接换算并保存余数 | 增强 | +| 每转脉冲数和每转移动量 | 28、60等 | 公共参数 | 已纳入 | +| 软限位和正负限位值 | 25~26 | 减速停止、禁越界方向、允许反向离开 | 已纳入 | +| 硬限位输入和常开/常闭 | 31、61等 | 输入点及极性可配置 | 已纳入 | +| 正反向齿隙补偿 | 31、41~43 | V1.0实现 | 已纳入 | +| 补偿加减速时间 | 41 | S2参数 | 已纳入 | +| FOLLOW性能参数 | 23~24、44 | 范围1~100 | 已纳入 | +| FOLLOW前馈补偿 | 23~24、44 | 范围0~100% | 已纳入 | +| 0.1 ms/1 ms刷新 | 24、44 | S2配置,独立硬件控制周期 | 增强 | + +## 6. 监控、事件和本项目增强 + +| 功能 | 本项目要求 | 状态 | +|---|---|---| +| 每段对应脉冲中断 | 提供带轴号、段号、原因的段事件 | 等效实现 | +| 正在发脉冲标志 | 每轴独立运行标志 | 等效实现 | +| 当前段脉冲数 | 每轴当前段已发/剩余计数 | 增强 | +| Modbus状态监控 | 原子状态快照 | 增强 | +| 参数原子提交 | 影子参数加COMMIT | 增强 | +| 命令防重 | 命令序号保证只执行一次 | 增强 | +| 四轴资源检查 | PULSE/DIR轴数 + 2×AB轴数不超过4 | 增强 | +| 自测和错误数据块号 | 参数、状态机、计数、跳转、定时器和冲突诊断 | 增强 | + +## 7. 关闭准则 + +严格功能对标完成必须同时满足: + +1. 本矩阵不存在未处理的信捷PLSR功能。 +2. `待实机确认`项目已通过信捷实机或厂家书面资料关闭。 +3. 所有`已纳入`和`等效实现`项目具有测试用例和结果。 +4. Y0~Y3的PLSR固定软元件地址不得作为差异项;差异仅限编程界面或明确记录的增强行为。 diff --git a/Document/PLSR_document/PLSR地址映射.md b/Document/PLSR_document/PLSR地址映射.md new file mode 100644 index 0000000..f2016d9 --- /dev/null +++ b/Document/PLSR_document/PLSR地址映射.md @@ -0,0 +1,50 @@ +# PLSR 地址映射 + +> 文档版本:V1.0 +> 适用轴:Y0~Y3 + +## 1 固定配置参数 + +| 地址 | 用途 | +|---|---| +| HSD460~539 | K0参数区 | +| SFD900~1419 | 公共参数及K1~K4参数区 | + +## 2 固定运行状态 + +| 地址 | 用途 | +|---|---| +| HSD0~15 | 累计脉冲状态 | +| SM1000、SM1001 | Y0运行和方向状态 | +| SM1020、SM1021 | Y1运行和方向状态 | +| SM1040、SM1041 | Y2运行和方向状态 | +| SM1060、SM1061 | Y3运行和方向状态 | +| SD1000~1011 | Y0实时运行状态 | +| SD1020~1031 | Y1实时运行状态 | +| SD1040~1051 | Y2实时运行状态 | +| SD1060~1071 | Y3实时运行状态 | + +## 3 固定事件入口 + +| 地址 | 用途 | +|---|---| +| I6000~6399 | Y0~Y3每段事件入口 | + +## 4 动态数据地址 + +| 地址 | 用途 | +|---|---| +| S0 | 路径数据块,首地址动态指定 | +| S1 | 执行参数块,首地址动态指定 | + +汇总 + + +| 类别 | 固定地址 | +|---|---:| +| K0参数 | HSD460~539 | +| 公共参数及K1~K4参数 | SFD900~1419 | +| 累计脉冲状态 | HSD0~15 | +| 正在发脉冲、方向标志 | SM1000~SM1001、SM1020~SM1021、SM1040~SM1041、SM1060~SM1061 | +| 实时运行状态 | SD1000~1011、SD1020~1031、SD1040~1051、SD1060~1071 | +| 每段事件入口 | I6000~6099、I6100~6199、I6200~6299、I6300~6399 | \ No newline at end of file diff --git a/Document/PLSR_document/PLSR需求确认清单.md b/Document/PLSR_document/PLSR需求确认清单.md new file mode 100644 index 0000000..5eaaacc --- /dev/null +++ b/Document/PLSR_document/PLSR需求确认清单.md @@ -0,0 +1,524 @@ +# PLSR 需求确认清单 + +> 清单版本:V1.0 Rev.B(S0/S1动态地址及固定参数映射确认) +> 创建日期:2026-08-04 +> 对应需求文档:[PLSR需求规格统计.md](./PLSR需求规格统计.md) + +## 填写说明 + +1. 在选中的选项前将 `[ ]` 修改为 `[x]`。 +2. 标有“单选”的项目只能选择一项。 +3. 标有“多选”的项目可以选择多项。 +4. 不清楚的硬件参数可以选择“待上板实测”。 +5. 如果没有填写,需求评审时默认采用标有“建议”的选项。 +6. 补充内容直接填写在横线或“备注”后。 + +确认人:_虞文昊___________________ +确认日期:_________2026/8/4_________ +计划开始日期:_________2026/8/4_____ +计划验收日期:_______2026/8/25_______ + +--- + +## 1. 开发板范围 + +### 1.1 首版验收平台(单选) + +- [ ] 只验收 XDM-60T4-E,T10-E 仅保留兼容设计(建议) +- [ ] 同时验收 XDM-60T4-E 和 XDM-60T10-E +- [ ] 只验收 XDM-60T10-E +- [x] 只验收 XDM-60T4-E + +补充型号或要求:____________________________________________ + +### 1.2 MCU 和时钟 + +- [x] 确认使用 STM32F407,外部晶振 12 MHz,CPU 168 MHz(建议) +- [ ] 参数需要修改 + +修改内容:____________________________________________________ + +## 2. 轴数和输出点 + +### 2.1 V1.0 轴数(单选) + +- [ ] 单轴(建议) +- [ ] 双轴 +- [x] 四轴(V1.0 的 PULSE/DIR 最多四轴,AB 相最多两轴) +- [ ] 其他:________轴 + +### 2.2 四轴输出点 + +脉冲输出点:Q0、Q1、Q2、Q3 +脉冲 MCU 引脚:Q0/PF6、Q1/PF8、Q2/PF7、Q3/PF9 +脉冲定时器/通道:Q0/PF6/TIM10_CH1、Q1/PF8/TIM13_CH1、Q2/PF7/TIM11_CH1、Q3/PF9/TIM14_CH1 + +AB 相输出点对:AB轴0使用 Q0(A)/Q1(B),AB轴1使用 Q2(A)/Q3(B)。 +每个 PULSE/DIR 轴占用一个高速输出点,每个 AB 轴占用两个高速输出点,且满足 +`PULSE/DIR轴数 + 2 × AB轴数 ≤ 4`。 + +方向点允许从 XDM-60T4-E 的有效输出点 `Q0~Q7、Q10~Q17、Q20` 中运行时配置; +不得与任何正在使用的脉冲点或其它已占用输出点冲突。四轴全部启用时,方向点白名单为: + +| 方向输出点 | MCU 引脚 | 方向输出点 | MCU 引脚 | +|---|---|---|---| +| Q4 | PI8 | Q5 | PE6 | +| Q6 | PE5 | Q7 | PE4 | +| Q10 | PG7 | Q11 | PG6 | +| Q12 | PH9 | Q13 | PH8 | +| Q14 | PH7 | Q15 | PH6 | +| Q16 | PF11 | Q17 | PB0 | +| Q20 | PH5 | | | + +- [x] 上述映射已经原理图确认 +- [ ] 上述映射已经上板实测 +- [ ] 映射尚未确认,开发前需要核对(建议在第 1 周第一天完成) + +### 2.3 输出点配置方式(单选) + +- [ ] 编译时固定脉冲点和方向点 +- [x] 运行时从支持列表中配置(建议) +- [ ] 任意 Q 点均可配置 + +## 3. 伺服脉冲接口 + +### 3.1 输出形式(单选) + +- [ ] PULSE/DIR(建议) +- [ ] CW/CCW +- [ ] PULSE/DIR 和 CW/CCW 都支持 +- [x] PULSE/DIR 和 AB 都支持 +### 3.2 有效边沿(单选) + +- [x] 上升沿(建议) +- [ ] 下降沿 +- [ ] 参数可配置 + +### 3.3 输出极性(单选) + +- [ ] 高电平有效 +- [ ] 低电平有效 +- [x] 参数可配置(建议) +- [ ] 待上板实测 + +### 3.4 伺服驱动器电气参数 + +伺服品牌及型号:______________________________________________ +最大接收频率:________________ Hz +最小高电平时间:______________ us +最小低电平时间:______________ us +最小方向建立时间:____________ us +最小方向保持时间:____________ us + +- [ ] 参数来自伺服驱动器手册 +- [ ] 参数已经示波器实测 +- [x] 暂时未知,按保守值实现并在联调时确认 + +### 3.5 AB 相计数定义 + +- [x] 采用 x4 边沿计数:A 或 B 每次有效跳变计 1 个指令脉冲 +- [x] AB 模式的目标频率表示每秒有效计数边沿数 +- [x] 一个完整 AB 正交周期对应 4 个指令脉冲 +- [x] 停止时允许保持在任一合法正交状态,下一次运动从该状态继续 + +## 4. 频率和脉冲数量 + +### 4.1 V1.0 保证频率范围(单选) + +- [x] 1 Hz~100 kHz(建议) +- [ ] 1 Hz~200 kHz +- [ ] 其他:________ Hz~________ Hz +- [ ] 先按 100 kHz 实现,最高值由上板测试决定 + +### 4.2 频率误差(单选) + +- [ ] 不超过 ±0.1%(建议) +- [ ] 不超过 ±0.5% +- [x] 只要求使用最佳定时器分频值,不设固定百分比 +- [ ] 其他:________________ + +### 4.3 单段脉冲数量(单选) + +- [x] 完整有符号32位,范围 -2,147,483,648~2,147,483,647,对标信捷 +- [ ] 无符号 32 位,方向单独设置 +- [ ] 64 位脉冲数量 +- [ ] 其他:________________ + +### 4.4 正常完成脉冲误差(单选) + +- [x] 必须为 0 个脉冲(建议) +- [ ] 允许误差:±________个脉冲 + +## 5. 定位模式 + +### 5.1 支持模式(多选) + +- [x] 相对定位(必须,建议勾选) +- [x] 绝对定位(必须,建议勾选) +- [x] 设置当前位置 +- [x] 当前逻辑位置清零 + +### 5.2 绝对位置无效时的处理(单选) + +- [x] 禁止绝对定位,必须先设置或清零当前位置(建议) +- [ ] 自动将当前位置视为 0 +- [ ] 自动读取保存值,即使上次异常掉电 +- [ ] 其他:________________________________________________ + +### 5.3 位置单位(单选) + +- [ ] PLSR 内核只使用脉冲和 Hz,工程单位由上位机换算(建议) +- [ ] PLSR 直接支持 mm、mm/s +- [ ] PLSR 直接支持角度、rpm +- [x] 同时支持脉冲单位和工程单位,对标信捷 + +如需工程单位,请填写: + +``` +脉冲、1 mm、0.1 mm、0.01 mm、1 μm +``` + +每圈指令脉冲数:____________ +电子齿轮比:________________ +机械减速比:________________ +丝杠螺距:________________mm + +## 6. 多段路径 + +### 6.1 最大段数(单选) + +- [x] 100 段,对标信捷(建议) +- [ ] 32 段 +- [ ] 16 段 +- [ ] 其他:________段 + +### 6.2 每段参数(多选) + +- [x] 有符号脉冲数量(必须) +- [x] 目标频率(必须) +- [ ] 段起始频率 +- [ ] 段结束频率 +- [x] 等待类型 +- [x] 等待参数 +- [x] 下一段编号 +- [ ] 本段加速时间 +- [ ] 本段减速时间 +- [ ] 本段曲线类型 + +### 6.3 段起止频率配置方式(单选) + +- [ ] 每段显式配置起始频率和结束频率 +- [x] 只配置每段目标频率,由 S2 和相邻段自动推导(建议) +- [ ] 两种方式都支持;显式值优先,未配置时自动推导 + +### 6.4 段间条件(多选) + +- [x] 当前段脉冲发送完成(必须) +- [x] 等待指定时间(建议) +- [x] 等待指定输入点(建议) +- [x] 输入有效或本段完成 +- [x] 指定下一段(建议) +- [ ] 有限循环(建议) +- [x] 从指定段号开始(建议) +- [ ] 上述功能 V1.0 全部实现 +- [x] ACT 指定时间后跳段 +- [x] EXT 外部输入立即跳段 +- [x] 跳转值为 0:顺序执行 +- [x] 最后一段跳转值为 0:结束 +- [x] 跳转到自身:无限循环 +- [x] “有限循环”没有独立循环次数字段,需要通过寄存器、计数器和动态下一段编号实现。 +- [ ] V1.0 只实现顺序执行,其余放到 V1.1 + +### 6.5 多段衔接方式(多选) + +- [x] 完成方式(建议) +- [x] 后续方式(建议) +- [x] 两种方式均作为 V1.0 强制验收项 +- [ ] V1.0 只实现完成方式 + +## 7. 加减速曲线 + +### 7.1 V1.0 曲线(多选) + +- [x] 无加减速(建议)将加速度时间设为0 +- [x] 直线/梯形加减速(必须,建议勾选) +- [x] S 形加减速(必须,建议勾选) +- [x] 正弦曲线加减速 +- [ ] 正弦曲线作为 V1.1 加分项 + +### 7.2 参数方式(单选) + +- [x] S2 保存默认速度和默认加减速时间,按斜率计算(对标信捷) +- [ ] 直接为每次任务设置总加速时间和总减速时间(建议,接口更直观) +- [ ] 两种方式均支持 + +### 7.3 短距离处理(单选) + +- [x] 自动压缩为三角或短距离曲线(建议) +- [ ] 无法完成完整曲线时拒绝启动 +- [ ] 其他:________________________________________________ + +## 8. 调用方式和运行控制 + +### 8.1 调用方式(多选) + +- [ ] 同步等待(建议) +- [x] 异步返回(建议) +- [ ] 两种方式均作为 V1.0 强制功能 + +### 8.2 运行中控制(多选) + +- [x] 动态修改当前段目标频率(必须) +- [x] 频率刷新周期可选 `1 ms` 或 `0.1 ms` +- [x] 刷新周期保存在 S2 中,调频应在所配置的 `1 ms` 或 `0.1 ms` 内开始生效 +- [x] uC/OS-II Tick 保持 `1 ms`;`0.1 ms` PLSR刷新由独立硬件定时器触发 +- [x] 减速停止(必须) +- [x] 立即停止(必须) +- [x] 暂停(建议) +- [x] 继续(建议) +- [ ] 暂停和继续放到 V1.1 + +### 8.3 重复 START(单选) + +- [ ] 运行中拒绝并返回 BUSY,不影响当前任务(建议) +- [ ] 中止当前任务并启动新任务 +- [ ] 将新任务加入队列 +- [x] 运行中拒绝并且不用返回 BUSY,不影响当前任务(建议) + +### 8.4 通信断开时的运动行为(单选) + +- [ ] 已启动任务继续运行,记录通信断开状态(建议) +- [ ] 通信超时后减速停止 +- [ ] 通信超时后立即停止 +- [x] 已启动任务继续运行,不用记录通信断开状态 +- [ ] 参数可配置 + +## 9. 累计数据和掉电保存 + +### 9.1 必须保存的数据(多选) + +- [x] 输出点和输出极性 +- [x] S2 参数套组 +- [x] 默认运行和衔接模式 +- [x] 总累计脉冲数 +- [ ] 正向、反向累计脉冲数 +- [x] 当前逻辑位置及独立有效标志 +- [ ] 当前逻辑位置有累计位置,但无独立有效标志 +- [ ] 未完成任务及剩余路径 + +### 9.2 参数保存方式(单选) + +- [ ] 内部 Flash 双备份、版本号和 CRC(建议) +- [ ] 只使用 Backup SRAM +- [ ] 外部 EEPROM/FRAM,型号:________________ +- [x] 其他:___固定参数使用 Flash;动态参数使用 Backup SRAM,例如累计位置和第 0 套动态参数_____________________________________________ + +### 9.3 运行中突然掉电的恢复等级(单选) + +- [ ] 只保证已完成任务和检查点;上电不续跑,位置可能无效(建议) +- [x] 有 VBAT,恢复 Backup SRAM 最近检查点;上电不续跑 +- [ ] 要求累计位置零脉冲误差恢复,需要增加 FRAM 或掉电检测 +- [ ] 要求自动继续未完成运动(不建议,需单独安全评审) + +板卡是否安装并有效连接 VBAT: + +- [x] 是 +- [ ] 否 +- [ ] 未确认 + +允许异常掉电丢失的最大累计数据:____________________________ + +- [x] 异常掉电后恢复最近检查点供诊断,但将独立 `position_valid` 标志清零 +- [x] 重新清零、设置位置或完成回零前,禁止绝对定位 + +## 10. 安全输入和伺服状态 + +### 10.1 V1.0 输入信号(多选) + +- [x] 急停;V1.0 无外部硬件切断回路,由软件立即停止脉冲输出 + +信捷明确指出“脉冲发送完成”不等于“伺服到位”,In-position 必须读取伺服反馈信号。 + +- [x] 正限位 +- [x] 负限位 +- [ ] 伺服 Ready +- [ ] 伺服 Alarm +- [ ] 伺服 In-position +- [ ] V1.0 不接入上述硬件信号,只预留软件接口(建议按任务书最小范围) + +### 10.2 限位触发后的行为(单选) + +- [x] 减速停止,禁止继续向限位方向运动(建议) +- [ ] 立即停止,禁止继续向限位方向运动 +- [ ] 可按每个输入单独配置 +- [ ] V1.0 不适用 + +### 10.3 急停行为(单选) + +- [ ] 硬件切断脉冲输出,同时软件记录状态(建议用于正式设备) +- [x] 软件立即停止 +- [ ] 软件减速停止 +- [ ] V1.0 不适用 + +## 11. Modbus 接口 + +### 11.1 接口功能(多选) + +- [x] 读取配置和实时状态(必须) +- [x] 写入单段和多段参数(必须) +- [x] 启动、停止和清零(必须) +- [x] 暂停和继续 +- [x] 保存和加载参数(必须) +- [x] 自测和错误复位(必须) + +### 11.2 参数提交方式(单选) + +- [x] 影子参数写入完成后,通过提交命令原子生效(建议) +- [ ] 每写一个寄存器立即生效 +- [ ] 其他:________________________________________________ + +### 11.3 多字数据寄存器顺序(单选) + +- [x] 高字在前、低字在后(建议) +- [ ] 低字在前、高字在后 + +### 11.4 命令防重(单选) + +- [x] 使用命令序号;相同序号只执行一次(建议)普通参数读写不需要 +- [ ] 不使用命令序号 +- [ ] 其他:________________________________________________ + +## 12. 自测和诊断 + +### 12.1 V1.0 自测项目(多选) + +- [ ] 参数版本和 CRC(本项目增强项,不作为信捷对标前提) +- [x] 输出点冲突 +- [x] 定时器时钟和分频 +- [x] 频率、段数和脉冲数量范围 +- [x] 路径跳转和循环(包括跳转目标及死循环) +- [x] 计数溢出 +- [x] 状态机非法转换 +- [ ] 外部输入回接脉冲输出 + +- [x] 频率、参数块、段数据范围检查 +- [x] 当前段和当前输出频率监控 +- [x] 累计脉冲溢出标志 +- [x] 正负限位停止错误 +- [x] PLSR 每段中断 +- [x] 脉冲错误码和错误数据块号 + + +### 12.2 测试设备(多选) + +- [ ] 示波器 +- [x] 逻辑分析仪 +- [ ] 伺服驱动器和电机 +- [ ] 外部脉冲计数器 +- [x] PC Modbus 测试工具 + +现有设备型号:________________________________________________ + +## 13. 性能和资源预算 + +### 13.1 是否接受当前建议指标 + +- [ ] 频率误差不超过 ±0.1% +- [ ] 正常完成脉冲误差为 0 +- [x] 调频在 S2 配置的 1 ms 或 0.1 ms 内开始生效 +- [ ] PLSR 平均 CPU 占用率不超过 20% +- [ ] PLSR 静态 RAM 不超过 8 KiB +- [ ] 脉冲级中断最坏时间不超过 100 kHz 周期的 25% +- [ ] 运行阶段禁止动态内存分配 +- [ ] 连续运行 24 小时无异常 +- [x] 最大额定频率:100 kHz +- [x] 频率刷新周期:1 ms 或 0.1 ms +- [x] 定位数值范围:32 位有符号数 +- [x] 正常完成按指定脉冲数量停止 +需要修改的指标:________________________________________________ + +## 14. 交付范围 + +### 14.1 必须交付(多选) + +- [ ] PLSR 源代码和头文件 +- [ ] 定时器、GPIO 和板型适配代码 +- [ ] Modbus 通信协议 +- [ ] 参数保存模块 +- [ ] 需求规格书 +- [ ] 软件设计说明书 +- [ ] 测试方案 +- [ ] 测试记录和测试报告 +- [ ] 上位机测试工具 +- [ ] 示例程序和使用说明 + +### 14.2 四周周期(单选) + +- [ ] 接受当前四周开发计划(建议) +- [ ] 周期调整为:________周 +- [ ] 硬件和需求冻结后再确定周期 + +## 15. 后续版本和排除项 + +### 15.1 后续版本或加分项(多选) + +- [ ] AB 相正交脉冲输出(已纳入 V1.0) +- [ ] 外部输入脉冲回读诊断 +- [ ] 多轴输出(四轴独立输出已纳入 V1.0) +- [ ] 超过 100 kHz 输出 +- [x] 完整机械回零(ZRN独立指令,仍为后续项) +- [ ] 齿隙补偿(已纳入V1.0 PLSR) +- [ ] FOLLOW 前馈控制(已纳入V1.0 PLSR) +- [ ] 编码器实际位置监控 + +### 15.2 确认 V1.0 不包含(多选) + +- [x] 编码器闭环位置控制 +- [x] 多轴插补 +- [x] 电子凸轮和龙门同步 +- [ ] 信捷专用软元件地址兼容(已改为V1.0必须一比一对应,不再属于排除项) +- [x] XDPPro 参数界面兼容 +- [x] 完整复制信捷全部运动指令语法 + +## 16. 最终确认 + +### 16.1 需求处理结果(单选) + +- [ ] 清单尚未填写完成 +- [ ] 已填写,但仍有项目需要硬件实测 +- [x] 已填写,同意据此更新 V1.0 需求规格书 +- [ ] 已填写并确认,可以开始软件设计和实现 + +仍需讨论的问题: + +1. CW/CCW 双脉冲不纳入 V1.0;V1.0 实现 PULSE/DIR 与 AB 相输出。 +2. 急停无外部硬件切断,由软件立即停止脉冲输出。 +3. AB 相最多同时运行两轴,采用 x4 边沿计数;点对为 Q0/Q1 和 Q2/Q3,定时器/DMA方案仍需上板验证。 + +确认人签字:____________________ +确认日期:______________________ + +## 17. 信捷 PLSR 功能超集补充确认 + +- [x] 信捷PLSR已有功能全部作为V1.0最低基线,本项目增强功能继续保留 +- [x] Y0~Y3的PLSR固定HSD、SFD、SD、SM和I地址按信捷手册一比一对应 +- [x] S1只保存相对/绝对模式和起始执行段;异步调用不占用S1字段 +- [x] S0和S1在Modbus动态数据池中指定首地址,不设置固定数据块地址,不永久绑定到轴 +- [x] COMMIT时创建轴运行快照,提交后修改原S0/S1动态数据块不影响已提交或已运行任务 +- [x] 除S0和S1外,S2、D、公共参数、命令和状态全部映射到固定保持寄存器地址 +- [x] 取消16条Modbus通信历史,其原地址空间释放给S0/S1动态数据池 +- [x] 段频率为0时使用S2默认速度 +- [x] 脉冲数0的确切语义在实现冻结前通过信捷实机或厂家资料确认 +- [x] Wait时间、Wait信号、ACT、EXT、EXT或完成按信捷触发时序实现 +- [x] Wait时间范围1~2,147,483,647 ms,0按1 ms处理 +- [x] 跳转目标支持常数和运行时变量,0为顺序/结束,自身为无限循环 +- [x] 每段产生包含轴号、段号和结束原因的段事件 +- [x] 支持脉冲、1 μm、0.01 mm、0.1 mm和1 mm单位 +- [x] 支持每转脉冲数、每转移动量及累计余数换算 +- [x] 支持软限位、方向逻辑、方向延时和限位输入极性 +- [x] 方向延时默认10 ms,单位ms并可配置 +- [x] 支持正反向齿隙补偿及补偿加减速时间 +- [x] S2支持FOLLOW性能参数和FOLLOW前馈补偿参数 +- [x] 绝对目标等于当前位置时零脉冲完成 +- [x] START接受后锁存运行,触发条件消失不终止任务 +- [x] 100 kHz以上至200 kHz属于非保证扩展区,通过板级测试后开放 diff --git a/Document/PLSR_document/PLSR需求规格统计.md b/Document/PLSR_document/PLSR需求规格统计.md index cec46c7..f4f97aa 100644 --- a/Document/PLSR_document/PLSR需求规格统计.md +++ b/Document/PLSR_document/PLSR需求规格统计.md @@ -1,98 +1,89 @@ -# PLSR 项目需求规格统计 +# PLSR 需求规格书 -> 文档状态:V0.1(需求基线草案) -> 整理日期:2026-08-03 -> 目标平台:XDM-60T4-E / XDM-60T10-E -> 当前首要目标:在 STM32F407 + uC/OS-II 平台实现单轴 PLSR 定位脉冲模块 +> 文档版本:V1.0 Rev.B(S0/S1动态地址及固定参数映射基线) +> 更新日期:2026-08-04 +> 目标平台:XDM-60T4-E +> 软件平台:STM32F407 + uC/OS-II -## 1. 需求来源 -本规格由以下材料及当前项目讨论整理而成: +[TOC] +## 1 概述 -1. [任务要求.png](./任务要求.png) -2. [实现PLSR指令.pdf](./实现PLSR指令.pdf) -3. [信捷XD_XL系列PLC定位控制手册](./信捷XD_XL系列PLC定位控制手册_PD02_20260510_V1.3.pdf) -4. 当前工程代码,包括 uC/OS-II、Modbus RTU、Backup SRAM 和上位机测试程序 +### 1.1 项目背景 -信捷手册用于功能对标,不要求逐项复制信捷的寄存器地址、软元件和编程软件界面。 -本项目的目标是实现功能相当的自有 PLSR 模块。 +本项目计划在新一代 XDM 系列 PLC 中实现一个高性能定位脉冲输出模块, +通过 PLC 指令或 Modbus 命令驱动伺服驱动器,完成四轴独立位置控制。 -## 2. 范围结论 +项目当前已有以下基础: -### 2.1 V1.0 必须交付 +- STM32F407 硬件平台和 IAR 工程。 +- uC/OS-II 实时操作系统。 +- USART1 DMA Modbus RTU 从站。 +- USB CDC 框架。 +- Backup SRAM 数据保持基础。 +- PC 端 Modbus RTU 测试工具。 -- 基于 uC/OS-II 运行。 -- 单轴 PULSE/DIR 脉冲输出。 -- 指定脉冲数量和输出频率。 -- 正向、反向运动。 -- 相对定位和绝对定位。 -- 前台完成模式和后台运行模式。 -- 运行中修改目标频率。 -- 多段脉冲输出。 -- 多种加减速曲线。 -- 累计脉冲数和逻辑位置记录。 -- 上位机清零累计数据。 -- 参数配置、保存及上电恢复。 -- Modbus RTU 控制和状态监控。 -- 基本自测、错误诊断和完整技术文档。 - -### 2.2 建议作为 V1.0 完整版交付 - -- 最多 100 段路径。 -- 梯形、S 形、正弦三种加减速曲线。 -- 段间延时等待。 -- 段间输入信号等待。 -- 指定下一段和有限循环。 -- 暂停、继续、减速停止和立即停止。 -- 参数 CRC、双备份和恢复默认值。 -- 逻辑分析仪脉冲数量、频率和曲线验证。 - -### 2.3 V1.1 或加分项 - -- AB 相正交脉冲输出。 -- 外部输入回读脉冲的硬件自诊断。 -- 伺服到位、报警及编码器位置监控。 -- 多轴扩展。 -- 更高脉冲频率。 - -### 2.4 当前不在范围内 - -- 闭环位置控制和编码器误差补偿。 -- 多轴直线、圆弧插补。 -- 电子凸轮和龙门同步。 -- 完整机械回零 ZRN 指令。 -- 完整复刻信捷 DRVI、DRVA、PLSF、STOP 和 GOON 指令语法。 -- 兼容信捷 HD、HSD、SFD、SM 等软元件地址。 -- 复制 XDPPro 的 PLSR 参数配置界面。 -- 齿轮间隙补偿和 FOLLOW 前馈控制。 +本项目以信捷 PLC 的 PLSR 功能作为最低功能基线:信捷 PLSR 已有的功能和 +可观察运行语义均应具备;本项目已有的四轴资源管理、Modbus原子提交、命令防重、 +64位累计、诊断和Backup SRAM等增强功能继续保留。Y0~Y3的PLSR操作数、公共参数、 +K0~K4参数组和固定状态地址必须与信捷手册一比一对应;不复制XDPPro参数配置界面。 -## 3. 硬件和系统要求 +逐项对应关系见[PLSR信捷对标追踪矩阵](./PLSR信捷对标追踪矩阵.md)。矩阵中未关闭的 +差异不得宣称为“严格功能对标完成”。 -| 编号 | 需求 | 优先级 | 验收方式 | -|---|---|---|---| -| SYS-01 | 使用 STM32F407 和 12 MHz 外部晶振 | 必须 | 检查工程和系统时钟 | -| SYS-02 | CPU 主频为 168 MHz | 必须 | 读取时钟配置 | -| SYS-03 | 运行于 uC/OS-II | 必须 | 检查任务和调度运行 | -| SYS-04 | 首版适配 XDM-60T4-E(STM32F407IG) | 必须 | T4-E 开发板测试 | -| SYS-05 | 架构兼容 XDM-60T10-E(STM32F407ZG) | 建议 | 编译配置和接口评审 | -| SYS-06 | 使用硬件定时器产生脉冲 | 必须 | 检查代码及示波器波形 | -| SYS-07 | 脉冲输出不依赖 OS Tick 翻转 GPIO | 必须 | 关闭任务调度干扰测试 | -| SYS-08 | 上电及复位过程中输出保持无效 | 必须 | 上电、复位波形测试 | +V1.0 的目标范围如下: -### 3.1 已知板级点位 +- 四轴独立 PULSE/DIR 脉冲输出,不包含多轴插补。 +- AB 相正交脉冲输出和方向控制,最多同时运行两轴。 +- 指定频率、脉冲数量和方向。 +- 相对定位和绝对定位。 +- 单段和多段路径。 +- 多种加减速曲线。 +- 异步返回调用。 +- 完成方式和后续方式两种多段衔接模式。 +- 运行中调频。 +- Modbus 配置和状态监控。 +- 参数及累计数据保存。 +- 自测、诊断和测试文档。 -XDM-60T4-E: +外部脉冲回读、编码器闭环和多轴插补等功能作为后续版本或加分项。 -| PLC 点 | MCU 引脚 | +### 1.2 定义 + +| 名称 | 定义 | |---|---| -| Q0 | PF6 | -| Q1 | PF8 | -| Q2 | PF7 | -| Q3 | PF9 | -| USART1_TX | PA9 | -| USART1_RX | PA10 | +| PLSR | 本项目的定位脉冲输出模块,支持单段及多段位置控制 | +| PULSE/DIR | 脉冲加方向的伺服控制接口,PULSE 表示位置增量,DIR 表示方向 | +| AB 相输出 | A、B 两路相差 90° 的正交脉冲接口,通过相位先后表示方向 | +| 指令位置 | PLC 根据已输出脉冲累计得到的位置,不等同于编码器实际位置 | +| 相对定位 | 以当前逻辑位置为基准移动指定距离 | +| 绝对定位 | 移动到指定逻辑坐标 | +| 异步返回 | 启动成功后立即返回,通过状态接口查询运动结果 | +| 完成方式 | 上一段脉冲发送完后,才开始向下一段频率加减速 | +| 后续方式 | 在上一段内提前变频,使段结束时已经达到下一段频率 | +| S0 | 路径数据块,保存段数、频率、脉冲数、等待和跳转参数 | +| S1 | 用户执行参数,保存定位模式、起始段和调用方式 | +| S2 | K0~K4运动参数套组,保存速度限制、起止频率、加减速、补偿、FOLLOW和刷新周期 | +| D | 输出轴或脉冲输出点 | +| 控制周期 | PLSR 更新状态和速度规划的周期,由 S2 配置为 1 ms 或 0.1 ms | +| 检查点 | 为掉电恢复而保存的一致性累计数据快照 | +| 影子参数 | 上位机可编辑但尚未提交给运行模块的参数副本 | + +## 2 功能需求 + +### 2.1 系统与硬件功能 + +| 编号 | 需求 | 优先级 | +|---|---|---| +| FR-SYS-01 | 系统应运行在 STM32F407 和 uC/OS-II 平台上 | 必须 | +| FR-SYS-02 | 系统应使用 12 MHz 外部晶振并运行于 168 MHz 主频 | 必须 | +| FR-SYS-03 | 首版应在 XDM-60T4-E(STM32F407IG)上完成验收 | 必须 | +| FR-SYS-05 | 脉冲必须由硬件定时器产生,不得使用 OS 延时翻转 GPIO | 必须 | +| FR-SYS-06 | 上电、复位和初始化期间,脉冲及方向输出应处于安全无效状态 | 必须 | +| FR-SYS-07 | V1.0 应支持四轴独立运行,各轴具有独立状态和参数上下文 | 必须 | +| FR-SYS-08 | 四轴之间不要求直线、圆弧或其它形式的插补 | 必须 | -XDM-60T10-E: +已知主要输出点如下: | PLC 点 | MCU 引脚 | |---|---| @@ -100,78 +91,142 @@ XDM-60T10-E: | Q1 | PF8 | | Q2 | PF7 | | Q3 | PF9 | +| Q4 | PI8 | +| Q5 | PE6 | +| Q6 | PE5 | +| Q7 | PE4 | +| Q10 | PG7 | +| Q11 | PG6 | +| Q12 | PH9 | +| Q13 | PH8 | +| Q14 | PH7 | +| Q15 | PH6 | +| Q16 | PF11 | +| Q17 | PB0 | +| Q20 | PH5 | | USART1_TX | PA9 | | USART1_RX | PA10 | -Q 点与定时器通道的最终映射仍需结合 STM32 数据手册、板卡原理图和实测确认。 +Q0~Q3 的脉冲映射为 Q0/PF6/TIM10_CH1、Q1/PF8/TIM13_CH1、 +Q2/PF7/TIM11_CH1、Q3/PF9/TIM14_CH1,仍应通过上板波形测试确认。 +方向点允许从 XDM-60T4-E 的有效输出点 `Q0~Q7、Q10~Q17、Q20` 中配置, +但不得与脉冲点或其它已占用输出点冲突;四轴脉冲全部启用时,方向点应从 +`Q4~Q7、Q10~Q17、Q20` 中选择。 -## 4. 脉冲输出要求 +### 2.2 脉冲输出功能 -| 编号 | 需求 | 建议指标 | 优先级 | -|---|---|---|---| -| PUL-01 | 输出形式 | PULSE/DIR | 必须 | -| PUL-02 | 脉冲有效边沿 | 默认上升沿计数 | 必须 | -| PUL-03 | 占空比 | 50% | 必须 | -| PUL-04 | 保证频率范围 | 1~100,000 Hz | 必须 | -| PUL-05 | 单段脉冲数 | 1~2,147,483,647 | 必须 | -| PUL-06 | 正反方向 | 独立方向输出电平 | 必须 | -| PUL-07 | 方向极性 | 参数可配置 | 必须 | -| PUL-08 | 方向建立时间 | 默认 10 us,可配置 | 必须 | -| PUL-09 | 正常完成脉冲误差 | 0 个 | 必须 | -| PUL-10 | 频率误差 | 不超过 ±0.1% | 必须 | -| PUL-11 | 运行调频响应 | 不超过 1 ms | 必须 | -| PUL-12 | 频率修改 | 不改变剩余脉冲数量 | 必须 | +| 编号 | 需求 | V1.0 指标 | +|---|---|---| +| FR-PUL-01 | 输出形式 | PULSE/DIR、AB 相;不支持 CW/CCW 双脉冲 | +| FR-PUL-02 | PULSE/DIR 有效计数边沿 | 固定为物理上升沿 | +| FR-PUL-03 | 脉冲占空比 | 50% | +| FR-PUL-04 | 输出频率范围 | 1~100,000 Hz | +| FR-PUL-05 | 单段脉冲数量 | 完整有符号32位,范围 -2,147,483,648~2,147,483,647 | +| FR-PUL-06 | 输出方向 | 正向、反向 | +| FR-PUL-07 | 方向有效极性 | 参数可配置 | +| FR-PUL-08 | 方向延时时间 | 默认10 ms,以ms为单位并可配置 | +| FR-PUL-09 | 输出点 | 脉冲点和方向点可配置且不得重复 | +| FR-PUL-10 | 运行调频 | 修改目标频率后不改变剩余脉冲数量 | +| FR-PUL-11 | 四轴运行 | 四轴可独立启动、停止、调频和查询状态 | +| FR-PUL-12 | AB 相方向和计数 | 通过A、B相位先后控制方向;采用x4计数,A或B每次有效跳变计1个指令脉冲 | +| FR-PUL-13 | AB 相轴数 | 最多同时运行两轴;AB轴0使用 Q0(A)/Q1(B),AB轴1使用 Q2(A)/Q3(B) | +| FR-PUL-14 | 高速点资源 | PULSE/DIR轴数 + 2 × AB轴数不得超过4,启动前必须检查资源冲突 | +| FR-PUL-15 | AB 相频率 | 目标频率表示每秒有效计数边沿数,一个完整AB周期对应4个指令脉冲 | +| FR-PUL-16 | 默认速度 | 段频率为0时使用当前S2套组的脉冲默认速度 | +| FR-PUL-17 | 扩展频率 | 100,001~200,000 Hz作为非保证扩展区,仅在板级测试通过后开放并报告警告 | + +手册对“段脉冲个数为0”同时描述了使用默认速度,但没有明确连续输出或零距离的 +终止语义。V1.0实现冻结前必须使用信捷实机或厂家确认该行为,并将结果写入追踪矩阵; +不得自行把0定义为普通非法参数后仍宣称严格对标。 + +最小有效脉宽、输出极性及最高可靠频率还应满足 PLC 输出电路和伺服驱动器 +的电气要求。100 kHz 是 V1.0 建议保证值,更高频率需通过硬件测试后开放。 + +### 2.3 定位功能 + +#### 2.3.1 相对定位 + +相对定位按下式计算: -说明:100 kHz 是 V1.0 建议保证值。是否开放更高频率由 PLC 输出电路、伺服输入规格和上板测试决定。 +```text +目标位置 = 当前逻辑位置 + 相对位移 +``` -## 5. 定位模式 +- 相对位移为正数时正向运动,为负数时反向运动。 +- 正常完成后,逻辑位置应等于目标位置。 +- 中途停止时,应按实际已输出脉冲更新逻辑位置。 -### 5.1 相对定位 +#### 2.3.2 绝对定位 -相对定位的输入值表示相对当前位置需要移动的脉冲数: +绝对定位按下式计算: ```text -目标位置 = 当前逻辑位置 + 相对位移 +输出位移 = 目标绝对位置 - 当前逻辑位置 ``` -- 正数表示正向运动。 -- 负数表示反向运动。 -- 正常完成后更新逻辑位置。 -- 中途停止时按实际已发脉冲更新逻辑位置。 +- 执行绝对定位前,当前位置必须有效。 +- 位置未建立或掉电恢复无效时,应拒绝启动并报告错误。 +- 系统应支持设置当前位置和当前位置清零。 +- 绝对定位只表示 PLC 逻辑坐标,不代表伺服具有绝对值编码器。 -### 5.2 绝对定位 +#### 2.3.3 位置与累计计数 -绝对定位的输入值表示目标逻辑坐标: +系统应维护以下 64 位数据: -```text -实际输出位移 = 目标绝对位置 - 当前逻辑位置 -``` +- 当前逻辑位置。 +- 本次任务累计脉冲数。 +- 总累计脉冲数。 -- 当前位置必须有效。 -- 位置未建立时禁止绝对定位,并返回错误。 -- 支持设置当前位置和当前位置清零。 -- 绝对定位是 PLC 的逻辑坐标功能,不代表伺服具有绝对值编码器。 +上位机应能够读取并清零累计数据。运行期间禁止清零或设置当前位置。 -## 6. S0、S1、S2、D 功能模型 +### 2.4 S0、S1、S2、D 功能模型 项目采用与信捷 PLSR 相似的逻辑模型,但不要求使用相同的物理寄存器地址。 -| 参数 | 本项目含义 | 主要内容 | +| 参数 | 功能 | 主要内容 | |---|---|---| -| S0 | 路径数据块 | 总段数、每段频率、脉冲数、等待和跳转 | -| S1 | 用户执行参数 | 相对/绝对模式、起始段号、执行方式 | -| S2 | 运动参数配方 | 加减速斜率、曲线、最高速度、起止速度 | -| D | 输出轴/脉冲点 | 脉冲输出点及其对应的轴配置 | +| S0 | 路径数据块 | 总段数、每段频率、脉冲数、等待及跳转 | +| S1 | 用户执行参数 | 仅包含相对/绝对模式和起始执行段;异步调用属于指令接口而非S1字段 | +| S2 | 运动参数套组 | K0~K4,包含默认频率、最高频率、起止频率、加减速、曲线、补偿、FOLLOW和刷新周期 | +| D | 输出配置 | 输出形式、PULSE/DIR 点或 AB 点对、输出极性和方向建立时间 | -建议的软件接口关系: +逻辑调用关系为: ```text PLSR_Start(S0路径, S1执行参数, S2参数套组, D输出轴) ``` -### 6.1 S0 路径数据 +Modbus实现应为S0和S1提供动态数据池。调用方在池内选择不重叠的连续区域,并把 +S0、S1首地址传给目标轴;数据块不永久绑定到轴,多个轴允许只读共享同一数据块。 +COMMIT成功时为目标轴创建不可变运行快照,随后修改原动态数据块不得影响已经启动 +或已经提交的轴任务。除S0和S1数据块首地址动态指定外,S2、D、公共参数、命令和 +运行状态均使用固定的Modbus保持寄存器地址。 + +每个输出轴必须提供第0~4套S2参数: + +- 第 0 套用于运行时或上位机动态调整。 +- 第 1~4 套用于保存预设运动配方。 -每段至少包含: +每套S2至少包含: + +- 脉冲默认速度;段频率为0时采用该速度。 +- 默认速度加速时间、默认速度减速时间;二者与默认速度共同定义加减速斜率。 +- 齿隙补偿加减速时间。 +- 直线、S形、正弦三种加减速模式。 +- 最高速度限制、起始速度和终止速度。 +- FOLLOW性能参数,范围1~100。 +- FOLLOW前馈补偿百分比,范围0~100。 +- 脉冲频率刷新周期,0.1 ms或1 ms。 + +S2 的控制刷新周期只允许配置为 `1 ms` 或 `0.1 ms`。系统OS Tick保持1 ms; +0.1 ms运动控制刷新应由独立硬件定时器触发,不得通过提高全局OS Tick实现。 +运行中修改目标频率后, +系统应在当前 S2 所配置的刷新周期内开始应用新目标;该指标表示调频响应时间, +不表示脉冲输出周期。 + +### 2.5 单段与多段路径 + +系统应支持 1~100 段路径,每段至少包含: ```text 有符号脉冲数量 @@ -181,117 +236,105 @@ PLSR_Start(S0路径, S1执行参数, S2参数套组, D输出轴) 下一段编号 ``` -### 6.2 S1 用户参数 +S0应提供与信捷每段数据等效的字段和动态引用能力,但不要求复刻HD寄存器地址: -至少包含: +- 等待条件和等待参数均可表达常数或受支持的数据/位变量引用。 +- 跳转目标可为常数或运行时数据变量引用,范围0~100。 +- Wait时间范围1~2,147,483,647 ms,配置0时按1 ms处理;计时从本段脉冲完成后开始。 +- Wait信号在本段完成后判断;若信号已有效则立即跳段,否则保持WAIT直至有效。 +- ACT从本段开始输出时计时;时间到时放弃本段剩余脉冲并跳段;若脉冲先完成则等待ACT到时。 +- EXT采用输入上升沿;运动中触发立即放弃剩余脉冲并跳段,脉冲先完成则等待后续EXT边沿。 +- EXT或脉冲完成采用先到条件;EXT先到时放弃剩余脉冲,脉冲先完成时立即跳段。 +- 外部中断输入应优先用于EXT,以避免普通IO映射周期造成响应延迟。 -```text -相对/绝对定位模式 -起始执行段号 -前台/后台执行方式 -命令超时时间 -``` +多段路径应满足: -### 6.3 S2 运动参数套组 +| 编号 | 需求 | 优先级 | +|---|---|---| +| FR-SEG-01 | 每段可独立设置有符号脉冲数量 | 必须 | +| FR-SEG-02 | 每段可独立设置目标频率 | 必须 | +| FR-SEG-03 | 段起止频率由S2和相邻段目标频率自动推导,不要求每段显式配置 | 必须 | +| FR-SEG-04 | 同方向连续段允许不停顿变频 | 必须 | +| FR-SEG-05 | 反方向段切换前必须减速停止 | 必须 | +| FR-SEG-06 | 支持当前段完成后执行下一段 | 必须 | +| FR-SEG-07 | 支持等待指定时间及ACT指定时间后跳段 | 必须 | +| FR-SEG-08 | 支持等待指定输入点、EXT立即跳段及输入有效或本段完成 | 必须 | +| FR-SEG-09 | 支持指定下一段;跳转值为0时顺序执行,最后一段为0时结束 | 必须 | +| FR-SEG-10 | 不设置独立有限循环次数字段;有限循环由寄存器、计数器和动态下一段实现 | 必须 | +| FR-SEG-11 | 支持从指定段号开始;跳转到自身表示有意无限循环 | 必须 | +| FR-SEG-12 | 每个实际完成或被条件切换的段均产生带轴号、段号和原因的段事件 | 必须 | +| FR-SEG-13 | 最后一段使用等待类条件时保持WAIT/运行状态,直到条件成立或STOP,不得静默结束 | 必须 | -每个输出轴建议提供 5 套参数(0~4): +运行期间除当前目标频率外,其余路径参数修改不得影响当前任务。新参数应在 +下一次成功提交并启动时生效。 -- 第 0 套用于上位机运行时调整。 -- 第 1~4 套用于保存预设运动配方。 +### 2.6 加减速与段内变频 -每套至少包含: +系统应支持: -```text -默认频率 -最高频率 -起始频率 -结束频率 -默认加速时间 -默认减速时间 -加减速曲线 -频率刷新周期 -``` +- 无加减速。 +- 直线或梯形加减速。 +- S 形加减速。 +- 正弦曲线加减速。 -### 6.4 D 输出配置 +加减速应满足以下规则: -每个轴至少包含: +1. 起始频率、目标频率和结束频率不得超过最高频率。 +2. 目标频率超限时应拒绝启动,不得静默截断。 +3. 加减速距离不足时,应自动生成三角或短距离曲线。 +4. 无法在指定脉冲数量内满足起止频率和曲线约束时,应报告参数冲突。 +5. 加减速过程中必须保证最终脉冲数量准确。 +6. 变频点应由脉冲位置和控制周期共同约束,不得只依赖 OS 延时。 +7. 运行中修改目标频率时,应按照当前曲线平滑过渡。 +8. 反向前应减速至停止,切换方向并等待方向建立时间。 -```text -脉冲输出点 -方向输出点 -脉冲有效极性 -方向有效极性 -方向建立时间 -``` +### 2.7 调用与多段衔接模式 -## 7. 多段路径要求 +调用方式和脉冲衔接方式是两个独立配置项。 -| 编号 | 需求 | 优先级 | +#### 2.7.1 调用方式 + +- V1.0 只提供异步返回:启动成功后立即返回,通过状态接口查询结果。 +- START被接受后即锁存执行;启动条件或通信请求结束不应中断运动,只有正常完成、STOP、限位、急停或错误才能结束。 + +#### 2.7.2 多段衔接方式 + +- 完成方式:上一段按其频率发送完规定脉冲后,才向下一段频率变化。 +- 后续方式:在上一段内提前变频,使上一段结束时已经达到下一段频率。 +- 两种方式都必须保证各段及整个任务的脉冲数量准确。 + +### 2.8 运行控制 + +系统至少应支持以下命令: + +| 命令 | 行为 | 优先级 | |---|---|---| -| SEG-01 | 支持 1~100 段 | 建议 V1.0 | -| SEG-02 | 每段独立设置有符号脉冲数 | 必须 | -| SEG-03 | 每段独立设置目标频率 | 必须 | -| SEG-04 | 同方向连续段允许不停顿变频 | 必须 | -| SEG-05 | 反方向段切换前先减速停止 | 必须 | -| SEG-06 | 支持脉冲完成后执行下一段 | 必须 | -| SEG-07 | 支持等待指定时间 | 建议 V1.0 | -| SEG-08 | 支持等待指定输入点 | 建议 V1.0 | -| SEG-09 | 支持指定下一段 | 建议 V1.0 | -| SEG-10 | 支持有限循环并检测异常死循环 | 建议 V1.0 | -| SEG-11 | 支持从指定段号开始 | 建议 V1.0 | - -多段路径执行期间,除当前段目标频率外,其余结构参数修改不应影响已经启动的任务。新参数在下一次启动时生效。 - -## 8. 加减速要求 - -| 编号 | 曲线 | 优先级 | 说明 | -|---|---|---|---| -| ACC-01 | 无加减速 | 必须 | 调试和低速场景使用 | -| ACC-02 | 直线/梯形 | 必须 | 首个实现和基础验收曲线 | -| ACC-03 | S 形 | 必须 | 降低机械冲击 | -| ACC-04 | 正弦曲线 | 建议 V1.0 | 对标信捷增强能力 | - -其他规则: - -- 起始频率和结束频率不得超过最高频率。 -- 目标频率超过最高频率时拒绝启动,不进行静默截断。 -- 加减速距离不足时自动生成三角速度曲线。 -- 加减速过程中必须保证最终脉冲总数准确。 -- 同方向连续段根据完成/后续模式决定在段边界达到本段速度还是下一段速度。 -- 运行中修改目标频率时,按照当前曲线平滑过渡。 - -## 9. 运行控制 - -| 编号 | 命令 | 行为 | 优先级 | -|---|---|---|---| -| CTL-01 | START | 校验参数并启动任务 | 必须 | -| CTL-02 | STOP_DECEL | 按减速曲线停止 | 必须 | -| CTL-03 | STOP_IMMEDIATE | 完成当前有效脉冲后立即关闭输出 | 必须 | -| CTL-04 | PAUSE | 减速暂停并保留剩余路径 | 建议 V1.0 | -| CTL-05 | RESUME | 从暂停状态继续 | 建议 V1.0 | -| CTL-06 | SET_POSITION | 设置逻辑当前位置 | 必须 | -| CTL-07 | CLEAR_POSITION | 逻辑当前位置清零 | 必须 | -| CTL-08 | CLEAR_TOTAL | 累计脉冲数清零 | 必须 | -| CTL-09 | SAVE_CONFIG | 保存配置参数 | 必须 | -| CTL-10 | LOAD_CONFIG | 重新加载保存参数 | 必须 | -| CTL-11 | RESET_ERROR | 清除可恢复错误 | 必须 | -| CTL-12 | SELF_TEST | 执行内部自测 | 必须 | - -### 9.1 前台完成模式 - -- 调用任务等待运动完成、停止、超时或错误。 -- 使用 uC/OS-II 信号量或事件通知。 -- 禁止在中断上下文中等待。 - -### 9.2 后台运行模式 - -- 参数校验且成功启动后立即返回。 -- 调用方通过状态接口读取结果。 -- 运行中允许调频、暂停、继续和停止。 - -## 10. 状态机和状态数据 - -状态至少包括: +| START | 校验并启动任务 | 必须 | +| STOP_DECEL | 按减速曲线停止 | 必须 | +| STOP_IMMEDIATE | 完成本次有效脉冲后关闭输出 | 必须 | +| PAUSE | 减速暂停并保存剩余路径 | 必须 | +| RESUME | 从暂停状态继续 | 必须 | +| SET_POSITION | 设置逻辑当前位置 | 必须 | +| CLEAR_POSITION | 逻辑当前位置清零 | 必须 | +| CLEAR_TOTAL | 累计脉冲数清零 | 必须 | +| SAVE_CONFIG | 保存稳定配置 | 必须 | +| LOAD_CONFIG | 加载已保存配置 | 必须 | +| RESET_ERROR | 清除可恢复错误 | 必须 | +| SELF_TEST | 执行内部自测 | 必须 | + +命令边界行为: + +- IDLE 状态收到 START 时,校验通过后接受。 +- 运行、减速、等待或暂停状态再次收到 START 时拒绝执行,不重启任务,也不要求返回BUSY。 +- ERROR 状态收到 START 时,应拒绝执行,必须先清除错误。 +- 相同命令序号重复到达时,应返回上次结果,不得重复执行运动。 +- 多次 STOP_IMMEDIATE 应按幂等命令处理。 +- CLEAR_POSITION、SET_POSITION 和 CLEAR_TOTAL 在运行期间应被拒绝。 +- 发生数值溢出时应报告错误,不得依赖整数回绕。 + +### 2.9 状态机与状态监控 + +PLSR 至少应包含以下状态: ```text UNINITIALIZED 未初始化 @@ -306,7 +349,7 @@ STOPPED 停止 ERROR 错误 ``` -上位机至少可以读取: +上位机至少能够读取: - 当前状态和错误码。 - 当前段号和总段数。 @@ -314,170 +357,284 @@ ERROR 错误 - 当前设定频率和目标频率。 - 本段已发、剩余脉冲数。 - 本次任务已发、剩余脉冲数。 -- 当前逻辑位置。 -- 正向、反向和总累计脉冲数。 +- 当前逻辑位置和累计脉冲数。 - 最近一次完成或停止原因。 -- 当前使用的 S2 参数套组。 -- 参数版本、保存序号和 CRC 状态。 +- 当前 S2 参数套组。 +- 每轴正在发送脉冲标志。 +- 当前段已发送脉冲数,以及最近一次段事件的轴号、段号和结束原因。 -## 11. Modbus 要求 +绝对模式目标等于当前累计位置时不得输出脉冲;完成状态不得依赖必须出现一次 +“运行标志下降沿”,应直接返回零位移完成结果。 -现有 USART1 Modbus RTU 从站作为控制和监控通道。 +### 2.10 Modbus 通信 -| 编号 | 需求 | 优先级 | -|---|---|---| -| COM-01 | 读取 PLSR 配置和实时状态 | 必须 | -| COM-02 | 写入单段和多段参数 | 必须 | -| COM-03 | 下发启动、停止和清零命令 | 必须 | -| COM-04 | 参数范围及组合合法性检查 | 必须 | -| COM-05 | 参数写入与运动启动采用提交机制 | 必须 | -| COM-06 | 32/64 位状态采用一致性快照 | 必须 | -| COM-07 | 非法通信参数不得破坏运行任务 | 必须 | -| COM-08 | 保存通信和 PLSR 诊断统计 | 建议 V1.0 | +现有 USART1 Modbus RTU 从站作为配置和监控通道。 -建议采用“影子参数 + 提交命令”机制: +系统应支持: -```text -上位机写影子参数 - ↓ -发送参数提交命令 - ↓ -完整校验 - ↓ -原子复制到运行参数 - ↓ -允许启动 -``` +- 读取 PLSR 配置和实时状态。 +- 写入单段和多段参数。 +- 下发启动、停止、暂停、继续、保存、清零和自测命令。 +- 校验参数范围和组合合法性。 +- 使用影子参数和提交命令,原子更新运行参数。 +- 对 32 位和 64 位状态提供一致性快照。 +- 非法通信参数不得破坏正在运行的任务。 + +协议规则如下: -具体 Modbus 寄存器地址在《PLSR Modbus 通信协议》中单独定义,避免与现有通信历史区冲突。 +1. 16 位寄存器按 Modbus 大端字节序传输。 +2. 32/64 位数据的寄存器顺序必须在通信协议中统一定义。 +3. 参数提交应携带命令序号,响应返回相同序号、状态和错误码。 +4. 重复收到相同序号时,应返回上次结果,不重复启动运动。 +5. 参数提交成功与 START 接受成功应作为两个独立结果。 +6. 主站断开不停止已经接受的运动,也不要求记录通信断开状态。 +7. 运行中写影子参数不得改变当前任务,允许运行修改的目标频率除外。 +8. 协议应包含版本号,新增字段时不得改变既有寄存器语义。 -## 12. 掉电保存要求 +PLSR内存地址、数据类型和固定占用规则见 +[PLSR地址映射](./PLSR地址映射.md);Modbus报文、访问权限和提交规则另见 +[PLSR Modbus通信协议](./PLSR_Modbus通信协议.md)。地址分配必须避开现有演示、 +Backup SRAM保持区。原Modbus通信历史功能不纳入PLSR版本,原历史寄存器区域释放给 +S0/S1动态数据池使用。 + +### 2.11 参数与累计数据保存 需要保存: - 脉冲和方向输出点。 -- 输出极性和方向建立时间。 +- 输出极性及方向建立时间。 - S2 参数套组。 -- 默认运行模式。 +- 默认运行和衔接模式。 - 累计脉冲数。 -- 逻辑当前位置及有效标志。 -- 数据版本、序号和 CRC。 +- 当前逻辑位置及有效标志。 + +保存规则如下: + +1. 固定配置参数使用内部 Flash 保存。 +2. 动态参数、累计位置和第0套动态S2参数使用有VBAT维持的 Backup SRAM 保存。 +3. 不得每个脉冲写 Flash。 +4. 正常完成、正常停止、清零和设置位置后,应保存一致累计值。 +5. SAVE_CONFIG 返回成功后,重新上电必须完整恢复固定配置。 +6. 重新上电不得自动继续未完成运动。 +7. 异常掉电或异常复位后可恢复最近检查点供诊断,但必须清除 `position_valid`。 +8. 重新清零、设置当前位置或完成回零前,禁止绝对定位。 +9. 任意掉电瞬间零脉冲误差恢复需要额外硬件,Backup SRAM单独不能保证。 + +测试报告应记录板卡是否安装 VBAT 以及最终采用的数据恢复等级。 +XDM-60T4-E 已确认安装有效 VBAT,Backup SRAM 可用于保持动态检查点; +当前逻辑位置必须具有独立的 `position_valid` 标志。 + +### 2.11.1 信捷等效脉冲公共参数 -保存策略: +每个轴必须提供以下与PLSR直接相关的公共参数,字段地址严格采用 +[PLSR地址映射](./PLSR地址映射.md)中的信捷原地址,不得采用自定义轴块偏移: -- 配置参数使用内部 Flash 双备份。 -- 新副本校验成功后再替代旧副本。 -- 避免每个脉冲或每毫秒写 Flash。 -- 累计位置在任务完成、清零、设置位置及固定周期检查点保存。 -- Backup SRAM 可用于提高异常复位后的恢复精度。 -- 如果板卡没有 VBAT、FRAM 或掉电检测电路,不能承诺任意断电瞬间零脉冲误差恢复。 -- 复位或重新上电后不得自动恢复电机运动。 +- 脉冲方向逻辑正/负配置。 +- 软限位启用、正极限值和负极限值。 +- 脉冲单位:脉冲、1 μm、0.01 mm、0.1 mm、1 mm。 +- 每转指令脉冲数和每转移动量。 +- 输出类型:PULSE/DIR或AB相。 +- 多段脉冲发送方式:完成方式或后续方式。 +- 方向输出点和方向延时时间;默认10 ms,单位ms,可配置。 +- 正向和反向齿隙补偿量。 +- 电气原点位置。 +- 正负限位输入点及常开/常闭逻辑。 -## 13. 自测与诊断 +工程单位必须在内核换算层支持,不再限定为上位机换算。换算应保存小数余数, +避免多段或重复运动的累计舍入漂移。 -### 13.1 内部自测 +软限位按当前逻辑位置判断。到达对应软限位时执行减速停止,禁止继续向越界方向 +启动,但允许反向离开。软限位和硬限位可同时启用。 + +发生运动方向反转时,应按配置加入对应方向的齿隙补偿脉冲,并使用补偿加减速时间; +补偿脉冲、指令位置和累计脉冲的统计口径必须在设计书中分别定义。 + +### 2.12 自测与诊断 + +内部自测至少包括: -- 参数结构版本和 CRC 检查。 - 输出点冲突检查。 -- 定时器时钟和分频计算检查。 +- 定时器时钟和分频结果检查。 - 频率范围检查。 -- 路径段数、跳转和循环检查。 -- 64 位累计计数溢出检查。 +- 路径段数、等待、跳转和循环检查。 +- 累计计数溢出检查。 - 状态机非法转换检查。 -### 13.2 外部测试 +外部诊断和测试至少包括: - 使用示波器或逻辑分析仪测量输出频率。 - 统计实际脉冲边沿数量。 -- 检查占空比、方向建立时间及方向切换。 -- 检查梯形、S 形和正弦频率曲线。 -- 连续运行和频繁启停压力测试。 -- 可选使用输入点回接输出脉冲进行硬件自诊断。 +- 检查占空比和方向建立时间。 +- 检查梯形、S 形和正弦曲线。 +- 进行连续运行和频繁启停压力测试。 -## 14. 错误码要求 +### 2.13 安全与异常处理 -至少包含: +- 上电、复位、HardFault 和看门狗复位时,脉冲输出必须保持无效。 +- 立即停止命令应具有高于普通运行命令的处理优先级。 +- 不可恢复错误发生后,应禁止装载新脉冲并锁存 ERROR 状态。 +- 清除错误不得自动重新启动未完成运动。 +- 配置限位输入后,限位有效时应禁止向该方向启动,但允许反向离开限位。 +- 运动中限位触发默认执行减速停止。 +- V1.0 急停没有外部硬件切断回路;急停输入由软件立即禁止脉冲输出并锁存状态。 +- 软件急停不具备独立硬件安全回路的故障容错能力,不得宣称为安全认证急停。 + +至少应定义以下错误: ```text 参数未初始化 -输出点非法 -脉冲点与方向点冲突 +输出点非法或冲突 频率为零或超限 -脉冲数非法 -段数非法 -段参数非法 +脉冲数或段数非法 +段参数冲突 跳转段号非法 路径循环超限 绝对位置未建立 模块忙 非法状态命令 定时器初始化失败 -Flash数据无效 -Flash保存失败 +Flash数据无效或保存失败 等待输入超时 立即停止 +累计计数溢出 内部计数异常 ``` -发生严重错误时,模块必须停止装载新脉冲,并使输出回到安全无效电平。 +## 3 性能需求 -## 15. 验收标准 +### 3.1 脉冲性能 + +| 编号 | 性能项 | 验收指标 | +|---|---|---| +| PR-01 | 保证频率范围 | 1 Hz~100 kHz | +| PR-02 | 固定频率误差 | 使用可实现的最佳定时器分频值,记录目标值、实际值及误差,不设统一百分比限值 | +| PR-03 | 正常完成脉冲误差 | 0 个脉冲 | +| PR-04 | 占空比 | 目标 50%,满足驱动器最小高低电平时间 | +| PR-05 | 方向建立时间 | 不小于配置值 | +| PR-06 | 运行调频开始生效 | 不超过当前 S2 配置的 1 ms 或 0.1 ms | +| PR-07 | 段边界 | 不得产生非配置停顿、窄脉冲或重复边沿 | + +### 3.2 实时性能 + +以下是 V1.0 初始预算,首次 100 kHz 压力测试后可根据实测调整,但必须经过 +设计评审并记录原因: + +| 编号 | 性能项 | 初始指标 | +|---|---|---| +| PR-RT-01 | 控制更新周期 | S2 可配置为 1 ms 或 0.1 ms | +| PR-RT-02 | 脉冲产生 | 由硬件定时器维持,不受 OS 调度影响 | +| PR-RT-03 | 脉冲级中断最坏执行时间 | 实测并记录,不得导致脉冲数量错误 | +| PR-RT-04 | PLSR CPU 占用率 | 四轴 100 kHz 并发时以实测记录并验证不影响系统实时性 | +| PR-RT-05 | PLSR 静态 RAM | 实测并记录,不设固定8 KiB限制 | +| PR-RT-07 | 共享数据 | 使用原子快照或临界区保护 | +| PR-RT-08 | 通信压力 | Modbus/USB 压力下脉冲计数误差仍为 0 | + +### 3.3 可靠性 + +| 编号 | 性能项 | 验收指标 | +|---|---|---| +| PR-REL-01 | 连续运行 | 测试时长由测试方案确定,运行期间不得出现计数错误或任务失联 | +| PR-REL-02 | 频繁启停 | 不产生额外脉冲和非法状态转换 | +| PR-REL-03 | 异常参数 | 拒绝执行且不影响当前合法任务 | +| PR-REL-04 | 重新上电 | 输出安全,不自动恢复运动 | +| PR-REL-05 | 参数恢复 | 已成功保存的固定配置和Backup SRAM动态数据能够按定义恢复 | +| PR-REL-06 | 通信并发 | 连续读写状态时运动结果保持准确 | + +### 3.4 工程单位与换算边界 + +- PLSR内核同时支持脉冲模式和当量模式,当量单位为1 μm、0.01 mm、0.1 mm或1 mm。 +- 当量模式根据每转指令脉冲数和每转移动量换算频率与脉冲数量。 +- 换算层必须定义舍入方式并保存累计余数,连续多段运动不得持续产生单向舍入漂移。 +- 上位机仍可提前换算,但不得成为使用工程单位的唯一途径。 +- PLSR 累计脉冲表示指令位置,不等同于电机实际反馈位置。 + +## 4 其它需求 + +### 4.1 验收要求 | 编号 | 验收项 | 合格标准 | |---|---|---| -| TST-01 | 固定频率 | 1 Hz~100 kHz 内误差不超过 ±0.1% | -| TST-02 | 固定脉冲数 | 正常完成误差为 0 个脉冲 | -| TST-03 | 正反转 | 方向电平及脉冲数量正确 | -| TST-04 | 相对定位 | 连续多次相对运动位置累计正确 | -| TST-05 | 绝对定位 | 从不同当前位置到同一目标位置结果正确 | -| TST-06 | 加减速 | 曲线、起止频率和总脉冲数正确 | -| TST-07 | 多段路径 | 段顺序、频率、数量和等待条件正确 | -| TST-08 | 动态调频 | 命令后 1 ms 内开始生效且无异常脉冲 | -| TST-09 | 停止控制 | 减速停止和立即停止符合定义 | -| TST-10 | 掉电参数 | 重新上电后配置校验和恢复正确 | -| TST-11 | 异常参数 | 拒绝启动并返回明确错误码 | -| TST-12 | 连续运行 | 24 小时无异常停止、计数错误或任务失联 | -| TST-13 | Modbus并发 | 通信压力下脉冲输出数量和频率仍正确 | -| TST-14 | 上电安全 | 上电和复位期间无意外脉冲 | - -## 16. 交付物 - -- PLSR 软件源代码和头文件。 +| AT-01 | 固定频率 | 1 Hz~100 kHz 使用最佳定时器分频值,并记录实际误差 | +| AT-02 | 固定脉冲数 | 正常完成误差为 0 个 | +| AT-03 | 正反转 | 方向电平和脉冲数量正确 | +| AT-04 | 相对定位 | 连续相对运动位置累计正确 | +| AT-05 | 绝对定位 | 从不同当前位置到同一目标位置结果正确 | +| AT-06 | 加减速 | 曲线、起止频率和脉冲总数正确 | +| AT-07 | 多段路径 | 段顺序、频率、数量和等待条件正确 | +| AT-08 | 完成方式 | 段结束后才向下一段频率变化 | +| AT-09 | 后续方式 | 段结束时已经达到下一段目标频率 | +| AT-10 | 动态调频 | 在 S2 配置的 1 ms 或 0.1 ms 内开始生效且无异常脉冲 | +| AT-11 | 停止控制 | 减速停止和立即停止符合定义 | +| AT-12 | 重复命令 | 相同命令序号不产生重复运动 | +| AT-13 | 掉电恢复 | 不自动运动,位置有效性符合恢复等级 | +| AT-14 | 上电安全 | 上电和复位期间无意外脉冲 | +| AT-17 | 四轴独立运行 | 四轴可独立启动、停止、调频,状态和累计数据互不串扰 | +| AT-18 | AB 相输出 | 两个AB轴可独立运行;采用x4计数,完整周期4个计数边沿,方向、频率和数量正确 | +| AT-19 | S0等待与跳转 | 六种等待条件、动态参数来源、提前/延后触发和0/指定/自身跳转语义与信捷一致 | +| AT-20 | 公共参数 | 单位换算、软限位、方向延时、齿隙补偿和FOLLOW参数均通过测试 | +| AT-21 | 零值及边界 | INT32最小值、频率0、脉冲数0和绝对零位移行为完成对标测试 | +| AT-22 | 段事件和监控 | 每段事件、运行标志、当前段计数和累计计数可被稳定读取 | + +正式测试应使用开发板、逻辑分析仪和PC Modbus测试工具,并记录测试固件、 +参数、接线、测量设备、原始波形和测试结论。 + +### 4.2 交付物 + +- PLSR 源代码和头文件。 - 硬件定时器、GPIO 和板型适配代码。 - Modbus 寄存器及命令协议。 - Flash 参数保存模块。 -- PLSR 需求规格书。 -- PLSR 软件设计说明书。 +- 需求规格书。 +- 软件设计说明书。 - 单元测试和上板测试方案。 - 测试记录及测试报告。 - 上位机调试或测试工具。 - 示例程序和使用说明。 -## 17. 待确认事项 - -以下项目在开始硬件实现前必须确认: - -1. Q0~Q3 与 STM32 定时器通道的准确映射。 -2. 输出电路的最高可靠频率和有效电平。 -3. 伺服驱动器采用 PULSE/DIR 还是 CW/CCW 接口。 -4. 驱动器的有效边沿、最小脉宽和方向建立时间。 -5. 首版只验收 XDM-60T4-E,还是同时验收 T10-E。 -6. 100 段、外部等待和跳转是否全部列为 V1.0 强制功能。 -7. 掉电位置恢复允许的误差和板卡是否具有 VBAT。 -8. 是否需要将实际距离单位(mm、um)换算放入 PLSR 模块。 -9. 是否需要伺服报警、到位及正负限位输入。 -10. 频率上限最终按 100 kHz 还是更高指标验收。 - -## 18. 建议实施顺序 - -1. 确认定时器和 Q 点映射。 -2. 完成单段、固定频率和精确脉冲计数。 -3. 完成方向、相对定位和绝对定位。 -4. 完成梯形加减速及运行调频。 -5. 完成前台/后台控制和状态机。 -6. 接入 Modbus 参数提交与状态快照。 -7. 完成多段、等待和跳转。 -8. 完成 S 形及正弦曲线。 -9. 完成 Flash 保存、自测和诊断。 -10. 开展压力测试并整理交付文档。 +### 4.3 开发周期 + +项目周期按任务书要求控制为 4 周: + +| 周期 | 主要工作 | 周交付物 | +|---|---|---| +| 第 1 周 | 确认定时器映射;完成单段频率、计数和方向 | 定时器驱动、单段演示、基础波形 | +| 第 2 周 | 完成定位、状态机、梯形曲线、调用模式和调频 | PLSR 核心模块、单轴测试记录 | +| 第 3 周 | 完成多段、衔接模式、等待跳转、S 形、Modbus 和保存 | 多段演示、协议草案、恢复测试 | +| 第 4 周 | 完成正弦曲线、诊断、压力测试、修复和文档 | 交付固件、设计书、测试报告 | + +如果硬件映射、伺服接口或验收条件在第 1 周结束前仍未确认,应从关键条件 +冻结之日重新评估四周周期。 + +### 4.4 后续版本或加分项 + +- 完整机械回零。 +### 4.5 不在当前范围内 + +- 编码器闭环控制和位置误差修正。 +- 多轴直线或圆弧插补。 +- 电子凸轮和龙门同步。 +- 完整复制信捷 PLSR、PLSF、DRVI、DRVA、ZRN、STOP 和 GOON 语法。 +- 兼容信捷专用软元件地址和 XDPPro 界面。 + +### 4.6 实施验证事项 + +以下事项不改变V1.0需求范围,属于设计、实现和上板验收阶段需要验证的内容: + +1. Q0~Q3 定时器输出映射的上板波形确认。 +2. 输出电路的最高可靠频率、有效电平和最小脉宽。 +3. 两个 AB 轴的定时器/DMA同步方案及上板波形验证。 +4. 四轴100 kHz并发及0.1 ms控制刷新时的CPU和中断资源实测结果。 +5. Backup SRAM检查点的具体更新时机和诊断数据允许损失量。 +6. 信捷PLSR段脉冲数为0时的确切输出与终止语义。 + +## 5 参考资料 + +1. [PLSR 嵌入式方向任务要求](./任务要求.png) +2. [实现 PLSR 指令](./实现PLSR指令.pdf) +3. [信捷 XD/XL 系列 PLC 定位控制手册](./信捷XD_XL系列PLC定位控制手册_PD02_20260510_V1.3.pdf) +4. [C 语言规范](../c语言规范.pdf) +5. 当前工程 `Core`、`Modbus`、`Middlewares`、`EWARM` 和 `HostComputer` 目录 +6. [PLSR地址映射](./PLSR地址映射.md) +7. [PLSR Modbus通信协议](./PLSR_Modbus通信协议.md) +7. [PLSR信捷对标追踪矩阵](./PLSR信捷对标追踪矩阵.md) diff --git a/Document/PLSR_document/设计方案书.doc b/Document/PLSR_document/设计方案书.doc new file mode 100644 index 0000000000000000000000000000000000000000..ff4b774fcbf0f7110356b8f7a49976da27bfeb4c GIT binary patch literal 28365 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 literal 0 HcmV?d00001 diff --git a/Document/PLSR_document/需求规格书.docx b/Document/PLSR_document/需求规格书.docx new file mode 100644 index 0000000000000000000000000000000000000000..1d0ce68c0e18e22663af545611f0ecd34840aac0 GIT binary patch literal 32324 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 ZT=G)j??V2EHjfMx@@|(YcK_qm{{ul5*%AN% literal 0 HcmV?d00001