diff --git a/modbus/modbus_rtu.h b/modbus/modbus_rtu.h index 16918d5..439af35 100644 --- a/modbus/modbus_rtu.h +++ b/modbus/modbus_rtu.h @@ -37,7 +37,7 @@ /*============================================================================*/ /* 线圈/保持寄存器最大协议地址 */ -#define MODBUS_MB_MAXIMUM 0x270FU +#define MODBUS_MB_MAXIMUM 0x3000U /* 实际能存储的最大数据个数 */ #define MODBUS_POINT_COUNT (MODBUS_MB_MAXIMUM + 1U) diff --git a/plsr/command/plsr_command.c b/plsr/command/plsr_command.c index 2e541af..8ab2ac2 100644 --- a/plsr/command/plsr_command.c +++ b/plsr/command/plsr_command.c @@ -1,6 +1,6 @@ /** * @file plsr_command.c - * @brief 指令接口:Modbus 命令/线圈 → 参数块 + 运行控制;状态与故障回写 + * @brief 指令接口:0x3000 控制位 → 运行控制;监控写回 0x2000~0x2006 */ #include "plsr_command.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)); } +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) { s_fault = code; - WriteHoldReg(PLSR_CMD_REG_ERR, code); + WriteHoldReg(PLSR_MON_ERR, code); } void PlsrCommandClearFault(void) { s_fault = PLSR_ERR_NONE; - WriteHoldReg(PLSR_CMD_REG_ERR, PLSR_ERR_NONE); + WriteHoldReg(PLSR_MON_ERR, PLSR_ERR_NONE); } uint16_t PlsrCommandGetFault(void) @@ -35,45 +44,41 @@ uint16_t PlsrCommandGetFault(void) void PlsrCommandInit(void) { - WriteHoldReg(PLSR_CMD_REG_COMMAND, PLSR_CMD_IDLE); + WriteHoldReg(PLSR_CTRL_REG, 0U); PlsrCommandClearFault(); + PlsrCommandPublishMonitor(); } 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(); PlsrStop(); (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(); } diff --git a/plsr/command/plsr_command.h b/plsr/command/plsr_command.h index bfa5659..e6a8b99 100644 --- a/plsr/command/plsr_command.h +++ b/plsr/command/plsr_command.h @@ -2,36 +2,29 @@ * @file plsr_command.h * @brief 指令接口模块 * - * 职责(与方案书 3.1 对齐;未实现项后续补充): - * 1. 接收启动 / STOP 急停等外部触发(当前经 Modbus 命令寄存器与线圈) - * 2. (待实现)重复启动防护、GOON 恢复、fault_buf - * 3. 指令分发:启动时先走参数块管理再启运行;停机直接停运动 - * 4. 状态上报:忙闲、当前段、频率、累计脉冲写回保持寄存器 + * 监控区 0x2000~0x2006:下位机刷新,上位机 0x03 读。 + * 控制寄存器 0x3000:上位机置位,下位机处理后清零。 */ #ifndef PLSR_COMMAND_H #define PLSR_COMMAND_H #include -/* 指令与状态保持寄存器(地址与原协议兼容) */ -#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_SEG_FREQ 1U /* 段频率非法(非 0 且越界,或解析后不在 1~100k) */ diff --git a/plsr/param/plsr_param.h b/plsr/param/plsr_param.h index 512bde3..ca581ae 100644 --- a/plsr/param/plsr_param.h +++ b/plsr/param/plsr_param.h @@ -47,7 +47,7 @@ #define PLSR_SEG_OFF_WAIT 4U /* 等待类型 */ #define PLSR_SEG_OFF_WAIT_MS 5U #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 @@ -115,7 +115,7 @@ typedef struct { PlsrWaitType_e wait_type; uint16_t wait_ms; uint16_t act_ms; - uint16_t jump_seg; /* 0=结束;1~N=跳转目标段号 */ + uint16_t jump_seg; /* 0=末段结束 / 非末段则顺序下一段;1~N=跳转目标段号 */ } PlsrSeg_t; /* ---------- 运行映像访问 ---------- */ diff --git a/plsr/path_plan/plsr_path_plan.c b/plsr/path_plan/plsr_path_plan.c index 2d5c08c..d6caeec 100644 --- a/plsr/path_plan/plsr_path_plan.c +++ b/plsr/path_plan/plsr_path_plan.c @@ -13,13 +13,17 @@ int16_t PlsrPathPlanNextSeg(uint16_t cur_seg_0based) /* * 跳转目标(1-based): - * 0 → 结束(含末段写 0) + * 0 → 末段:结束;非末段:顺序下一段(cur+1) * 1..N → 跳到对应段(可顺序、回跳循环、任意段) * 其它 → 结束 */ 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; } if ((jump >= 1U) && (jump <= n)) diff --git a/plsr/path_plan/plsr_path_plan.h b/plsr/path_plan/plsr_path_plan.h index 37bf512..ffe6414 100644 --- a/plsr/path_plan/plsr_path_plan.h +++ b/plsr/path_plan/plsr_path_plan.h @@ -14,7 +14,8 @@ * @brief 解析下一段索引 * @param cur_seg_0based 当前段 0-based * @return 下一段 0-based;无下一段或非法跳转返回 -1 - * @note jump=0 结束;jump=1~N 跳到对应段(可循环) + * @note jump=0:末段→结束;非末段→顺序下一段 + * jump=1~N:跳到对应段(可循环) */ int16_t PlsrPathPlanNextSeg(uint16_t cur_seg_0based);