瀏覽代碼

修复段跳转逻辑:当跳转至为0但是非最后一段时,当前段执行完跳转到下一段。最后一段跳转至为0时,结束输出。

master
hanyongwei 1 月之前
父節點
當前提交
5fe2d95c90
共有 6 個檔案被更改,包括 60 行新增57 行删除
  1. +1
    -1
      modbus/modbus_rtu.h
  2. +34
    -29
      plsr/command/plsr_command.c
  3. +15
    -22
      plsr/command/plsr_command.h
  4. +2
    -2
      plsr/param/plsr_param.h
  5. +6
    -2
      plsr/path_plan/plsr_path_plan.c
  6. +2
    -1
      plsr/path_plan/plsr_path_plan.h

+ 1
- 1
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)


+ 34
- 29
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();
}

+ 15
- 22
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 <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_SEG_FREQ 1U /* 段频率非法(非 0 且越界,或解析后不在 1~100k) */



+ 2
- 2
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;

/* ---------- 运行映像访问 ---------- */


+ 6
- 2
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))


+ 2
- 1
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);



Loading…
取消
儲存