Преглед на файлове

增加故障诊断

dev1
hanyongwei преди 1 месец
родител
ревизия
cda1eac2af
променени са 4 файла, в които са добавени 121 реда и са изтрити 22 реда
  1. +0
    -4
      iar/plsr.dep
  2. +1
    -0
      plsr/command/plsr_command.c
  3. +5
    -2
      plsr/command/plsr_command.h
  4. +115
    -16
      plsr/run_control/plsr_run_control.c

+ 0
- 4
iar/plsr.dep Целия файл

@@ -3092,10 +3092,6 @@
<name>BICOMP</name> <name>BICOMP</name>
<file> 283</file> <file> 283</file>
</tool> </tool>
<tool>
<name>ICCARM</name>
<file> 33</file>
</tool>
<tool> <tool>
<name>__cstat</name> <name>__cstat</name>
<file> 268</file> <file> 268</file>


+ 1
- 0
plsr/command/plsr_command.c Целия файл

@@ -99,6 +99,7 @@ void PlsrCommandOnSegFreqHoldWrite(uint16_t start_addr, uint16_t quantity)
((uint32_t)ReadHoldReg((uint16_t)(start_addr + 1U)) << 16); ((uint32_t)ReadHoldReg((uint16_t)(start_addr + 1U)) << 16);
if ((f < 1U) || (f > 100000U)) if ((f < 1U) || (f > 100000U))
{ {
PlsrCommandSetFault(PLSR_ERR_FREQ_ILLEGAL);
return; return;
} }




+ 5
- 2
plsr/command/plsr_command.h Целия файл

@@ -25,8 +25,11 @@
#define PLSR_CTRL_BIT_STOP (1U << 1) /* 停止脉冲 */ #define PLSR_CTRL_BIT_STOP (1U << 1) /* 停止脉冲 */
#define PLSR_CTRL_BIT_CLR (1U << 2) /* 清除状态信息 */ #define PLSR_CTRL_BIT_CLR (1U << 2) /* 清除状态信息 */


#define PLSR_ERR_NONE 0U
#define PLSR_ERR_SEG_FREQ 1U /* 段频率非法(非 0 且越界,或解析后不在 1~100k) */
#define PLSR_ERR_NONE 0x00U /* 无故障 */
#define PLSR_ERR_PULSE_CNT 0x01U /* 脉冲输出个数与设置不一致(告警,继续) */
#define PLSR_ERR_FREQ_UNREACH 0x02U /* 输出频率与设置不一致/三角达不到(告警,继续) */
#define PLSR_ERR_CURVE_MISMATCH 0x03U /* 加减速曲线与设置不一致(告警,继续) */
#define PLSR_ERR_FREQ_ILLEGAL 0x04U /* 脉冲频率非法(1~100k)(告警,禁止启动) */


void PlsrCommandInit(void); void PlsrCommandInit(void);
void PlsrCommandPoll(void); void PlsrCommandPoll(void);


+ 115
- 16
plsr/run_control/plsr_run_control.c Целия файл

@@ -77,6 +77,11 @@ static uint8_t s_pwm_on;
static uint16_t s_run_accel_ms; static uint16_t s_run_accel_ms;
static uint16_t s_run_decel_ms; static uint16_t s_run_decel_ms;


/* 规划锁定的加/减速脉冲预算(EnterDecel 会改写 plan.dec_n,故另存) */
static uint32_t s_plan_acc_n;
static uint32_t s_plan_dec_n;
static uint32_t s_decel_budget; /* 进入减速时的 remain,用于 0x03 */

