| @@ -37,7 +37,7 @@ | |||||
| /*============================================================================*/ | /*============================================================================*/ | ||||
| /* 线圈/保持寄存器最大协议地址 */ | /* 线圈/保持寄存器最大协议地址 */ | ||||
| #define MODBUS_MB_MAXIMUM 0x270FU | |||||
| #define MODBUS_MB_MAXIMUM 0x3000U | |||||
| /* 实际能存储的最大数据个数 */ | /* 实际能存储的最大数据个数 */ | ||||
| #define MODBUS_POINT_COUNT (MODBUS_MB_MAXIMUM + 1U) | #define MODBUS_POINT_COUNT (MODBUS_MB_MAXIMUM + 1U) | ||||
| @@ -1,6 +1,6 @@ | |||||
| /** | /** | ||||
| * @file plsr_command.c | * @file plsr_command.c | ||||
| * @brief 指令接口:Modbus 命令/线圈 → 参数块 + 运行控制;状态与故障回写 | |||||
| * @brief 指令接口:0x3000 控制位 → 运行控制;监控写回 0x2000~0x2006 | |||||
| */ | */ | ||||
| #include "plsr_command.h" | #include "plsr_command.h" | ||||
| #include "plsr_param.h" | #include "plsr_param.h" | ||||
| @@ -16,16 +16,25 @@ static void PlsrCommandWriteDWord(uint16_t addr, uint32_t value) | |||||
| WriteHoldReg((uint16_t)(addr + 1U), (uint16_t)((value >> 16) & 0xFFFFU)); | WriteHoldReg((uint16_t)(addr + 1U), (uint16_t)((value >> 16) & 0xFFFFU)); | ||||
| } | } | ||||
| static void PlsrCommandPublishMonitor(void) | |||||
| { | |||||
| PlsrCommandWriteDWord(PLSR_MON_ACC_PULSE_L, (uint32_t)PlsrGetAccPulse()); | |||||
| PlsrCommandWriteDWord(PLSR_MON_FREQ_L, PlsrRunControlGetCurFreq()); | |||||
| WriteHoldReg(PLSR_MON_RUN_STATUS, PlsrIsBusy() ? 1U : 0U); | |||||
| WriteHoldReg(PLSR_MON_CUR_SEG, PlsrRunControlGetCurSeg()); | |||||
| WriteHoldReg(PLSR_MON_ERR, s_fault); | |||||
| } | |||||
| void PlsrCommandSetFault(uint16_t code) | void PlsrCommandSetFault(uint16_t code) | ||||
| { | { | ||||
| s_fault = code; | s_fault = code; | ||||
| WriteHoldReg(PLSR_CMD_REG_ERR, code); | |||||
| WriteHoldReg(PLSR_MON_ERR, code); | |||||
| } | } | ||||
| void PlsrCommandClearFault(void) | void PlsrCommandClearFault(void) | ||||
| { | { | ||||
| s_fault = PLSR_ERR_NONE; | s_fault = PLSR_ERR_NONE; | ||||
| WriteHoldReg(PLSR_CMD_REG_ERR, PLSR_ERR_NONE); | |||||
| WriteHoldReg(PLSR_MON_ERR, PLSR_ERR_NONE); | |||||
| } | } | ||||
| uint16_t PlsrCommandGetFault(void) | uint16_t PlsrCommandGetFault(void) | ||||
| @@ -35,45 +44,41 @@ uint16_t PlsrCommandGetFault(void) | |||||
| void PlsrCommandInit(void) | void PlsrCommandInit(void) | ||||
| { | { | ||||
| WriteHoldReg(PLSR_CMD_REG_COMMAND, PLSR_CMD_IDLE); | |||||
| WriteHoldReg(PLSR_CTRL_REG, 0U); | |||||
| PlsrCommandClearFault(); | PlsrCommandClearFault(); | ||||
| PlsrCommandPublishMonitor(); | |||||
| } | } | ||||
| void PlsrCommandPoll(void) | void PlsrCommandPoll(void) | ||||
| { | { | ||||
| uint16_t cmd = ReadHoldReg(PLSR_CMD_REG_COMMAND); | |||||
| uint16_t ctrl = ReadHoldReg(PLSR_CTRL_REG); | |||||
| if (ReadCoil(PLSR_CMD_COIL_CLR_ACC) != 0U) | |||||
| { | |||||
| WriteCoil(PLSR_CMD_COIL_CLR_ACC, 0U); | |||||
| PlsrClearAccPulse(); | |||||
| } | |||||
| if (ReadCoil(PLSR_CMD_COIL_STOP) != 0U) | |||||
| if (ctrl != 0U) | |||||
| { | { | ||||
| WriteCoil(PLSR_CMD_COIL_STOP, 0U); | |||||
| PlsrStop(); | |||||
| } | |||||
| /* 上位机置位,从站处理后立刻清零 */ | |||||
| WriteHoldReg(PLSR_CTRL_REG, 0U); | |||||
| if (cmd == PLSR_CMD_STOP) | |||||
| { | |||||
| WriteHoldReg(PLSR_CMD_REG_COMMAND, PLSR_CMD_IDLE); | |||||
| PlsrStop(); | |||||
| } | |||||
| else if ((cmd == PLSR_CMD_START) || (cmd == PLSR_CMD_IMPORT)) | |||||
| { | |||||
| WriteHoldReg(PLSR_CMD_REG_COMMAND, PLSR_CMD_IDLE); | |||||
| (void)PlsrParamBlockApplyFromHold(); | |||||
| if (cmd == PLSR_CMD_START) | |||||
| if ((ctrl & PLSR_CTRL_BIT_STOP) != 0U) | |||||
| { | |||||
| PlsrStop(); | |||||
| } | |||||
| if ((ctrl & PLSR_CTRL_BIT_CLR) != 0U) | |||||
| { | |||||
| PlsrClearAccPulse(); | |||||
| PlsrCommandClearFault(); | |||||
| } | |||||
| /* 同时有停止位时不启动 */ | |||||
| if (((ctrl & PLSR_CTRL_BIT_START) != 0U) && | |||||
| ((ctrl & PLSR_CTRL_BIT_STOP) == 0U)) | |||||
| { | { | ||||
| (void)PlsrParamBlockApplyFromHold(); | |||||
| PlsrCommandClearFault(); | PlsrCommandClearFault(); | ||||
| PlsrStop(); | PlsrStop(); | ||||
| (void)PlsrStart(PlsrParamGetStartSeg()); | (void)PlsrStart(PlsrParamGetStartSeg()); | ||||
| } | } | ||||
| } | } | ||||
| WriteHoldReg(PLSR_CMD_REG_BUSY, PlsrIsBusy()); | |||||
| WriteHoldReg(PLSR_CMD_REG_CUR_SEG, PlsrRunControlGetCurSeg()); | |||||
| PlsrCommandWriteDWord(PLSR_CMD_REG_CUR_FREQ_L, PlsrRunControlGetCurFreq()); | |||||
| PlsrCommandWriteDWord(PLSR_CMD_REG_ACC_PULSE_L, (uint32_t)PlsrGetAccPulse()); | |||||
| WriteHoldReg(PLSR_CMD_REG_ERR, s_fault); | |||||
| PlsrCommandPublishMonitor(); | |||||
| } | } | ||||
| @@ -2,36 +2,29 @@ | |||||
| * @file plsr_command.h | * @file plsr_command.h | ||||
| * @brief 指令接口模块 | * @brief 指令接口模块 | ||||
| * | * | ||||
| * 职责(与方案书 3.1 对齐;未实现项后续补充): | |||||
| * 1. 接收启动 / STOP 急停等外部触发(当前经 Modbus 命令寄存器与线圈) | |||||
| * 2. (待实现)重复启动防护、GOON 恢复、fault_buf | |||||
| * 3. 指令分发:启动时先走参数块管理再启运行;停机直接停运动 | |||||
| * 4. 状态上报:忙闲、当前段、频率、累计脉冲写回保持寄存器 | |||||
| * 监控区 0x2000~0x2006:下位机刷新,上位机 0x03 读。 | |||||
| * 控制寄存器 0x3000:上位机置位,下位机处理后清零。 | |||||
| */ | */ | ||||
| #ifndef PLSR_COMMAND_H | #ifndef PLSR_COMMAND_H | ||||
| #define PLSR_COMMAND_H | #define PLSR_COMMAND_H | ||||
| #include <stdint.h> | #include <stdint.h> | ||||
| /* 指令与状态保持寄存器(地址与原协议兼容) */ | |||||
| #define PLSR_CMD_REG_COMMAND 0x10F0U /* 写命令 */ | |||||
| #define PLSR_CMD_REG_BUSY 0x10F1U /* 运动忙 */ | |||||
| #define PLSR_CMD_REG_CUR_SEG 0x10F2U /* 当前段号 1-based */ | |||||
| #define PLSR_CMD_REG_CUR_FREQ_L 0x10F3U | |||||
| #define PLSR_CMD_REG_CUR_FREQ_H 0x10F4U | |||||
| #define PLSR_CMD_REG_ACC_PULSE_L 0x10F5U | |||||
| #define PLSR_CMD_REG_ACC_PULSE_H 0x10F6U | |||||
| #define PLSR_CMD_REG_ERR 0x10F7U /* 故障码 */ | |||||
| /* ---------- 监控保持寄存器(双字低地址存低字) ---------- */ | |||||
| #define PLSR_MON_ACC_PULSE_L 0x2000U /* 脉冲累计,有符号补码 */ | |||||
| #define PLSR_MON_ACC_PULSE_H 0x2001U | |||||
| #define PLSR_MON_FREQ_L 0x2002U /* 当前发送频率 Hz */ | |||||
| #define PLSR_MON_FREQ_H 0x2003U | |||||
| #define PLSR_MON_RUN_STATUS 0x2004U /* 0空闲 1运行 */ | |||||
| #define PLSR_MON_CUR_SEG 0x2005U /* 当前执行段 1-based */ | |||||
| #define PLSR_MON_ERR 0x2006U /* 错误码 */ | |||||
| #define PLSR_CMD_IDLE 0U | |||||
| #define PLSR_CMD_START 1U | |||||
| #define PLSR_CMD_STOP 2U | |||||
| #define PLSR_CMD_IMPORT 3U | |||||
| /* ---------- 控制寄存器(读/写,处理后由从站清 0) ---------- */ | |||||
| #define PLSR_CTRL_REG 0x3000U | |||||
| #define PLSR_CTRL_BIT_START (1U << 0) /* 启动脉冲 */ | |||||
| #define PLSR_CTRL_BIT_STOP (1U << 1) /* 停止脉冲 */ | |||||
| #define PLSR_CTRL_BIT_CLR (1U << 2) /* 清除状态信息 */ | |||||
| #define PLSR_CMD_COIL_STOP 0x2001U | |||||
| #define PLSR_CMD_COIL_CLR_ACC 0x2003U | |||||
| /* 故障码(写入 0x10F7,供 Modbus 读取) */ | |||||
| #define PLSR_ERR_NONE 0U | #define PLSR_ERR_NONE 0U | ||||
| #define PLSR_ERR_SEG_FREQ 1U /* 段频率非法(非 0 且越界,或解析后不在 1~100k) */ | #define PLSR_ERR_SEG_FREQ 1U /* 段频率非法(非 0 且越界,或解析后不在 1~100k) */ | ||||
| @@ -47,7 +47,7 @@ | |||||
| #define PLSR_SEG_OFF_WAIT 4U /* 等待类型 */ | #define PLSR_SEG_OFF_WAIT 4U /* 等待类型 */ | ||||
| #define PLSR_SEG_OFF_WAIT_MS 5U | #define PLSR_SEG_OFF_WAIT_MS 5U | ||||
| #define PLSR_SEG_OFF_ACT_MS 6U | #define PLSR_SEG_OFF_ACT_MS 6U | ||||
| #define PLSR_SEG_OFF_JUMP 7U /* 0=结束;1~N=跳转目标段号 */ | |||||
| #define PLSR_SEG_OFF_JUMP 7U /* 0=末段停 / 非末段接下一段;1~N=跳转目标段号 */ | |||||
| /* 分帧传输状态(上位机可轮询) */ | /* 分帧传输状态(上位机可轮询) */ | ||||
| #define PLSR_PARAM_XFER_RECV_REG 0x0FFCU | #define PLSR_PARAM_XFER_RECV_REG 0x0FFCU | ||||
| @@ -115,7 +115,7 @@ typedef struct { | |||||
| PlsrWaitType_e wait_type; | PlsrWaitType_e wait_type; | ||||
| uint16_t wait_ms; | uint16_t wait_ms; | ||||
| uint16_t act_ms; | uint16_t act_ms; | ||||
| uint16_t jump_seg; /* 0=结束;1~N=跳转目标段号 */ | |||||
| uint16_t jump_seg; /* 0=末段结束 / 非末段则顺序下一段;1~N=跳转目标段号 */ | |||||
| } PlsrSeg_t; | } PlsrSeg_t; | ||||
| /* ---------- 运行映像访问 ---------- */ | /* ---------- 运行映像访问 ---------- */ | ||||
| @@ -13,13 +13,17 @@ int16_t PlsrPathPlanNextSeg(uint16_t cur_seg_0based) | |||||
| /* | /* | ||||
| * 跳转目标(1-based): | * 跳转目标(1-based): | ||||
| * 0 → 结束(含末段写 0) | |||||
| * 0 → 末段:结束;非末段:顺序下一段(cur+1) | |||||
| * 1..N → 跳到对应段(可顺序、回跳循环、任意段) | * 1..N → 跳到对应段(可顺序、回跳循环、任意段) | ||||
| * 其它 → 结束 | * 其它 → 结束 | ||||
| */ | */ | ||||
| if (jump == 0U) | if (jump == 0U) | ||||
| { | { | ||||
| (void)cur_seg_0based; | |||||
| /* 非末段写 0:视为顺序下一档,不是停机 */ | |||||
| if ((n >= 1U) && (cur_seg_0based + 1U < n)) | |||||
| { | |||||
| return (int16_t)(cur_seg_0based + 1U); | |||||
| } | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| if ((jump >= 1U) && (jump <= n)) | if ((jump >= 1U) && (jump <= n)) | ||||
| @@ -14,7 +14,8 @@ | |||||
| * @brief 解析下一段索引 | * @brief 解析下一段索引 | ||||
| * @param cur_seg_0based 当前段 0-based | * @param cur_seg_0based 当前段 0-based | ||||
| * @return 下一段 0-based;无下一段或非法跳转返回 -1 | * @return 下一段 0-based;无下一段或非法跳转返回 -1 | ||||
| * @note jump=0 结束;jump=1~N 跳到对应段(可循环) | |||||
| * @note jump=0:末段→结束;非末段→顺序下一段 | |||||
| * jump=1~N:跳到对应段(可循环) | |||||
| */ | */ | ||||
| int16_t PlsrPathPlanNextSeg(uint16_t cur_seg_0based); | int16_t PlsrPathPlanNextSeg(uint16_t cur_seg_0based); | ||||