Selaa lähdekoodia

增加故障诊断

dev1
hanyongwei 1 kuukausi sitten
vanhempi
commit
cda1eac2af
4 muutettua tiedostoa jossa 121 lisäystä ja 22 poistoa
  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 Näytä tiedosto

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


+ 1
- 0
plsr/command/plsr_command.c Näytä tiedosto

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



+ 5
- 2
plsr/command/plsr_command.h Näytä tiedosto

@@ -25,8 +25,11 @@
#define PLSR_CTRL_BIT_STOP (1U << 1) /* 停止脉冲 */
#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 PlsrCommandPoll(void);


+ 115
- 16
plsr/run_control/plsr_run_control.c Näytä tiedosto

@@ -77,6 +77,11 @@ static uint8_t s_pwm_on;
static uint16_t s_run_accel_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 {
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,
uint32_t f_tgt, uint32_t f_end,
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 uint32_t PlsrRunControlClampSpeed(uint32_t spd);
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)
{
PlsrCfg_t *cfg = PlsrParamGetCfg();
PlsrSeg_t *seg = PlsrParamGetSeg(s_cur_seg);
uint8_t keep_pwm;

PlsrRunControlCheckPulseCntFault();
PlsrRunControlCheckDecelCurveFault();

/* 先脱离 RUN,避免脉冲 ISR 重入 */
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。
*
* @return 1 成功;0 下一段目标频非法(仅后续无缝衔接时)
* @return 1 成功
*/
static uint8_t PlsrRunControlResolveSegCallIo(uint16_t seg_0, uint32_t f_tgt,
PlsrSegCallIo_t *io)
@@ -498,7 +552,14 @@ static uint8_t PlsrRunControlResolveSegCallIo(uint16_t seg_0, uint32_t f_tgt,
cfg->default_speed,
&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;
@@ -686,6 +747,7 @@ static void PlsrRunControlEnterDecel(uint32_t from_hz, uint32_t remain_pulses)
{
PlsrRunControlEnterPhase(PH_DECEL, from_hz);

s_decel_budget = remain_pulses;
s_accel_plan.acc_n = 0U;
s_accel_plan.const_n = 0U;
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(复用缓存)。
*/
@@ -789,6 +864,7 @@ static void PlsrRunControlRefreshProfile(uint8_t do_start)
(next <= s_accel_plan.f_tgt)))
{
next = s_accel_plan.f_tgt;
PlsrRunControlOnApproachDone();
if ((PlsrRunControlHasDecel() != 0U) &&
(remain <= s_accel_plan.dec_n))
{
@@ -837,6 +913,24 @@ static void PlsrRunControlPlanSeg(uint32_t total, uint32_t f_from,
decel_ms,
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;

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

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;
}

/* 策略层解析起/止速与加减速;段内只跑 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;
PlsrRunControlPlanSeg(total, io.f_from, f_tgt, io.f_end,
@@ -1102,6 +1186,19 @@ uint8_t PlsrRunControlStart(uint16_t start_seg_1based)
}

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_chain_valid = 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))
{
PlsrCommandSetFault(PLSR_ERR_FREQ_ILLEGAL);
return 0U;
}
if (s_done >= s_target)
@@ -1342,6 +1440,7 @@ void PlsrRunControlOnPulseIsr(void)
(next <= s_accel_plan.f_tgt)))
{
next = s_accel_plan.f_tgt;
PlsrRunControlOnApproachDone();
if ((PlsrRunControlHasDecel() != 0U) &&
(remain <= s_accel_plan.dec_n))
{


Ladataan…
Peruuta
Tallenna