/** 策略层交给段处理的接口参数 */ /** 策略层交给段处理的接口参数 */
typedef struct { typedef struct {
uint32_t f_from; uint32_t f_from;
@@ -102,6 +107,10 @@ static uint16_t PlsrRunControlWaitTimeMs(const PlsrSeg_t *seg);
static void PlsrRunControlPlanSeg(uint32_t total, uint32_t f_from, static void PlsrRunControlPlanSeg(uint32_t total, uint32_t f_from,
uint32_t f_tgt, uint32_t f_end, uint32_t f_tgt, uint32_t f_end,
uint16_t accel_ms, uint16_t decel_ms); uint16_t accel_ms, uint16_t decel_ms);
static void PlsrRunControlCheckPulseCntFault(void);
static void PlsrRunControlCheckApproachCurveFault(uint8_t by_pulse_budget);
static void PlsrRunControlOnApproachDone(void);
static void PlsrRunControlCheckDecelCurveFault(void);
static int32_t PlsrRunControlAbsLocalPos(void); static int32_t PlsrRunControlAbsLocalPos(void);
static uint32_t PlsrRunControlClampSpeed(uint32_t spd); static uint32_t PlsrRunControlClampSpeed(uint32_t spd);
static uint8_t PlsrRunControlGetSegTargetFreq(int32_t freq_hz, static uint8_t PlsrRunControlGetSegTargetFreq(int32_t freq_hz,
@@ -320,12 +329,57 @@ static void PlsrRunControlGotoNextOrFinish(uint16_t cur_seg)
} }
} }


/** 0x01:段正常结束时实际脉冲 ≠ 本段目标(告警,不停) */
static void PlsrRunControlCheckPulseCntFault(void)
{
if ((s_target > 0) && (s_done != s_target))
{
PlsrCommandSetFault(PLSR_ERR_PULSE_CNT);
}
}

/**
* 0x03:加速段结束时,相内脉冲与规划 acc_n 不一致。
* by_pulse_budget:因 n 走到预算而收尾,须精确相等;因频率提前到位则仅超额时报。
*/
static void PlsrRunControlCheckApproachCurveFault(uint8_t by_pulse_budget)
{
if (s_plan_acc_n == 0U)
{
return;
}
if (by_pulse_budget != 0U)
{
if (s_pulse_rt.n != s_plan_acc_n)
{
PlsrCommandSetFault(PLSR_ERR_CURVE_MISMATCH);
}
}
else if (s_pulse_rt.n > s_plan_acc_n)
{
PlsrCommandSetFault(PLSR_ERR_CURVE_MISMATCH);
}
}

/** 0x03:减速段在段末核对相内脉冲与进入减速时的预算 */
static void PlsrRunControlCheckDecelCurveFault(void)
{
if ((s_phase == PH_DECEL) && (s_decel_budget > 0U) &&
(s_pulse_rt.n != s_decel_budget))
{
PlsrCommandSetFault(PLSR_ERR_CURVE_MISMATCH);
}
}

