diff --git a/Core/Src/main.c b/Core/Src/main.c index 95a89a1..5fb8f1f 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -100,8 +100,6 @@ static void AppTaskStart(void *pArg) // (void)ModbusSlaveSetHoldingRegister( // 非法数据值计数 // D6, (uint16_t)ModbusSlaveStatistics.illegalValueCount); - // HistorySaveToRegisters(); - /* * 每1ms轮询一次, */ diff --git a/Document/PLSR_document/PLSR方案设计书_V1.0.md b/Document/PLSR_document/PLSR方案设计书_V1.0.md index e734991..fabf7b3 100644 --- a/Document/PLSR_document/PLSR方案设计书_V1.0.md +++ b/Document/PLSR_document/PLSR方案设计书_V1.0.md @@ -270,6 +270,10 @@ void Plsr_IsrPost(uint8_t axis, uint32_t event_mask); #### 3.1.3 流程图 +![PLSR单轴完整执行流程图](./PLSR单轴完整执行流程图.png) + +**图 3-1 PLSR单轴完整执行流程图** + ```text 系统启动 -> 输出置安全状态 @@ -476,6 +480,10 @@ void PlsrProfile_SetTarget(PlsrProfile *profile, uint32_t target_hz); 高速输出模块使用硬件定时器维持脉冲边沿,OS不参与逐脉冲翻转。 +![PLSR高速脉冲与硬件计数架构图](./PLSR高速脉冲与硬件计数架构图.svg) + +**图 3-2 PLSR高速脉冲与硬件计数架构图** + | 逻辑点 | MCU引脚 | 定时器通道 | 定时器时钟 | | --- | --- | --- | ---: | | Q0/Y0 | PF6 | TIM10_CH1 | 168 MHz | @@ -655,6 +663,10 @@ UNINITIALIZED、IDLE、ACCEL、RUN、DECEL、WAIT、PAUSED、 COMPLETED、STOPPED、ERROR ``` +![PLSR单轴状态机与命令优先级图](./PLSR单轴状态机与命令优先级图.svg) + +**图 3-3 PLSR单轴状态机与命令优先级图** + 主要合法转换如下: | 当前状态 | 事件 | 下一状态 | @@ -1128,6 +1140,13 @@ typedef struct { #### 4.2.1 数据流关系 +![PLSR数据流关系图](./PLSR数据流关系图.svg) + +**图 4-1 PLSR数据流关系图** + +图中蓝色表示配置和运动数据,橙色表示硬实时数据及中断事件,绿色表示持久化数据,紫色表示命令与 +状态接口。为方便纯文本环境阅读,保留如下简化关系。 + ```text S0/S1/S2/D逻辑软元件 | diff --git a/Document/PLSR_document/图片/PLSR单轴完整执行流程图.png b/Document/PLSR_document/图片/PLSR单轴完整执行流程图.png new file mode 100644 index 0000000..f7e9294 Binary files /dev/null and b/Document/PLSR_document/图片/PLSR单轴完整执行流程图.png differ diff --git a/Document/PLSR_document/图片/PLSR单轴状态机与命令优先级图.png b/Document/PLSR_document/图片/PLSR单轴状态机与命令优先级图.png new file mode 100644 index 0000000..f8061bb Binary files /dev/null and b/Document/PLSR_document/图片/PLSR单轴状态机与命令优先级图.png differ diff --git a/Document/PLSR_document/图片/PLSR单轴状态机与命令优先级图.svg b/Document/PLSR_document/图片/PLSR单轴状态机与命令优先级图.svg new file mode 100644 index 0000000..c0d57a7 --- /dev/null +++ b/Document/PLSR_document/图片/PLSR单轴状态机与命令优先级图.svg @@ -0,0 +1,216 @@ + + + PLSR单轴状态机与命令优先级图 + 展示单轴从初始化、空闲、运动、等待、暂停到正常完成、停止和错误的状态转换,以及软件急停到正常运行的命令事件优先级。 + + + + + + + + + + + + + + + + + + + + + + + + + PLSR 单轴状态机与命令优先级图 + 每轴独立状态 · 唯一转换入口 · 高优先级事件不可被低优先级命令覆盖 + + + + + + 单轴状态转换 + + + + + + + + + + + + + + + + UNINITIALIZED + 输出安全 · 模块未就绪 + + IDLE + BUSY=0 · PULSE_ACTIVE=0 + + ACCEL + 加速输出 + BUSY=1 · PULSE_ACTIVE=1 + + RUN + 目标频率运行/段内调频 + BUSY=1 · PULSE_ACTIVE=1 + + DECEL + 减速或反向前停车 + BUSY=1 · PULSE_ACTIVE=1 + + WAIT + 等待时间/信号/EXT + BUSY=1 · PULSE_ACTIVE=0 + + PAUSED + 保留快照、段号和剩余量 + BUSY=1 · PULSE_ACTIVE=0 + + COMPLETED + 正常结束 · DONE=1并锁存 + BUSY=0 · PULSE_ACTIVE=0 + + STOPPED + 命令/限位停止 · DONE=0 + 停止原因锁存 + + ERROR + 不可恢复运行错误 · DONE=0 + 禁止新脉冲并锁存错误 + + + + 初始化成功 + + + START成功并建立运行快照 + + + 达到运行频率 + + + 需减速或反向 + + + 下一同向段或继续运行 + + + + 段完成且条件未满足 + + + 条件满足,进入下一段 + + + + PAUSE:减速到0 + + + RESUME + + + + 等待后正常结束 + + + 最后一段正常完成 + + + + 零位移/零脉冲末段 + + + + 任意BUSY状态:STOP_DECEL减速到0 + STOP_IMMEDIATE完成当前有效脉冲后关闭 + + + + 任意状态:初始化、参数、定时器 + 或硬件计数发生不可恢复错误 + + + + RESET_ERROR成功:仅回IDLE,不自动续跑 + + + + COMPLETED / STOPPED收到合法START:清DONE,建立新快照后重新运行 + + + + + + 命令与事件优先级 + 越靠上优先级越高 + + + 1 软件急停 + 立即禁止新脉冲并锁存 + + + 2 硬限位 + 禁止越界方向,默认减速停止 + + + 3 STOP_IMMEDIATE + 完成当前有效脉冲后关闭 + + + 4 STOP_DECEL + 按当前减速曲线停止 + + + 5 PAUSE + 减速到0并保留运行快照 + + + 6 正常运行事件 + 段完成、等待、跳转、调频 + + + + + + + + + 锁存规则 + 高优先级原因一旦锁存 + 低优先级命令不得覆盖 + 重复立即停止按幂等处理 + + + + 脉冲活动状态 + + BUSY但不发脉冲 + + 正常完成 + + 异常/抢占转换 + diff --git a/Document/PLSR_document/图片/PLSR单轴状态机图.png b/Document/PLSR_document/图片/PLSR单轴状态机图.png new file mode 100644 index 0000000..78cd6a4 Binary files /dev/null and b/Document/PLSR_document/图片/PLSR单轴状态机图.png differ diff --git a/Document/PLSR_document/图片/PLSR单轴状态机图.svg b/Document/PLSR_document/图片/PLSR单轴状态机图.svg new file mode 100644 index 0000000..93cf9c5 --- /dev/null +++ b/Document/PLSR_document/图片/PLSR单轴状态机图.svg @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + PLSR 单轴状态机 + 每轴独立运行 · 唯一状态入口 · 硬件脉冲发生与状态控制解耦 + + + + + + + + + 准备状态 + 脉冲活动状态 + 保持状态 + 终止状态 + + + + + + + UNINITIALIZED + 输出安全,模块尚未就绪 + IDLE + BUSY=0 · PULSE_ACTIVE=0 + + + + + + + + ACCEL + 按加速参数提升频率 + BUSY=1 · PULSE_ACTIVE=1 + RUN + 恒频或段内动态调频 + BUSY=1 · PULSE_ACTIVE=1 + DECEL + 减速、反向或受控停止 + BUSY=1 · PULSE_ACTIVE=1 + + + + + + + WAIT + 等待时间、信号或EXT条件 + BUSY=1 · PULSE_ACTIVE=0 + PAUSED + 保留快照、段号与剩余量 + BUSY=1 · PULSE_ACTIVE=0 + + + + + + + + COMPLETED + 正常结束,DONE=1并锁存 + BUSY=0 · PULSE_ACTIVE=0 + STOPPED + 命令或限位停止,DONE=0 + 停止原因锁存 + ERROR + 不可恢复运行错误,DONE=0 + 禁止新脉冲并锁存错误 + + + + 初始化成功 + + + 合法START:校验并建立快照 + + + 达到目标频率 + + + 需要减速或反向 + + + 下一同向段或继续运行 + + + + 段完成且等待条件未满足 + + 条件满足,进入下一段 + + + + PAUSE减速到0 + + RESUME + + + + 等待后正常结束 + + 最后一段正常完成 + + + + 停止入口 + STOP_DECEL到0 / STOP_IMMEDIATE收尾 + + + + + 任意状态不可恢复错误 + 参数、定时器、计数或非法转换 + + + RESET_ERROR成功:仅回IDLE,不自动续跑 + + + + 转换原则 + 1. 每个周期只执行一次转换 + 2. 高优先级事件先于普通事件 + 3. 状态切换不直接产生脉冲 + 4. 硬件安全收尾后确认终态 + 5. 终态原因和错误均需锁存 + 6. 零任务直接进入完成态 + + 正常运行 + + 等待/暂停/停止 + + COMPLETED 或 STOPPED 收到下一次合法 START:清除旧完成标志,重新校验并建立运行快照 + diff --git a/Document/PLSR_document/图片/PLSR数据流关系图.png b/Document/PLSR_document/图片/PLSR数据流关系图.png new file mode 100644 index 0000000..b198e70 Binary files /dev/null and b/Document/PLSR_document/图片/PLSR数据流关系图.png differ diff --git a/Document/PLSR_document/图片/PLSR数据流关系图.svg b/Document/PLSR_document/图片/PLSR数据流关系图.svg new file mode 100644 index 0000000..4d8d71e --- /dev/null +++ b/Document/PLSR_document/图片/PLSR数据流关系图.svg @@ -0,0 +1,179 @@ + + + PLSR 4.2.1 数据流关系图 + 展示PLSR逻辑软元件、参数快照、路径和速度处理、轴状态机、硬件与软件计数、状态发布及持久化之间的数据关系。 + + + + + + + + + + + + + + + + + + + + + + + + + PLSR 数据流关系图 + 参数数据、运行快照、运动计算、实时计数、状态发布与持久化 + + + + + + 输入数据层 + + + S0 / S1 动态数据 + 路径段 · 定位模式 · 起始段 + + + S2 与固定配置 + HSD460~539 · SFD900~1419 + + + D 与输出配置 + 模式 · 高速点 · DIR点 · 极性 + + + 命令与运行变量 + START/STOP · Wait/EXT · 动态频率 + + + + + + + + + + PlsrParser_BuildSnapshot + 边界与组合校验 · 原子申请资源 · 生成不可变执行副本 + + + + + + PlsrJobSnapshot + S0段快照 · S1模式 · S2参数 · D绑定 · 计数器租约 + + + 运动处理层 + + + + + + + PlsrPath 路径解释 + 段进入 · Wait/ACT/EXT · 动态跳转 + 输出:段目标、方向、结束与事件 + + + PlsrProfile 速度规划 + 直线/S形/正弦 · 短距离 · 动态调频 + 输出:命令频率与PSC/ARR/CCR + + + PlsrResource 资源管理 + Q0~Q3 · DIR · TIM9/TIM12 + 输出:输出租约与计数模式 + + + + + + + + + + PlsrAxis 四轴运行对象 + 状态机 · 当前段 · 运行快照 · 计数模式 · 停止原因 + 64位逻辑位置 · 任务累计 · 总累计 · 事件序号 + + + + + TIM6 控制刷新 + 0.1 ms / 1 ms + + + + PWM输出定时器 + TIM10/13/11/14 + + + + 脉冲累计与ISR事件 + TIM9/TIM12硬件计数优先 + 输出定时器软件计数兜底 + + + 块累计 / 最终比较 / 故障事件 + + + + + + Flash / Backup SRAM + 固定配置 · K0 · 位置与累计检查点 + 复位后不自动恢复运动 + + + + PlsrStatusPublish + 版本化一致快照 + 状态 · 频率 · 位置 · 计数 · 错误 + + + + 固定运行状态 + HSD0~15 · SM · SD + I6000~6399段事件 + + + + 外部读取 + Modbus RTU · 内部API + 读取一致状态,不直接写运行对象 + + + + 运行命令与条件变量 + + + + 配置与运动数据 + + 硬实时数据与事件 + + 持久化数据 + + 状态/命令接口 + diff --git a/Document/PLSR_document/PLSR系统结构图.png b/Document/PLSR_document/图片/PLSR系统结构图.png similarity index 100% rename from Document/PLSR_document/PLSR系统结构图.png rename to Document/PLSR_document/图片/PLSR系统结构图.png diff --git a/Document/PLSR_document/PLSR系统结构图.svg b/Document/PLSR_document/图片/PLSR系统结构图.svg similarity index 100% rename from Document/PLSR_document/PLSR系统结构图.svg rename to Document/PLSR_document/图片/PLSR系统结构图.svg diff --git a/Document/PLSR_document/图片/PLSR高速脉冲与硬件计数架构图.png b/Document/PLSR_document/图片/PLSR高速脉冲与硬件计数架构图.png new file mode 100644 index 0000000..eebed17 Binary files /dev/null and b/Document/PLSR_document/图片/PLSR高速脉冲与硬件计数架构图.png differ diff --git a/Document/PLSR_document/图片/PLSR高速脉冲与硬件计数架构图.svg b/Document/PLSR_document/图片/PLSR高速脉冲与硬件计数架构图.svg new file mode 100644 index 0000000..538d4a0 --- /dev/null +++ b/Document/PLSR_document/图片/PLSR高速脉冲与硬件计数架构图.svg @@ -0,0 +1,166 @@ + + + PLSR高速脉冲与硬件计数架构图 + 展示TIM6控制刷新、四路PWM输出、TIM9和TIM12硬件计数二选一连接、软件计数兜底以及最终完整边沿关闭流程。 + + + + + + + + + + + + + + + + + + + + + + + + + PLSR 高速脉冲与硬件计数架构图 + 硬件PWM维持边沿 · TIM9/TIM12硬件计数优先 · 软件周期计数兜底 + + + + + + 控制与配置 + + + PlsrProfile 速度规划 + 命令频率 · PSC/ARR/CCR + + + TIM6 控制刷新 + 0.1 ms / 1 ms · 安全预装载 + + + PlsrResource 资源管理 + 输出租约 · 计数器租约 · 计数模式 + + + + + + 硬件PWM输出层 + + + + + + + + + + + + + + Q0 · PF6 + TIM10_CH1 · 168 MHz + PWM / A相 / CW或CCW + + Q1 · PF8 + TIM13_CH1 · 84 MHz + PWM / B相 / CW或CCW + + Q2 · PF7 + TIM11_CH1 · 168 MHz + PWM / A相 / CW或CCW + + Q3 · PF9 + TIM14_CH1 · 84 MHz + PWM / B相 / CW或CCW + + + + + + + + 物理高速输出 Q0~Q3 + PULSE/DIR:上升沿计数 · AB相:完整四状态周期计数 · CW/CCW:当前方向通道计数 + + + 内部硬件计数与软件兜底 + + + + + + + TIM10_OC · ITR2 + TIM11_OC · ITR3 + TIM13_OC · ITR2 + TIM14_OC · ITR3 + + + + + + TIM9 · 16位硬件累计 + Q0/TIM10 或 Q2/TIM11 二选一 + External Clock Mode 1 · 65536脉冲块 + 100 kHz时块中断约1.53次/秒 + + TIM12 · 16位硬件累计 + Q1/TIM13 或 Q3/TIM14 二选一 + External Clock Mode 1 · 65536脉冲块 + 100 kHz时块中断约1.53次/秒 + + + 软件周期计数兜底 + 计数器不可达或被占用时,启用对应PWM定时器更新中断 + + + + 未获得租约的轴自动回退,不拒绝合法任务 + + + + + + + + + 目标数量到达与最终完整边沿 + PULSE/CW/CCW:末脉冲下降沿 · AB:第四次状态跳变 + + + + 安全关闭并发布完成事件 + 关闭通道 · 释放租约 · 更新位置和段状态 + + + + 控制配置 + + 物理脉冲 + + 计数连接/回退 + + 完成与状态事件 + diff --git a/Document/PLSR_document/任务要求.png b/Document/PLSR_document/图片/任务要求.png similarity index 100% rename from Document/PLSR_document/任务要求.png rename to Document/PLSR_document/图片/任务要求.png diff --git a/Document/PLSR_document/框图/PLSR运动控制流程图 - 副本.vsdx b/Document/PLSR_document/框图/PLSR运动控制流程图 - 副本.vsdx new file mode 100644 index 0000000..1ca44d2 Binary files /dev/null and b/Document/PLSR_document/框图/PLSR运动控制流程图 - 副本.vsdx differ diff --git a/Document/PLSR_document/框图/PLSR运动控制流程图 - 副本_修改前备份.vsdx b/Document/PLSR_document/框图/PLSR运动控制流程图 - 副本_修改前备份.vsdx new file mode 100644 index 0000000..1ca44d2 Binary files /dev/null and b/Document/PLSR_document/框图/PLSR运动控制流程图 - 副本_修改前备份.vsdx differ diff --git a/Document/PLSR_document/框图/PLSR运动控制流程图.vsdx b/Document/PLSR_document/框图/PLSR运动控制流程图.vsdx new file mode 100644 index 0000000..1ca44d2 Binary files /dev/null and b/Document/PLSR_document/框图/PLSR运动控制流程图.vsdx differ diff --git a/Document/PLSR_document/框图/PLSR运动控制流程图_完整版.vsdx b/Document/PLSR_document/框图/PLSR运动控制流程图_完整版.vsdx new file mode 100644 index 0000000..6fadae7 Binary files /dev/null and b/Document/PLSR_document/框图/PLSR运动控制流程图_完整版.vsdx differ diff --git a/Document/PLSR_document/框图/PLSR运动控制流程图_完整预览.png b/Document/PLSR_document/框图/PLSR运动控制流程图_完整预览.png new file mode 100644 index 0000000..dce1d6e Binary files /dev/null and b/Document/PLSR_document/框图/PLSR运动控制流程图_完整预览.png differ diff --git a/Document/PLSR_document/框图/PLSR运动控制流程图_当前预览.png b/Document/PLSR_document/框图/PLSR运动控制流程图_当前预览.png new file mode 100644 index 0000000..75ee3e5 Binary files /dev/null and b/Document/PLSR_document/框图/PLSR运动控制流程图_当前预览.png differ diff --git a/Document/PLSR_document/框图/PLSR高速脉冲与硬件计数架构图.vsdx b/Document/PLSR_document/框图/PLSR高速脉冲与硬件计数架构图.vsdx new file mode 100644 index 0000000..832134b Binary files /dev/null and b/Document/PLSR_document/框图/PLSR高速脉冲与硬件计数架构图.vsdx differ diff --git a/Document/PLSR_document/框图/~$$PLSR运动控制流程图 - 副本.~vsdx b/Document/PLSR_document/框图/~$$PLSR运动控制流程图 - 副本.~vsdx new file mode 100644 index 0000000..50439e7 Binary files /dev/null and b/Document/PLSR_document/框图/~$$PLSR运动控制流程图 - 副本.~vsdx differ diff --git a/Document/PLSR_document/框图/状态机图解.vsdx b/Document/PLSR_document/框图/状态机图解.vsdx new file mode 100644 index 0000000..b56ab28 Binary files /dev/null and b/Document/PLSR_document/框图/状态机图解.vsdx differ diff --git a/Document/PLSR_document/虞文昊_PLSR_2026.8.6.zip b/Document/PLSR_document/虞文昊_PLSR_2026.8.6.zip new file mode 100644 index 0000000..d034b00 Binary files /dev/null and b/Document/PLSR_document/虞文昊_PLSR_2026.8.6.zip differ diff --git a/Document/PLSR_document/虞文昊_PLSR_2026.8.6/设计方案书.docx b/Document/PLSR_document/虞文昊_PLSR_2026.8.6/设计方案书.docx new file mode 100644 index 0000000..fe7f91f Binary files /dev/null and b/Document/PLSR_document/虞文昊_PLSR_2026.8.6/设计方案书.docx differ diff --git a/Document/PLSR_document/虞文昊_PLSR_2026.8.6/需求规格书.docx b/Document/PLSR_document/虞文昊_PLSR_2026.8.6/需求规格书.docx new file mode 100644 index 0000000..0a5433e Binary files /dev/null and b/Document/PLSR_document/虞文昊_PLSR_2026.8.6/需求规格书.docx differ diff --git a/Document/PLSR_document/设计方案书.docx b/Document/PLSR_document/设计方案书.docx index 3bc0f34..fe7f91f 100644 Binary files a/Document/PLSR_document/设计方案书.docx and b/Document/PLSR_document/设计方案书.docx differ diff --git a/Document/PLSR_document/设计方案书2.docx b/Document/PLSR_document/设计方案书2.docx deleted file mode 100644 index a206f15..0000000 Binary files a/Document/PLSR_document/设计方案书2.docx and /dev/null differ diff --git a/Document/PLSR_document/需求规格书.docx b/Document/PLSR_document/需求规格书.docx index 216b6d0..0a5433e 100644 Binary files a/Document/PLSR_document/需求规格书.docx and b/Document/PLSR_document/需求规格书.docx differ diff --git a/Modbus/Inc/modbus_rtu_slave.h b/Modbus/Inc/modbus_rtu_slave.h index c24a3a2..3e139df 100644 --- a/Modbus/Inc/modbus_rtu_slave.h +++ b/Modbus/Inc/modbus_rtu_slave.h @@ -66,17 +66,6 @@ typedef struct uint32_t droppedFrameCount; ///< 接收槽占用或长度错误导致的丢帧数 uint32_t uartErrorCount; ///< HAL 串口错误计数 } MODBUS_SLAVE_STATS; -/** - * @brief 一次Modbus RTU通信的历史记录 - */ -typedef struct -{ - uint32_t tick; ///< 通信发生时的系统时间 - uint16_t requestLength; ///< 请求ADU长度 - uint16_t responseLength; ///< 响应ADU长度 - uint8_t request[256]; ///< 请求ADU数据 - uint8_t response[256]; ///< 响应ADU数据 -} MODBUS_HISTORY_ITEM; /** @brief Modbus 从站通信统计数据 */ extern volatile MODBUS_SLAVE_STATS ModbusSlaveStatistics; /** @@ -153,7 +142,6 @@ uint8_t ModbusSlaveGetCoil(uint16_t address, uint8_t *state); uint8_t ModbusSlaveIsConnected(uint32_t timeoutMs); void ModbusRetainedRegistersLoad(void); void ModbusRetainedRegistersPoll(void); -void HistorySaveToRegisters(void); #ifdef __cplusplus } diff --git a/Modbus/Src/modbus_rtu_slave.c b/Modbus/Src/modbus_rtu_slave.c index 0b031b8..bf00866 100644 --- a/Modbus/Src/modbus_rtu_slave.c +++ b/Modbus/Src/modbus_rtu_slave.c @@ -1,5 +1,4 @@ #include "modbus_rtu_slave.h" -#include "ucos_ii.h" #include #define MODBUS_RTU_ADU_SIZE_MAX (256U) // Modbus RTU 最大 ADU 长度,单位为字节 @@ -25,12 +24,7 @@ static UART_HandleTypeDef *ModbusUart; static uint8_t ModbusSlaveAddress; -static void ModbusHistorySave(uint32_t tick, const uint8_t *request, - uint16_t requestLength, const uint8_t *response, - uint16_t responseLength); static HAL_StatusTypeDef ModbusStartReceive(void); -static MODBUS_HISTORY_ITEM ModbusHistory[16]; -static uint16_t ModbusHistoryWriteIndex; /*最近一次字节尾到字节头的间隔周期数*/ static volatile uint32_t ModbusLastInterFrameGapCycles; /** @@ -457,73 +451,6 @@ tx: return (uint16_t)(5U + quantity * 2U); } -/* - * 返回帧 - *从站地址 | 14 | 总字节数 | 子响应长度 | 06 | 寄存器数据 | CRC - * - * 01 从站地址 - * 14 功能码 - * 06 后续响应数据共6字节 - * 05 当前子响应长度,共5字节 - * 06 引用类型 - * 12 34 第一个寄存器 - * 56 78 第二个寄存器 - */ -static uint16_t ModbusProcessFile(const uint8_t *request, - uint16_t requestLength) -{ - uint16_t fileNumber; - uint16_t recordNumber; - uint16_t quantity; - uint16_t index; - uint16_t value; - uint16_t *historyRegister; - if (requestLength != 12U) - { - ModbusSlaveStatistics.illegalValueCount++; - return ModbusBuildException(request[1], MODBUS_EX_ILLEGAL_VALUE); - } - if ((request[2] != 7U) || (request[3] != 0x06U)) - { - ModbusSlaveStatistics.illegalValueCount++; - return ModbusBuildException(request[1], MODBUS_EX_ILLEGAL_VALUE); - } - - quantity = ModbusGetU16Be(&request[8]); - fileNumber = ModbusGetU16Be(&request[4]); - recordNumber = ModbusGetU16Be(&request[6]); - if ((quantity == 0U) || (quantity > 124U)) // 数量0或者数量大于最大值 - { - ModbusSlaveStatistics.illegalValueCount++; - return ModbusBuildException(request[1], MODBUS_EX_ILLEGAL_VALUE); - } - /* 检查文件号、记录号和读取范围 */ - if ((fileNumber > 15U) || (recordNumber >= 260U) - || (((uint32_t)recordNumber + quantity) > 260UL)) - { - ModbusSlaveStatistics.illegalAddressCount++; - return ModbusBuildException(request[1], MODBUS_EX_ILLEGAL_ADDRESS); - } - ModbusTxFrame[0] = ModbusSlaveAddress; - ModbusTxFrame[1] = 0X14; - ModbusTxFrame[2] = (uint8_t)(2U + quantity * 2U); - ModbusTxFrame[3] = (uint8_t)(1U + quantity * 2U); - - ModbusTxFrame[4] = 0X06; - historyRegister = (uint16_t *)ModbusHistory; - for (index = 0U; index < quantity; index++) - { - uint16_t address = fileNumber * 260 + recordNumber + index; - - value = *(historyRegister + address); - ModbusTxFrame[5U + index * 2U] = (uint8_t)(value & 0x00FFU); - ModbusTxFrame[6U + index * 2U] = (uint8_t)(value >> 8U); - } - - ModbusAppendCrc(ModbusTxFrame, (uint16_t)(5U + quantity * 2U)); - return (uint16_t)(7U + quantity * 2U); -} - /** * @brief 处理写单个保持寄存器功能码 0x06 * @param[in] request RTU 请求帧 @@ -893,11 +820,6 @@ static uint16_t ModbusProcessRequest(const uint8_t *request, return (isBroadcast != 0U) ? 0U : ModbusProcessReadHolding(request, requestLength); - case 0x14U: - return (isBroadcast != 0U) - ? 0U - : ModbusProcessFile(request, requestLength); - case 0x05U: // 写单个线圈 return ModbusProcessWriteSingleCoil(request, requestLength, isBroadcast); @@ -959,9 +881,6 @@ void ModbusSlavePoll(void) } responseLength = ModbusProcessRequest(ModbusRxFrame, ModbusRxFrameLength); - ModbusHistorySave(OSTimeGet() / 1000, ModbusRxFrame, ModbusRxFrameLength, - ModbusTxFrame, responseLength); - if (responseLength > 0U) { ModbusTxBusy = 1U; @@ -1192,57 +1111,3 @@ void ModbusRetainedRegistersPoll(void) ModbusRetainedSnapshot[index] = value; } } -static void ModbusHistorySave(uint32_t tick, const uint8_t *request, - uint16_t requestLength, const uint8_t *response, - uint16_t responseLength) -{ - MODBUS_HISTORY_ITEM *item; - - if (requestLength > 256U) - { - requestLength = 256U; - } - - if (responseLength > 256U) - { - responseLength = 256U; - } - - item = &ModbusHistory[ModbusHistoryWriteIndex]; - - item->tick = tick; - item->requestLength = requestLength; - item->responseLength = responseLength; - - (void)memcpy(item->request, request, requestLength); - - if (responseLength > 0U) - { - (void)memcpy(item->response, response, responseLength); - } - - ModbusHistoryWriteIndex++; - - if (ModbusHistoryWriteIndex >= 16U) - { - ModbusHistoryWriteIndex = 0U; - } -} -void HistorySaveToRegisters(void) -{ - - - uint16_t index; - - if (ModbusHistoryWriteIndex == 0U) - { - index = 15U; - } - else - { - index = ModbusHistoryWriteIndex - 1U; - } - - (void)memcpy(&ModbusHoldingRegisters[1000U + index * 260U], - &ModbusHistory[index], sizeof(ModbusHistory[index])); -}