|
|
@@ -14,6 +14,10 @@ |
|
|
* 典型策略映射: |
|
|
* 典型策略映射: |
|
|
* - 完成方式:每段 f_end=止速;WAIT 只做段后等待与下一段 f_from(清链→起速) |
|
|
* - 完成方式:每段 f_end=止速;WAIT 只做段后等待与下一段 f_from(清链→起速) |
|
|
* - 后续方式末段:f_end=止速;非末段无缝:f_end=下一段目标 |
|
|
* - 后续方式末段:f_end=止速;非末段无缝:f_end=下一段目标 |
|
|
|
|
|
* - ACT:先按完成/后续规划加速/匀速/减速时间,再和 act_ms 比较: |
|
|
|
|
|
* 加速 > ACT → 加速中途打断;加速+匀速 > ACT → 不进减速; |
|
|
|
|
|
* 加速+匀速 < ACT < 三段总时间 → 减速中途打断; |
|
|
|
|
|
* ACT ≥ 加速+匀速+减速 → 三阶段(含减速)走完,脉冲照常计数,停表等到 ACT 再下一段(※4)。 |
|
|
* - 梯形/三角仅由 f_from/f_tgt/f_end/斜率/mode/脉冲数决定,不读 wait_type |
|
|
* - 梯形/三角仅由 f_from/f_tgt/f_end/斜率/mode/脉冲数决定,不读 wait_type |
|
|
* |
|
|
* |
|
|
* 【运行节拍】TIM3 1ms:RefreshProfile 改频;脉冲 UPDATE ISR 只计 s_done。 |
|
|
* 【运行节拍】TIM3 1ms:RefreshProfile 改频;脉冲 UPDATE ISR 只计 s_done。 |
|
|
@@ -51,9 +55,12 @@ static volatile int32_t s_target; |
|
|
static volatile int32_t s_acc_pulse; |
|
|
static volatile int32_t s_acc_pulse; |
|
|
|
|
|
|
|
|
static INT32U s_dir_deadline; |
|
|
static INT32U s_dir_deadline; |
|
|
static uint32_t s_wait_deadline_ms; /* TIM3:段后 WAIT 时间 */ |
|
|
|
|
|
static uint32_t s_act_deadline_ms; /* TIM3:ACT 脉冲输出时长 */ |
|
|
|
|
|
static uint8_t s_act_armed; |
|
|
|
|
|
|
|
|
static uint32_t s_wait_deadline_ms; /* TIM3:段后 WAIT 时间 / ACT※4 剩余 */ |
|
|
|
|
|
static uint16_t s_act_time_ms; /* 本段 ACT 时长(出脉冲后计) */ |
|
|
|
|
|
static uint32_t s_act_arm_ms; /* 武装时刻的 TIM3 s_ms,与改频 elapsed 脱钩 */ |
|
|
|
|
|
static volatile uint8_t s_act_armed; |
|
|
|
|
|
static volatile uint8_t s_act_expire_req; /* TIM3 置位,任务里切段(避免 ISR 里 PlanSeg) */ |
|
|
|
|
|
static volatile uint8_t s_wait_expire_req; /* WAIT 时间到:ISR 只置位 */ |
|
|
static uint8_t s_wait_is_signal; /* RC_WAIT_COND:1=等 WAIT 沿,0=等时间 */ |
|
|
static uint8_t s_wait_is_signal; /* RC_WAIT_COND:1=等 WAIT 沿,0=等时间 */ |
|
|
|
|
|
|
|
|
static PlsrAccelPlan_t s_accel_plan; |
|
|
static PlsrAccelPlan_t s_accel_plan; |
|
|
@@ -85,7 +92,9 @@ static void PlsrRunControlGotoNextOrFinish(uint16_t cur_seg); |
|
|
static void PlsrRunControlFinishAll(void); |
|
|
static void PlsrRunControlFinishAll(void); |
|
|
static void PlsrRunControlArmActExtOnPulseStart(void); |
|
|
static void PlsrRunControlArmActExtOnPulseStart(void); |
|
|
static void PlsrRunControlCutSegToNext(void); |
|
|
static void PlsrRunControlCutSegToNext(void); |
|
|
|
|
|
static void PlsrRunControlActExpire(void); |
|
|
static void PlsrRunControlEnterPostWaitOrNext(void); |
|
|
static void PlsrRunControlEnterPostWaitOrNext(void); |
|
|
|
|
|
static uint16_t PlsrRunControlActTimeMs(const PlsrSeg_t *seg); |
|
|
static uint8_t PlsrRunControlBlocksFollowKeep(uint16_t cur_seg); |
|
|
static uint8_t PlsrRunControlBlocksFollowKeep(uint16_t cur_seg); |
|
|
static uint8_t PlsrRunControlWillFollowKeep(uint16_t cur_seg); |
|
|
static uint8_t PlsrRunControlWillFollowKeep(uint16_t cur_seg); |
|
|
static uint8_t PlsrRunControlResolveSegCallIo(uint16_t seg_0, uint32_t f_tgt, |
|
|
static uint8_t PlsrRunControlResolveSegCallIo(uint16_t seg_0, uint32_t f_tgt, |
|
|
@@ -94,6 +103,7 @@ 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 PlsrRunControlApplyActTimeCap(uint16_t act_ms); |
|
|
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, |
|
|
uint32_t default_spd, |
|
|
uint32_t default_spd, |
|
|
@@ -113,20 +123,26 @@ static void PlsrRunControlArmActExtOnPulseStart(void) |
|
|
PlsrSignalIoClearEdges(); |
|
|
PlsrSignalIoClearEdges(); |
|
|
} |
|
|
} |
|
|
s_act_armed = 0U; |
|
|
s_act_armed = 0U; |
|
|
if ((seg->wait_type == PLSR_WAIT_ACT) && (seg->act_ms > 0U)) |
|
|
|
|
|
|
|
|
s_act_expire_req = 0U; |
|
|
|
|
|
s_wait_expire_req = 0U; |
|
|
|
|
|
if (seg->wait_type == PLSR_WAIT_ACT) |
|
|
{ |
|
|
{ |
|
|
|
|
|
/* 先写时长/起点再武装。计时用自由运行 s_ms,不被 PlanSeg 清 elapsed */ |
|
|
|
|
|
s_act_time_ms = PlsrRunControlActTimeMs(seg); |
|
|
|
|
|
s_act_arm_ms = PlsrSignalIoGetMs(); |
|
|
s_act_armed = 1U; |
|
|
s_act_armed = 1U; |
|
|
s_act_deadline_ms = PlsrSignalIoDeadlineFromNow(seg->act_ms); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** ACT/EXT 中途切段:停表后立即按 jump 跳转(不再做段后 WAIT) */ |
|
|
|
|
|
|
|
|
/** EXT 中途切段:停表后立即按 jump 跳转 */ |
|
|
static void PlsrRunControlCutSegToNext(void) |
|
|
static void PlsrRunControlCutSegToNext(void) |
|
|
{ |
|
|
{ |
|
|
PlsrCfg_t *cfg = PlsrParamGetCfg(); |
|
|
PlsrCfg_t *cfg = PlsrParamGetCfg(); |
|
|
|
|
|
|
|
|
s_state = RC_IDLE; |
|
|
s_state = RC_IDLE; |
|
|
s_act_armed = 0U; |
|
|
s_act_armed = 0U; |
|
|
|
|
|
s_act_expire_req = 0U; |
|
|
|
|
|
s_wait_expire_req = 0U; |
|
|
PlsrPulseDriverStop(); |
|
|
PlsrPulseDriverStop(); |
|
|
s_follow_cont = 0U; |
|
|
s_follow_cont = 0U; |
|
|
s_pwm_on = 0U; |
|
|
s_pwm_on = 0U; |
|
|
@@ -143,6 +159,50 @@ static void PlsrRunControlCutSegToNext(void) |
|
|
PlsrRunControlGotoNextOrFinish(s_cur_seg); |
|
|
PlsrRunControlGotoNextOrFinish(s_cur_seg); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* ACT 时间到(脉冲可能还没发完):从当前频率切下一段。 |
|
|
|
|
|
* 同向:不停表,下一段 f_from=当前频率(※2 加速相 / ※3 减速相)。 |
|
|
|
|
|
* 反向或无 PWM:停表,下一段从起速爬。 |
|
|
|
|
|
*/ |
|
|
|
|
|
static void PlsrRunControlActExpire(void) |
|
|
|
|
|
{ |
|
|
|
|
|
int16_t next0; |
|
|
|
|
|
uint8_t keep; |
|
|
|
|
|
|
|
|
|
|
|
s_act_armed = 0U; |
|
|
|
|
|
s_act_expire_req = 0U; |
|
|
|
|
|
s_wait_expire_req = 0U; |
|
|
|
|
|
s_state = RC_IDLE; |
|
|
|
|
|
|
|
|
|
|
|
next0 = PlsrPathPlanResolveAfterSeg(s_cur_seg); |
|
|
|
|
|
keep = 0U; |
|
|
|
|
|
if ((next0 >= 0) && (s_pwm_on != 0U) && (s_cur_freq >= 1U) && |
|
|
|
|
|
(PlsrPathPlanIsForward((uint16_t)next0, s_acc_pulse) == s_forward)) |
|
|
|
|
|
{ |
|
|
|
|
|
keep = 1U; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (keep != 0U) |
|
|
|
|
|
{ |
|
|
|
|
|
PlsrPulseDriverClearOnePulseStop(); |
|
|
|
|
|
s_follow_cont = 1U; |
|
|
|
|
|
s_chain_valid = 1U; |
|
|
|
|
|
s_chain_freq = s_cur_freq; |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
PlsrPulseDriverStop(); |
|
|
|
|
|
PlsrPulseDriverClearOnePulseStop(); |
|
|
|
|
|
s_follow_cont = 0U; |
|
|
|
|
|
s_pwm_on = 0U; |
|
|
|
|
|
s_cur_freq = 0U; |
|
|
|
|
|
s_chain_valid = 0U; |
|
|
|
|
|
s_chain_freq = 0U; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
PlsrRunControlGotoNextOrFinish(s_cur_seg); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static void PlsrRunControlEnterPostWaitOrNext(void) |
|
|
static void PlsrRunControlEnterPostWaitOrNext(void) |
|
|
{ |
|
|
{ |
|
|
PlsrSeg_t *seg = PlsrParamGetSeg(s_cur_seg); |
|
|
PlsrSeg_t *seg = PlsrParamGetSeg(s_cur_seg); |
|
|
@@ -209,11 +269,48 @@ static void PlsrRunControlGotoNextOrFinish(uint16_t cur_seg) |
|
|
static void PlsrRunControlAfterSegDone(void) |
|
|
static void PlsrRunControlAfterSegDone(void) |
|
|
{ |
|
|
{ |
|
|
PlsrCfg_t *cfg = PlsrParamGetCfg(); |
|
|
PlsrCfg_t *cfg = PlsrParamGetCfg(); |
|
|
|
|
|
PlsrSeg_t *seg = PlsrParamGetSeg(s_cur_seg); |
|
|
uint8_t keep_pwm; |
|
|
uint8_t keep_pwm; |
|
|
|
|
|
|
|
|
/* 先脱离 RUN,避免脉冲 ISR 重入 */ |
|
|
/* 先脱离 RUN,避免脉冲 ISR 重入 */ |
|
|
s_state = RC_IDLE; |
|
|
s_state = RC_IDLE; |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* ACT ※4:脉冲已发完但 ACT 时间未到 → 停表,等到到期再开下一段。 |
|
|
|
|
|
* 不从当前频率衔接(本段已经走完停表)。 |
|
|
|
|
|
*/ |
|
|
|
|
|
if (seg->wait_type == PLSR_WAIT_ACT) |
|
|
|
|
|
{ |
|
|
|
|
|
uint16_t remain; |
|
|
|
|
|
|
|
|
|
|
|
PlsrPulseDriverStop(); |
|
|
|
|
|
PlsrPulseDriverClearOnePulseStop(); |
|
|
|
|
|
s_follow_cont = 0U; |
|
|
|
|
|
s_pwm_on = 0U; |
|
|
|
|
|
s_cur_freq = 0U; |
|
|
|
|
|
s_chain_valid = 0U; |
|
|
|
|
|
s_chain_freq = 0U; |
|
|
|
|
|
s_act_expire_req = 0U; |
|
|
|
|
|
if ((s_act_armed != 0U) && |
|
|
|
|
|
(PlsrSignalIoMsReached(s_act_arm_ms + (uint32_t)s_act_time_ms) == 0U)) |
|
|
|
|
|
{ |
|
|
|
|
|
uint32_t used = PlsrSignalIoGetMs() - s_act_arm_ms; |
|
|
|
|
|
remain = (used < (uint32_t)s_act_time_ms) ? |
|
|
|
|
|
(uint16_t)((uint32_t)s_act_time_ms - used) : 1U; |
|
|
|
|
|
s_act_armed = 0U; |
|
|
|
|
|
s_wait_is_signal = 0U; |
|
|
|
|
|
s_wait_deadline_ms = PlsrSignalIoDeadlineFromNow(remain); |
|
|
|
|
|
s_state = RC_WAIT_COND; |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
s_act_armed = 0U; |
|
|
|
|
|
PlsrRunControlGotoNextOrFinish(s_cur_seg); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
s_act_armed = 0U; |
|
|
s_act_armed = 0U; |
|
|
|
|
|
s_act_expire_req = 0U; |
|
|
|
|
|
s_wait_expire_req = 0U; |
|
|
|
|
|
|
|
|
keep_pwm = PlsrRunControlWillFollowKeep(s_cur_seg); |
|
|
keep_pwm = PlsrRunControlWillFollowKeep(s_cur_seg); |
|
|
|
|
|
|
|
|
@@ -275,8 +372,6 @@ static uint8_t PlsrRunControlResolveSegCallIo(uint16_t seg_0, uint32_t f_tgt, |
|
|
int16_t next0; |
|
|
int16_t next0; |
|
|
uint8_t end_at_stop; /* 1:本段终止频率用公共止速 */ |
|
|
uint8_t end_at_stop; /* 1:本段终止频率用公共止速 */ |
|
|
|
|
|
|
|
|
(void)f_tgt; |
|
|
|
|
|
|
|
|
|
|
|
io->accel_ms = cfg->accel_ms; |
|
|
io->accel_ms = cfg->accel_ms; |
|
|
io->decel_ms = cfg->decel_ms; |
|
|
io->decel_ms = cfg->decel_ms; |
|
|
|
|
|
|
|
|
@@ -298,8 +393,9 @@ static uint8_t PlsrRunControlResolveSegCallIo(uint16_t seg_0, uint32_t f_tgt, |
|
|
* ---------- 终止频率:仅由发送模式 + 是否有下一段决定 ---------- |
|
|
* ---------- 终止频率:仅由发送模式 + 是否有下一段决定 ---------- |
|
|
* 完成方式 / 真末段:公共止速 |
|
|
* 完成方式 / 真末段:公共止速 |
|
|
* 后续方式非末段:下一段目标(无缝衔接) |
|
|
* 后续方式非末段:下一段目标(无缝衔接) |
|
|
* 不读 wait_type——等待只在段后 EnterPostWaitOrNext 处理 |
|
|
|
|
|
|
|
|
* ACT 不在这里改 f_end:先按梯形算出加/匀/减时间,再 ApplyActTimeCap。 |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
(void)f_tgt; |
|
|
next0 = PlsrPathPlanNextSeg(seg_0); |
|
|
next0 = PlsrPathPlanNextSeg(seg_0); |
|
|
end_at_stop = (next0 < 0) ? 1U : 0U; |
|
|
end_at_stop = (next0 < 0) ? 1U : 0U; |
|
|
|
|
|
|
|
|
@@ -337,6 +433,21 @@ static uint16_t PlsrRunControlWaitTimeMs(const PlsrSeg_t *seg) |
|
|
return seg->wait_ms; |
|
|
return seg->wait_ms; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** ACT 时间:优先 act_ms;0 则回退 wait_ms(旧上位机曾把 ACT 写在 WAIT 列) */ |
|
|
|
|
|
static uint16_t PlsrRunControlActTimeMs(const PlsrSeg_t *seg) |
|
|
|
|
|
{ |
|
|
|
|
|
uint16_t ms = seg->act_ms; |
|
|
|
|
|
if (ms == 0U) |
|
|
|
|
|
{ |
|
|
|
|
|
ms = seg->wait_ms; |
|
|
|
|
|
} |
|
|
|
|
|
if (ms == 0U) |
|
|
|
|
|
{ |
|
|
|
|
|
return 1U; |
|
|
|
|
|
} |
|
|
|
|
|
return ms; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static uint8_t PlsrRunControlWillFollowKeep(uint16_t cur_seg) |
|
|
static uint8_t PlsrRunControlWillFollowKeep(uint16_t cur_seg) |
|
|
{ |
|
|
{ |
|
|
PlsrCfg_t *cfg = PlsrParamGetCfg(); |
|
|
PlsrCfg_t *cfg = PlsrParamGetCfg(); |
|
|
@@ -587,17 +698,23 @@ static void PlsrRunControlRefreshProfile(uint8_t do_start) |
|
|
{ |
|
|
{ |
|
|
if ((s_accel_plan.f_end == 0U) && (s_seg_elapsed_ms > 0U)) |
|
|
if ((s_accel_plan.f_end == 0U) && (s_seg_elapsed_ms > 0U)) |
|
|
{ |
|
|
{ |
|
|
|
|
|
/* |
|
|
|
|
|
* 时间轴已落到止速 0。剩余脉冲仍要发出并计数(ACT※4: |
|
|
|
|
|
* 三阶段走完后等时间,不能把 s_target 截掉导致计数丢失)。 |
|
|
|
|
|
*/ |
|
|
if (s_done < s_target) |
|
|
if (s_done < s_target) |
|
|
{ |
|
|
{ |
|
|
s_target = s_done + 1; |
|
|
|
|
|
|
|
|
next = 1U; |
|
|
} |
|
|
} |
|
|
if (PlsrRunControlWillFollowKeep(s_cur_seg) == 0U) |
|
|
|
|
|
|
|
|
else |
|
|
{ |
|
|
{ |
|
|
PlsrPulseDriverArmOnePulseStop(); |
|
|
|
|
|
|
|
|
return; |
|
|
} |
|
|
} |
|
|
return; |
|
|
|
|
|
} |
|
|
} |
|
|
next = 1U; |
|
|
|
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
next = 1U; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if ((next != s_cur_freq) || (do_start != 0U) || (s_pwm_on == 0U)) |
|
|
if ((next != s_cur_freq) || (do_start != 0U) || (s_pwm_on == 0U)) |
|
|
@@ -726,6 +843,41 @@ static void PlsrRunControlPlanSeg(uint32_t total, uint32_t f_from, |
|
|
s_seg_elapsed_ms = 0U; |
|
|
s_seg_elapsed_ms = 0U; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 按 ACT 时间裁剪本段时间轴(规划已含加速/匀速/减速): |
|
|
|
|
|
* - T_acc > ACT → 加速未到目标频就被打断 |
|
|
|
|
|
* - T_acc+T_const > ACT → 匀速期内打断,不进入减速 |
|
|
|
|
|
* - T_acc+T_const < ACT < 三段总长 → 进入减速,可能被中途打断 |
|
|
|
|
|
* - ACT ≥ 加速+匀速+减速 → 三阶段走完(含减速到止速),脉冲发完后等 ACT(※4) |
|
|
|
|
|
*/ |
|
|
|
|
|
static void PlsrRunControlApplyActTimeCap(uint16_t act_ms) |
|
|
|
|
|
{ |
|
|
|
|
|
uint32_t t_act; |
|
|
|
|
|
uint32_t t_acc; |
|
|
|
|
|
uint32_t t_const_end; |
|
|
|
|
|
uint32_t t_wave; |
|
|
|
|
|
|
|
|
|
|
|
t_act = (act_ms == 0U) ? 1U : (uint32_t)act_ms; |
|
|
|
|
|
t_acc = s_accel_plan.t_acc_ms; |
|
|
|
|
|
t_const_end = s_accel_plan.t_decel_start_ms; |
|
|
|
|
|
if (t_const_end < t_acc) |
|
|
|
|
|
{ |
|
|
|
|
|
t_const_end = t_acc; |
|
|
|
|
|
} |
|
|
|
|
|
t_wave = t_const_end + s_accel_plan.t_dec_ms; |
|
|
|
|
|
|
|
|
|
|
|
if ((t_act >= t_wave) || (t_act > t_const_end)) |
|
|
|
|
|
{ |
|
|
|
|
|
/* 进入减速,或 ACT 比三段总时间还长:保留减速规划 */ |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* 加速中途或匀速期内就会切段:时间轴上不再走减速 */ |
|
|
|
|
|
s_accel_plan.t_dec_ms = 0U; |
|
|
|
|
|
s_accel_plan.dec_n = 0U; |
|
|
|
|
|
s_accel_plan.f_end = s_accel_plan.f_tgt; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static void PlsrRunControlFinishAll(void) |
|
|
static void PlsrRunControlFinishAll(void) |
|
|
{ |
|
|
{ |
|
|
PlsrPulseDriverStop(); |
|
|
PlsrPulseDriverStop(); |
|
|
@@ -738,6 +890,11 @@ static void PlsrRunControlFinishAll(void) |
|
|
s_follow_cont = 0U; |
|
|
s_follow_cont = 0U; |
|
|
s_chain_valid = 0U; |
|
|
s_chain_valid = 0U; |
|
|
s_chain_freq = 0U; |
|
|
s_chain_freq = 0U; |
|
|
|
|
|
s_act_armed = 0U; |
|
|
|
|
|
s_act_expire_req = 0U; |
|
|
|
|
|
s_wait_expire_req = 0U; |
|
|
|
|
|
s_act_time_ms = 0U; |
|
|
|
|
|
s_act_arm_ms = 0U; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void PlsrRunControlBeginSeg(uint16_t seg_0) |
|
|
static void PlsrRunControlBeginSeg(uint16_t seg_0) |
|
|
@@ -813,6 +970,10 @@ static void PlsrRunControlBeginSeg(uint16_t seg_0) |
|
|
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, |
|
|
io.accel_ms, io.decel_ms); |
|
|
io.accel_ms, io.decel_ms); |
|
|
|
|
|
if (seg->wait_type == PLSR_WAIT_ACT) |
|
|
|
|
|
{ |
|
|
|
|
|
PlsrRunControlApplyActTimeCap(PlsrRunControlActTimeMs(seg)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
s_done = 0; |
|
|
s_done = 0; |
|
|
s_busy = 1U; |
|
|
s_busy = 1U; |
|
|
@@ -861,9 +1022,12 @@ void PlsrRunControlInit(void) |
|
|
s_approach_from = 0U; |
|
|
s_approach_from = 0U; |
|
|
s_decel_from = 0U; |
|
|
s_decel_from = 0U; |
|
|
s_act_armed = 0U; |
|
|
s_act_armed = 0U; |
|
|
|
|
|
s_act_expire_req = 0U; |
|
|
|
|
|
s_wait_expire_req = 0U; |
|
|
|
|
|
s_act_time_ms = 0U; |
|
|
|
|
|
s_act_arm_ms = 0U; |
|
|
s_wait_is_signal = 0U; |
|
|
s_wait_is_signal = 0U; |
|
|
s_wait_deadline_ms = 0U; |
|
|
s_wait_deadline_ms = 0U; |
|
|
s_act_deadline_ms = 0U; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
uint8_t PlsrRunControlStart(uint16_t start_seg_1based) |
|
|
uint8_t PlsrRunControlStart(uint16_t start_seg_1based) |
|
|
@@ -909,6 +1073,10 @@ void PlsrRunControlStop(void) |
|
|
s_chain_valid = 0U; |
|
|
s_chain_valid = 0U; |
|
|
s_chain_freq = 0U; |
|
|
s_chain_freq = 0U; |
|
|
s_act_armed = 0U; |
|
|
s_act_armed = 0U; |
|
|
|
|
|
s_act_expire_req = 0U; |
|
|
|
|
|
s_wait_expire_req = 0U; |
|
|
|
|
|
s_act_time_ms = 0U; |
|
|
|
|
|
s_act_arm_ms = 0U; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
uint8_t PlsrRunControlChangeFreq(uint32_t new_tgt_hz) |
|
|
uint8_t PlsrRunControlChangeFreq(uint32_t new_tgt_hz) |
|
|
@@ -933,6 +1101,13 @@ uint8_t PlsrRunControlChangeFreq(uint32_t new_tgt_hz) |
|
|
f_end = s_accel_plan.f_end; |
|
|
f_end = s_accel_plan.f_end; |
|
|
PlsrRunControlPlanSeg(remain, s_cur_freq, new_tgt_hz, f_end, |
|
|
PlsrRunControlPlanSeg(remain, s_cur_freq, new_tgt_hz, f_end, |
|
|
s_run_accel_ms, s_run_decel_ms); |
|
|
s_run_accel_ms, s_run_decel_ms); |
|
|
|
|
|
if (PlsrParamGetSeg(s_cur_seg)->wait_type == PLSR_WAIT_ACT) |
|
|
|
|
|
{ |
|
|
|
|
|
uint32_t used = PlsrSignalIoGetMs() - s_act_arm_ms; |
|
|
|
|
|
uint16_t left = (used < (uint32_t)s_act_time_ms) ? |
|
|
|
|
|
(uint16_t)((uint32_t)s_act_time_ms - used) : 1U; |
|
|
|
|
|
PlsrRunControlApplyActTimeCap(left); |
|
|
|
|
|
} |
|
|
s_target = (int32_t)remain; |
|
|
s_target = (int32_t)remain; |
|
|
s_done = 0; |
|
|
s_done = 0; |
|
|
s_seg_elapsed_ms = 0U; |
|
|
s_seg_elapsed_ms = 0U; |
|
|
@@ -944,6 +1119,26 @@ void PlsrRunControlTickMs(void) |
|
|
{ |
|
|
{ |
|
|
PlsrSeg_t *seg; |
|
|
PlsrSeg_t *seg; |
|
|
|
|
|
|
|
|
|
|
|
/* ACT / WAIT 到期切段放任务里做(PlanSeg/BeginSeg 不能堵在 TIM3 ISR) */ |
|
|
|
|
|
if (s_act_expire_req != 0U) |
|
|
|
|
|
{ |
|
|
|
|
|
s_act_expire_req = 0U; |
|
|
|
|
|
if (s_state == RC_RUN) |
|
|
|
|
|
{ |
|
|
|
|
|
PlsrRunControlActExpire(); |
|
|
|
|
|
} |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
if (s_wait_expire_req != 0U) |
|
|
|
|
|
{ |
|
|
|
|
|
s_wait_expire_req = 0U; |
|
|
|
|
|
if (s_state == RC_WAIT_COND) |
|
|
|
|
|
{ |
|
|
|
|
|
PlsrRunControlGotoNextOrFinish(s_cur_seg); |
|
|
|
|
|
} |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (s_state == RC_DIR_WAIT) |
|
|
if (s_state == RC_DIR_WAIT) |
|
|
{ |
|
|
{ |
|
|
if (PlsrRunControlOsTimeReached(s_dir_deadline) != 0U) |
|
|
if (PlsrRunControlOsTimeReached(s_dir_deadline) != 0U) |
|
|
@@ -958,16 +1153,9 @@ void PlsrRunControlTickMs(void) |
|
|
|
|
|
|
|
|
if (s_state == RC_RUN) |
|
|
if (s_state == RC_RUN) |
|
|
{ |
|
|
{ |
|
|
/* 波形改频在 TIM3 On1ms;此处只处理 ACT/EXT */ |
|
|
|
|
|
|
|
|
/* 波形改频 / ACT 计时在 TIM3 On1ms;此处只处理 EXT */ |
|
|
seg = PlsrParamGetSeg(s_cur_seg); |
|
|
seg = PlsrParamGetSeg(s_cur_seg); |
|
|
|
|
|
|
|
|
if ((s_act_armed != 0U) && |
|
|
|
|
|
(PlsrSignalIoMsReached(s_act_deadline_ms) != 0U)) |
|
|
|
|
|
{ |
|
|
|
|
|
PlsrRunControlCutSegToNext(); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ((seg->wait_type == PLSR_WAIT_EXT) || |
|
|
if ((seg->wait_type == PLSR_WAIT_EXT) || |
|
|
(seg->wait_type == PLSR_WAIT_EXT_OR_DONE)) |
|
|
(seg->wait_type == PLSR_WAIT_EXT_OR_DONE)) |
|
|
{ |
|
|
{ |
|
|
@@ -989,18 +1177,27 @@ void PlsrRunControlTickMs(void) |
|
|
PlsrRunControlGotoNextOrFinish(s_cur_seg); |
|
|
PlsrRunControlGotoNextOrFinish(s_cur_seg); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
else if (PlsrSignalIoMsReached(s_wait_deadline_ms) != 0U) |
|
|
|
|
|
{ |
|
|
|
|
|
PlsrRunControlGotoNextOrFinish(s_cur_seg); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/* WAIT 时间 / ACT 剩余到期在 On1ms */ |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* TIM3 1ms:段内时间累加 + 按时间轴 RefreshProfile 改频。 |
|
|
* TIM3 1ms:段内时间累加 + 按时间轴 RefreshProfile 改频。 |
|
|
|
|
|
* ACT/WAIT 只置标志,切段在 TickMs(避免 ISR 里 PlanSeg 丢拍)。 |
|
|
*/ |
|
|
*/ |
|
|
void PlsrRunControlOn1ms(void) |
|
|
void PlsrRunControlOn1ms(void) |
|
|
{ |
|
|
{ |
|
|
|
|
|
if (s_state == RC_WAIT_COND) |
|
|
|
|
|
{ |
|
|
|
|
|
/* WAIT 时间 / ACT※4 剩余:跟 TIM3 1ms,不走 OS 节拍 */ |
|
|
|
|
|
if ((s_wait_is_signal == 0U) && |
|
|
|
|
|
(PlsrSignalIoMsReached(s_wait_deadline_ms) != 0U)) |
|
|
|
|
|
{ |
|
|
|
|
|
s_wait_expire_req = 1U; |
|
|
|
|
|
} |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (s_state != RC_RUN) |
|
|
if (s_state != RC_RUN) |
|
|
{ |
|
|
{ |
|
|
return; |
|
|
return; |
|
|
@@ -1011,17 +1208,37 @@ void PlsrRunControlOn1ms(void) |
|
|
s_seg_elapsed_ms++; |
|
|
s_seg_elapsed_ms++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* ACT 到点:若加/匀/减三阶段已经走完,不要按当前频率切段, |
|
|
|
|
|
* 剩余脉冲继续发完,由 AfterSegDone ※4 停表等到点。 |
|
|
|
|
|
*/ |
|
|
|
|
|
if ((s_act_armed != 0U) && |
|
|
|
|
|
(PlsrSignalIoMsReached(s_act_arm_ms + (uint32_t)s_act_time_ms) != 0U)) |
|
|
|
|
|
{ |
|
|
|
|
|
uint32_t t_wave; |
|
|
|
|
|
|
|
|
|
|
|
t_wave = s_accel_plan.t_decel_start_ms + s_accel_plan.t_dec_ms; |
|
|
|
|
|
if ((s_accel_plan.t_dec_ms >= 1U) && (s_seg_elapsed_ms >= t_wave)) |
|
|
|
|
|
{ |
|
|
|
|
|
/* 三段已结束,等脉冲 ISR 把 s_done 走到 s_target */ |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
s_act_armed = 0U; |
|
|
|
|
|
s_act_expire_req = 1U; |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if ((s_accel_plan.f_end == 0U) && |
|
|
if ((s_accel_plan.f_end == 0U) && |
|
|
(s_accel_plan.mode != PLSR_ACCEL_LINEAR) && |
|
|
(s_accel_plan.mode != PLSR_ACCEL_LINEAR) && |
|
|
(s_accel_plan.t_dec_ms >= 1U) && |
|
|
(s_accel_plan.t_dec_ms >= 1U) && |
|
|
(s_seg_elapsed_ms >= |
|
|
(s_seg_elapsed_ms >= |
|
|
(s_accel_plan.t_decel_start_ms + s_accel_plan.t_dec_ms))) |
|
|
(s_accel_plan.t_decel_start_ms + s_accel_plan.t_dec_ms))) |
|
|
{ |
|
|
{ |
|
|
if (s_done < s_target) |
|
|
|
|
|
{ |
|
|
|
|
|
s_target = s_done + 1; |
|
|
|
|
|
} |
|
|
|
|
|
if (PlsrRunControlWillFollowKeep(s_cur_seg) == 0U) |
|
|
|
|
|
|
|
|
/* 非直线:时间轴走完减速后,剩余脉冲仍按最后频率发完并计数 */ |
|
|
|
|
|
if ((s_done >= s_target) && |
|
|
|
|
|
(PlsrRunControlWillFollowKeep(s_cur_seg) == 0U)) |
|
|
{ |
|
|
{ |
|
|
PlsrPulseDriverArmOnePulseStop(); |
|
|
PlsrPulseDriverArmOnePulseStop(); |
|
|
} |
|
|
} |
|
|
|