static void PlsrRunControlAfterSegDone(void) static void PlsrRunControlAfterSegDone(void)
{ {
PlsrCfg_t *cfg = PlsrParamGetCfg(); PlsrCfg_t *cfg = PlsrParamGetCfg();
PlsrSeg_t *seg = PlsrParamGetSeg(s_cur_seg); PlsrSeg_t *seg = PlsrParamGetSeg(s_cur_seg);
uint8_t keep_pwm; uint8_t keep_pwm;


PlsrRunControlCheckPulseCntFault();
PlsrRunControlCheckDecelCurveFault();

/* 先脱离 RUN,避免脉冲 ISR 重入 */ /* 先脱离 RUN,避免脉冲 ISR 重入 */
s_state = RC_IDLE; s_state = RC_IDLE;


@@ -421,7 +475,7 @@ static uint8_t PlsrRunControlBlocksFollowKeep(uint16_t cur_seg)
* 调用/等待策略:根据发送模式、等待条件、衔接状态,解析本段 * 调用/等待策略:根据发送模式、等待条件、衔接状态,解析本段
* f_from / f_end / accel_ms / decel_ms。段内处理不读 wait_type。 * f_from / f_end / accel_ms / decel_ms。段内处理不读 wait_type。
* *
* @return 1 成功;0 下一段目标频非法(仅后续无缝衔接时)
* @return 1 成功
*/ */
static uint8_t PlsrRunControlResolveSegCallIo(uint16_t seg_0, uint32_t f_tgt, static uint8_t PlsrRunControlResolveSegCallIo(uint16_t seg_0, uint32_t f_tgt,
PlsrSegCallIo_t *io) PlsrSegCallIo_t *io)
@@ -498,7 +552,14 @@ static uint8_t PlsrRunControlResolveSegCallIo(uint16_t seg_0, uint32_t f_tgt,
cfg->default_speed, cfg->default_speed,
&io->f_end) == 0U) &io->f_end) == 0U)
{ {
return 0U;
/* 下一段频率非法:本段先止速收尾,下一段 Begin 再报 0x04 */
io->f_end = PlsrAccelCurveResolveEndHz(cfg->end_speed,
f_tgt,
cfg->default_speed,
cfg->start_speed,
cfg->end_speed,
io->accel_ms,
io->decel_ms);
} }
} }
return 1U; return 1U;
@@ -686,6 +747,7 @@ static void PlsrRunControlEnterDecel(uint32_t from_hz, uint32_t remain_pulses)
{ {
PlsrRunControlEnterPhase(PH_DECEL, from_hz); PlsrRunControlEnterPhase(PH_DECEL, from_hz);


s_decel_budget = remain_pulses;
s_accel_plan.acc_n = 0U; s_accel_plan.acc_n = 0U;
s_accel_plan.const_n = 0U; s_accel_plan.const_n = 0U;
s_accel_plan.dec_n = remain_pulses; s_accel_plan.dec_n = remain_pulses;
@@ -712,6 +774,19 @@ static void PlsrRunControlEnterDecel(uint32_t from_hz, uint32_t remain_pulses)
} }
} }


/** 离开加速相时做 0x03 诊断 */
static void PlsrRunControlOnApproachDone(void)
{
uint8_t by_budget;

if (s_phase != PH_APPROACH)
{
return;
}
by_budget = ((s_plan_acc_n > 0U) && (s_pulse_rt.n >= s_plan_acc_n)) ? 1U : 0U;
PlsrRunControlCheckApproachCurveFault(by_budget);
}

/** /**
* 进匀速:写一次 f_tgt,之后 ISR 不改 ARR(复用缓存)。 * 进匀速:写一次 f_tgt,之后 ISR 不改 ARR(复用缓存)。
*/ */
@@ -789,6 +864,7 @@ static void PlsrRunControlRefreshProfile(uint8_t do_start)
(next <= s_accel_plan.f_tgt))) (next <= s_accel_plan.f_tgt)))
{ {
next = s_accel_plan.f_tgt; next = s_accel_plan.f_tgt;
PlsrRunControlOnApproachDone();
if ((PlsrRunControlHasDecel() != 0U) && if ((PlsrRunControlHasDecel() != 0U) &&
(remain <= s_accel_plan.dec_n)) (remain <= s_accel_plan.dec_n))
{ {
@@ -837,6 +913,24 @@ static void PlsrRunControlPlanSeg(uint32_t total, uint32_t f_from,
decel_ms, decel_ms,
cfg->accel_mode); cfg->accel_mode);


/*
* 0x02:规划后峰值低于设定目标 → 脉冲不够爬到目标频(三角等)
* 告警,仍按当前规划继续跑。
*/
if ((f_tgt > f_from) && (s_accel_plan.f_tgt < f_tgt))
{
PlsrCommandSetFault(PLSR_ERR_FREQ_UNREACH);
}
else if ((f_tgt < f_from) && (s_accel_plan.f_tgt > f_tgt))
{
PlsrCommandSetFault(PLSR_ERR_FREQ_UNREACH);
}

/* 0x03 对照用:规划预算(运行中 s_accel_plan.acc_n 可能被改写) */
s_plan_acc_n = s_accel_plan.acc_n;
s_plan_dec_n = s_accel_plan.dec_n;
s_decel_budget = 0U;

/* 运行层使用规划后的实际起始频率。 */ /* 运行层使用规划后的实际起始频率。 */
f_start = s_accel_plan.f_cur; f_start = s_accel_plan.f_cur;


@@ -1003,24 +1097,14 @@ static void PlsrRunControlBeginSeg(uint16_t seg_0)


if (PlsrRunControlGetSegTargetFreq(seg->freq_hz, cfg->default_speed, &f_tgt) == 0U) if (PlsrRunControlGetSegTargetFreq(seg->freq_hz, cfg->default_speed, &f_tgt) == 0U)
{ {
PlsrCommandSetFault(PLSR_ERR_SEG_FREQ);
s_busy = 1U;
s_target = 0;
s_done = 0;
PlsrRunControlAfterSegDone();
/* 0x04:频率非法,禁止启动/切段 */
PlsrCommandSetFault(PLSR_ERR_FREQ_ILLEGAL);
PlsrRunControlFinishAll();
return; return;
} }


/* 策略层解析起/止速与加减速;段内只跑 PlanSeg */ /* 策略层解析起/止速与加减速;段内只跑 PlanSeg */
if (PlsrRunControlResolveSegCallIo(seg_0, f_tgt, &io) == 0U)
{
PlsrCommandSetFault(PLSR_ERR_SEG_FREQ);
s_busy = 1U;
s_target = 0;
s_done = 0;
PlsrRunControlAfterSegDone();
return;
}
(void)PlsrRunControlResolveSegCallIo(seg_0, f_tgt, &io);


total = (uint32_t)s_target; total = (uint32_t)s_target;
PlsrRunControlPlanSeg(total, io.f_from, f_tgt, io.f_end, PlsrRunControlPlanSeg(total, io.f_from, f_tgt, io.f_end,
@@ -1102,6 +1186,19 @@ uint8_t PlsrRunControlStart(uint16_t start_seg_1based)
} }


cfg = PlsrParamGetCfg(); cfg = PlsrParamGetCfg();
{
PlsrSeg_t *seg = PlsrParamGetSeg((uint16_t)(start_seg_1based - 1U));
uint32_t f_chk;

/* 启动前校验首段频率;非法则写 0x04 且不进入运行 */
if (PlsrRunControlGetSegTargetFreq(seg->freq_hz,
cfg->default_speed,
&f_chk) == 0U)
{
PlsrCommandSetFault(PLSR_ERR_FREQ_ILLEGAL);
return 0U;
}
}
s_follow_cont = 0U; s_follow_cont = 0U;
s_chain_valid = 0U; s_chain_valid = 0U;
s_chain_freq = 0U; s_chain_freq = 0U;
@@ -1145,6 +1242,7 @@ uint8_t PlsrRunControlChangeFreq(uint32_t new_tgt_hz)
} }
if ((new_tgt_hz < 1U) || (new_tgt_hz > 100000U)) if ((new_tgt_hz < 1U) || (new_tgt_hz > 100000U))
{ {
PlsrCommandSetFault(PLSR_ERR_FREQ_ILLEGAL);
return 0U; return 0U;
} }
if (s_done >= s_target) if (s_done >= s_target)
@@ -1342,6 +1440,7 @@ void PlsrRunControlOnPulseIsr(void)
(next <= s_accel_plan.f_tgt))) (next <= s_accel_plan.f_tgt)))
{ {
next = s_accel_plan.f_tgt; next = s_accel_plan.f_tgt;
PlsrRunControlOnApproachDone();
if ((PlsrRunControlHasDecel() != 0U) && if ((PlsrRunControlHasDecel() != 0U) &&
(remain <= s_accel_plan.dec_n)) (remain <= s_accel_plan.dec_n))
{ {


Зареждане…
Отказ
Запис