diff --git a/modbus/modbus_rtu.c b/modbus/modbus_rtu.c index 72c513f..842e973 100644 --- a/modbus/modbus_rtu.c +++ b/modbus/modbus_rtu.c @@ -441,7 +441,9 @@ static void WriteMultiRegs(const uint8_t *frame, uint16_t len) g_modbus_tx_buf[5] = frame[5]; AppendCrcAndSend(g_modbus_tx_buf, 6U); + /*统计接受帧数,收满释放信号量*/ PlsrParamBlockOnHoldWrite(startAddr, quantity); + /* 动态改频率 */ PlsrCommandOnSegFreqHoldWrite(startAddr, quantity); } diff --git a/plsr/accel_curve/plsr_accel_curve.c b/plsr/accel_curve/plsr_accel_curve.c index 5c6a8ae..f0ad4ef 100644 --- a/plsr/accel_curve/plsr_accel_curve.c +++ b/plsr/accel_curve/plsr_accel_curve.c @@ -125,28 +125,32 @@ static void PlsrAccelRuntimeSelectFreqTable(PlsrAccelRuntime_t *runtime, /* 公共 API */ /*============================================================================*/ +/*计算起始频率*/ uint32_t PlsrAccelCurveResolveStartHz(uint32_t configured_freq_hz, uint32_t target_freq_hz, uint32_t default_speed_hz, uint32_t accel_time_ms, uint32_t decel_time_ms) { + /*resolving_start=1 用 accel_time_ms 算 a;resolving_start=0 用 decel_time_ms(ResolveEndHz 止速侧)*/ return PlsrAccelCurveResolveBoundaryFreq(configured_freq_hz, target_freq_hz, default_speed_hz, accel_time_ms, decel_time_ms, 1U); } +/*计算终止频率*/ uint32_t PlsrAccelCurveResolveEndHz(uint32_t configured_freq_hz, uint32_t target_freq_hz, uint32_t default_speed_hz, uint32_t accel_time_ms, uint32_t decel_time_ms) { + /*resolving_start=1 用 accel_time_ms 算 a;resolving_start=0 用 decel_time_ms(ResolveEndHz 止速侧)*/ return PlsrAccelCurveResolveBoundaryFreq(configured_freq_hz, target_freq_hz, default_speed_hz, accel_time_ms, decel_time_ms, 0U); } /** - * @brief 规划一整段脉冲域(见 plsr_accel_curve.h) + * @brief 规划一整段脉冲 */ void PlsrAccelCurvePlan(PlsrAccelPlan_t *plan, uint32_t total_pulses, @@ -163,7 +167,7 @@ void PlsrAccelCurvePlan(PlsrAccelPlan_t *plan, uint32_t peak_freq_hz; uint32_t accel_rate_hz_per_s; uint32_t decel_rate_hz_per_s; - PlsrAccelMode_e selected_mode; + PlsrAccelMode_e selected_mode;/*曲线模式*/ if (plan == (PlsrAccelPlan_t *)0) { @@ -174,13 +178,16 @@ void PlsrAccelCurvePlan(PlsrAccelPlan_t *plan, target_freq_hz = PlsrAccelCurveClampFreqHz(target_freq_hz); end_freq_hz = PlsrAccelCurveClampFreqHz(end_freq_hz); + /*加减速曲线模式*/ selected_mode = (curve_mode > PLSR_ACCEL_SINE) ? PLSR_ACCEL_LINEAR : curve_mode; + /*起始频率小于1,计算一个合适的起始频率*/ if (start_freq_hz < 1U) { start_freq_hz = PlsrAccelCurveResolveStartHz(0U, target_freq_hz, default_speed_hz, accel_time_ms, decel_time_ms); } + /*终止频率小于1,计算一个合适的终止频率*/ if (end_freq_hz < 1U) { end_freq_hz = PlsrAccelCurveResolveEndHz(0U, target_freq_hz, default_speed_hz, @@ -191,13 +198,14 @@ void PlsrAccelCurvePlan(PlsrAccelPlan_t *plan, PlsrAccelCurveCalcRate(default_speed_hz, start_freq_hz, target_freq_hz, - accel_time_ms); + accel_time_ms);/*计算加速斜率*/ decel_rate_hz_per_s = PlsrAccelCurveCalcRate(default_speed_hz, target_freq_hz, end_freq_hz, - decel_time_ms); + decel_time_ms);/*计算减速斜率*/ + /*将结果写进规划结果*/ peak_freq_hz = target_freq_hz; plan->start_freq_hz = start_freq_hz; @@ -206,6 +214,7 @@ void PlsrAccelCurvePlan(PlsrAccelPlan_t *plan, plan->accel_rate_hz_per_s = accel_rate_hz_per_s; plan->decel_rate_hz_per_s = decel_rate_hz_per_s; + /*按峰值重算加速/减速脉冲预算*/ PlsrAccelCurveCalcPhasePulses(start_freq_hz, peak_freq_hz, end_freq_hz, @@ -756,6 +765,7 @@ static uint32_t PlsrAccelCurveResolveBoundaryFreq(uint32_t configured_freq_hz, uint32_t accel_hz_per_s; uint32_t jump_freq_hz; + /* 验证频率是否超过100k */ configured_freq_hz = PlsrAccelCurveClampFreqHz(configured_freq_hz); target_freq_hz = PlsrAccelCurveClampFreqHz(target_freq_hz); if (target_freq_hz < 1U) @@ -763,13 +773,14 @@ static uint32_t PlsrAccelCurveResolveBoundaryFreq(uint32_t configured_freq_hz, return 1U; } - /* 配置起/止速 > 目标:用配置速 */ + /* 配置起始速度/终止止速 > 目标频率:用配置速度 */ if (configured_freq_hz > target_freq_hz) { return configured_freq_hz; } ramp_time_ms = (resolving_start != 0U) ? accel_time_ms : decel_time_ms; + /*计算加速度*/ accel_hz_per_s = PlsrAccelCurveCalcRate(default_speed_hz, configured_freq_hz, @@ -780,6 +791,7 @@ static uint32_t PlsrAccelCurveResolveBoundaryFreq(uint32_t configured_freq_hz, return (configured_freq_hz >= 1U) ? configured_freq_hz : target_freq_hz; } + /*按运动学公式计算起跳频率*/ jump_freq_hz = PlsrAccelCurveCalcJumpFreq(configured_freq_hz, accel_hz_per_s); /* 目标 < 起跳 → 用目标;目标 >= 起跳 → 用起跳 */ @@ -790,6 +802,7 @@ static uint32_t PlsrAccelCurveResolveBoundaryFreq(uint32_t configured_freq_hz, return jump_freq_hz; } +/*线性插值*/ static uint32_t PlsrAccelCurveInterpolate(uint32_t start_val, uint32_t end_val, uint32_t ratio_permille) @@ -1277,7 +1290,7 @@ static uint32_t PlsrAccelCurveTimedFreqAtPulse( return cur_freq_hz; } -/*仿真离散脉冲频率,算出该段加减速一共需要输出多少个脉冲*/ +/*仿真离散脉冲频率,算出该段加/减速一共需要输出多少个脉冲*/ static uint32_t PlsrAccelCurveSimulateRampPulses(uint32_t start_freq_hz, uint32_t end_freq_hz, uint32_t accel_hz_per_s, PlsrAccelMode_e curve_mode) @@ -1285,18 +1298,21 @@ static uint32_t PlsrAccelCurveSimulateRampPulses(uint32_t start_freq_hz, uint32_ PlsrAccelRuntime_t runtime; uint32_t iteration_guard; + /*起始频率 = 终止频率,或者加速度=0,返回0*/ if (start_freq_hz == end_freq_hz || accel_hz_per_s == 0U) { return 0U; } + /* 填写一个加速或减速相的运行数据 */ PlsrAccelRuntimeBeginRamp(&runtime, start_freq_hz, end_freq_hz, - 0xFFFFFFFFUL, + 0xFFFFFFFFUL,/*总脉冲数,填写最大值*/ accel_hz_per_s, accel_hz_per_s, curve_mode); + /* 算出来的斜坡时间是 0(无效)时,仍按至少 1 个脉冲处理。 */ if (runtime.ramp_time_us < 1U) { return 1U; @@ -1306,14 +1322,16 @@ static uint32_t PlsrAccelCurveSimulateRampPulses(uint32_t start_freq_hz, uint32_ while ((runtime.is_active != 0U) && (iteration_guard < 5000000U)) { iteration_guard++; + /* 单个脉冲仿真 */ PlsrAccelRuntimeSimulateOnePulse(&runtime); } + /*使用的脉冲数至少为1个*/ if (runtime.completed_pulses == 0U) { return 1U; } - return runtime.completed_pulses; + return runtime.completed_pulses; /*返回仿真的后的总脉冲数*/ } /** @@ -1368,6 +1386,7 @@ static uint32_t PlsrAccelNextFreqTimed(PlsrAccelRuntime_t *runtime) /* 规划 */ /*============================================================================*/ +/* S或者正弦,采用仿真方式,直线采用直接计算方式 */ static uint32_t PlsrAccelCurveCalcRampPulses(uint32_t start_freq_hz, uint32_t end_freq_hz, uint32_t accel_hz_per_s, PlsrAccelMode_e curve_mode) @@ -1465,6 +1484,7 @@ static void PlsrAccelCurveCalcPhasePulses(uint32_t start_freq_hz, uint32_t *accel_pulses, uint32_t *decel_pulses) { + /*如果起始频率 > 峰值频率,加速脉冲数*/ if (start_freq_hz > peak_freq_hz) { *accel_pulses = PlsrAccelCurveCalcRampPulses(start_freq_hz, peak_freq_hz, decel_rate_hz_per_s, curve_mode); @@ -1534,6 +1554,7 @@ static uint32_t PlsrAccelCurveFitTargetToPulseBudget(uint32_t total_pulses, /* 运行态 */ /*============================================================================*/ +/* 运行时计算时间*/ static void PlsrAccelRuntimeCalcTimes(PlsrAccelRuntime_t *runtime) { runtime->elapsed_time_us = 0U; @@ -1541,15 +1562,18 @@ static void PlsrAccelRuntimeCalcTimes(PlsrAccelRuntime_t *runtime) runtime->const_accel_time_us = 0U; runtime->ramp_time_us = 0U; + /*加速度小于1,或者起始频率 = 终止频率,直接结束*/ if ((runtime->accel_hz_per_s < 1U) || (runtime->start_freq_hz == runtime->end_freq_hz)) { return; } + /*S曲线计算时间*/ if (runtime->curve_mode == PLSR_ACCEL_S) { PlsrAccelCurveCalcSCurveTimes(runtime->start_freq_hz, runtime->end_freq_hz, runtime->accel_hz_per_s, &runtime->jerk_time_us, &runtime->const_accel_time_us, &runtime->ramp_time_us); } + /* 正弦曲线计算时间*/ else if (runtime->curve_mode == PLSR_ACCEL_SINE) { PlsrAccelCurveCalcSineCurveTime(runtime->start_freq_hz, runtime->end_freq_hz, runtime->accel_hz_per_s, &runtime->ramp_time_us); @@ -1570,18 +1594,22 @@ static void PlsrAccelRuntimeBeginRamp(PlsrAccelRuntime_t *runtime, runtime->cur_freq_hz = start_freq_hz; runtime->completed_pulses = 0U; runtime->total_pulses = total_pulses; + /*终点 > 起点,加速过程*/ runtime->freq_rising = (end_freq_hz >= start_freq_hz) ? 1U : 0U; + /*加速度,上升用加速斜率,下降用减速斜率*/ runtime->accel_hz_per_s = (runtime->freq_rising != 0U) ? accel_rate_hz_per_s : decel_rate_hz_per_s; + /*曲线模式*/ runtime->curve_mode = curve_mode; + /* 1=当前相仍在运行 */ runtime->is_active = ((total_pulses > 0U) && (start_freq_hz != end_freq_hz)) ? 1U : 0U; runtime->freq_table_id = 0U; runtime->table_length = 0U; runtime->table_stride = 1U; - PlsrAccelRuntimeCalcTimes(runtime); + PlsrAccelRuntimeCalcTimes(runtime);/*计算加速时间*/ } /** 离散仿真一步:与建表 / 脉冲预算共用 */ diff --git a/plsr/command/plsr_command.c b/plsr/command/plsr_command.c index 02d120f..099e7ac 100644 --- a/plsr/command/plsr_command.c +++ b/plsr/command/plsr_command.c @@ -191,13 +191,13 @@ void PlsrCommandPoll(void) if ((ctrl & PLSR_CTRL_BIT_STOP) != 0U) { - PlsrStop(); + PlsrStop();/*停止输出*/ } if ((ctrl & PLSR_CTRL_BIT_CLR) != 0U) { - PlsrClearAccPulse(); - PlsrCommandClearFault(); /* 清零累计时同步清故障码 */ + PlsrClearAccPulse();/*清零累计脉冲与绝对原点*/ + PlsrCommandClearFault(); /* 清零故障码同步清累计脉冲 */ } /* 同时有停止位时不启动 */ @@ -209,18 +209,19 @@ void PlsrCommandPoll(void) /* 0x0C:运行中重复 START,启动无效 */ PlsrCommandSetFault(PLSR_ERR_DUP_START); } - else if (PlsrParamBlockApplyFromHold() == 0U) - { - /* 如果从modbus保持寄存器写入plsr结构体失败,暂不处理 */ - } + /*如果禁止启动,使用停止指令*/ else if (PlsrCommandIsStartBlocked() != 0U) { /* 0x04~0x0B 故障码:禁止启动 */ + PlsrStop(); } + /*如果允许运行,先停止清标志位,再开始输出*/ else { PlsrStop(); + /*启动输出入口*/ (void)PlsrStart(PlsrParamGetStartSeg()); + /*如果不需要精确等待,就跳过监控*/ if (PlsrRunControlIsPreciseWait() != 0U) { skip_monitor = 1U; @@ -234,11 +235,11 @@ void PlsrCommandPoll(void) { uint32_t freq = s_live_freq_hz; s_live_freq_req = 0U; - (void)PlsrChangeFreq(freq); + (void)PlsrChangeFreq(freq);/*动态改频函数入口*/ } if (skip_monitor == 0U) { - PlsrCommandPublishMonitor(); + PlsrCommandPublishMonitor();/*刷新全部监控寄存器*/ } } diff --git a/plsr/plsr.c b/plsr/plsr.c index 86e509f..b728e2b 100644 --- a/plsr/plsr.c +++ b/plsr/plsr.c @@ -71,9 +71,9 @@ void PlsrTask(void *pArg) s_booted = 1U; } - PlsrRunControlTickMs(); /* 优先:WAIT/换向到期立刻开表 */ + PlsrRunControlTickMs(); /* 处理延时/外部信号输入,优先:WAIT/换向到期立刻开表 */ PlsrSignalIoDebouncePoll(); /* OS 节拍消抖确认 */ - PlsrCommandPoll(); /* 收 START/STOP/CLR,回写 0x2000~0x2006 监控 */ + PlsrCommandPoll(); /* 收 START/STOP/CLR,回写 0x2000~0x2006 监控 ,决定是否开pwm输出*/ PlsrPersistTickMonitor(); /* 监控区:运行态→hold→BKP(每 OS 节拍) */ /* diff --git a/plsr/pulse_driver/plsr_pulse_driver.c b/plsr/pulse_driver/plsr_pulse_driver.c index bde8777..296b5ee 100644 --- a/plsr/pulse_driver/plsr_pulse_driver.c +++ b/plsr/pulse_driver/plsr_pulse_driver.c @@ -120,14 +120,10 @@ static void PlsrPulseDriverDirGpioInit(void) HAL_GPIO_WritePin(PLSR_Y3_PORT, PLSR_Y3_PIN, GPIO_PIN_RESET); } -/** - * 停表:不关复用、不关 CC1E。 - * HAL_TIM_PWM_Stop 会清 CC1E,脚变成 AF 高阻,飞线接地的沿会耦合出极短脉冲。 - * Forced inactive + 通道保持使能:TIM 推挽把脚主动拉低(段间空闲低)。 - */ + /*关掉末拍下降沿再锁低这套 CC1 监听;脚怎么拉低在下面的两个函数*/ static void PlsrPulseDriverClearSegEndFallArm(TIM_HandleTypeDef *htim) { - s_seg_end_fall_armed = 0U; + s_seg_end_fall_armed = 0U;/*末拍 CC1 下降沿后强制拉低 */ if ((htim == (TIM_HandleTypeDef *)0) || (htim->Instance == (TIM_TypeDef *)0)) { return; @@ -429,7 +425,9 @@ static void PlsrPulseDriverCalcPscArr(uint32_t clk_hz, uint32_t freq_hz, PlsrPulseDriverCalcArrWithPsc(clk_hz, freq_hz, p, arr, ccr); } -/** @brief 按频率跨度锁 PSC */ +/** @brief 按频率跨度锁 PSC + * 1 个 tick = TIM 输入时钟的 1 个周期。ticks = 输出 1 个脉冲要占多少个这种小时钟周期。 + */ void PlsrPulseDriverLockPscRange(uint32_t f_min_hz, uint32_t f_max_hz) { uint32_t ticks_max; @@ -437,6 +435,7 @@ void PlsrPulseDriverLockPscRange(uint32_t f_min_hz, uint32_t f_max_hz) uint32_t psc_div_max; uint32_t psc_div_min; uint32_t div; + /*获取Y端子的时钟频率,Y0/Y1为168MHz,Y2为84MHz */ uint32_t clk_hz = PlsrPulseDriverTimClkHz( PlsrPulseDriverHtimByY(PlsrPulseDriverSelectY())); @@ -448,6 +447,7 @@ void PlsrPulseDriverLockPscRange(uint32_t f_min_hz, uint32_t f_max_hz) { f_max_hz = 1U; } + /*如果最小值小于最大值,则交换最小值与最大值*/ if (f_max_hz < f_min_hz) { uint32_t temp = f_min_hz; @@ -455,8 +455,9 @@ void PlsrPulseDriverLockPscRange(uint32_t f_min_hz, uint32_t f_max_hz) f_max_hz = temp; } - ticks_max = clk_hz / f_min_hz; - ticks_min = clk_hz / f_max_hz; + ticks_max = clk_hz / f_min_hz;/*最大tick数=系统频率/最小频率*/ + ticks_min = clk_hz / f_max_hz;/*最小tick数=系统频率/最大频率*/ + /*如果tick数小于2,则改为2,因为tick=(psc+1)(arr+1),psc可以为0,但arr不能为0,否则输出单一电平*/ if (ticks_max < 2UL) { ticks_max = 2UL; @@ -466,16 +467,18 @@ void PlsrPulseDriverLockPscRange(uint32_t f_min_hz, uint32_t f_max_hz) ticks_min = 2UL; } - /* psc_div = PSC+1:低频要求 div 足够大,高频要求 div 足够小 */ + /* psc_div = PSC+1:低频要求 psc 足够大,高频要求 psc 足够小 */ + /* psc = tick / (ARR + 1) ,当arr+1最大时,psc为最小值,再小就不满足乘积=tick*/ psc_div_min = (ticks_max + 65535UL) / 65536UL; if (psc_div_min < 1UL) { psc_div_min = 1UL; } + /* psc = tick / (ARR + 1) ,当arr+1最小时,psc为最大值,再大就不满足乘积=tick*/ psc_div_max = ticks_min / 2UL; if (psc_div_max < 1UL) { - psc_div_max = 1UL; + psc_div_max = 1UL;/* psc的最大值最小为1,最小值可以为0 */ } if (psc_div_min > psc_div_max) @@ -489,7 +492,7 @@ void PlsrPulseDriverLockPscRange(uint32_t f_min_hz, uint32_t f_max_hz) return; } - div = psc_div_min; + div = psc_div_min;/*取最小的psc作为psc锁定,让arr尽可能大,提高分辨率*/ s_locked_psc = div - 1UL; s_psc_locked = 1U; } @@ -1003,7 +1006,7 @@ void PlsrPulseDriverClearOnePulseStop(void) return; } htim->Instance->CR1 &= (uint32_t)(~TIM_CR1_OPM); - PlsrPulseDriverClearSegEndFallArm(htim); + PlsrPulseDriverClearSegEndFallArm(htim);/*关掉末拍下降沿拉低标志*/ } /** @brief OPM 段末 UPDATE 后立刻拉低,消除 CNT 回零 PWM1 假上升沿 */ diff --git a/plsr/pulse_driver/plsr_pulse_driver.h b/plsr/pulse_driver/plsr_pulse_driver.h index 464720a..22659d9 100644 --- a/plsr/pulse_driver/plsr_pulse_driver.h +++ b/plsr/pulse_driver/plsr_pulse_driver.h @@ -38,7 +38,7 @@ extern TIM_HandleTypeDef htim13; extern volatile uint32_t g_plsr_output_freq_hz; extern volatile uint8_t g_plsr_pwm_running; extern uint8_t g_plsr_direction_forward; -extern uint8_t g_plsr_direction_valid; +extern uint8_t g_plsr_direction_valid;/*方向脚有效*/ /** * @brief 初始化三路脉冲 TIM + 方向 GPIO diff --git a/plsr/run_control/plsr_run_control.c b/plsr/run_control/plsr_run_control.c index cb44136..cddf38f 100644 --- a/plsr/run_control/plsr_run_control.c +++ b/plsr/run_control/plsr_run_control.c @@ -38,28 +38,28 @@ typedef enum { PH_DECEL } RunPhase_e; -volatile uint8_t g_plsr_busy; -volatile uint16_t g_plsr_cur_seg_idx; -volatile int32_t g_plsr_accumulated_pulses; -static volatile RcState_e s_state; -static volatile uint8_t s_forward;/*当前端脉冲方向*/ -static volatile int32_t s_seg_pulses_done; -static volatile int32_t s_seg_pulse_target; -static int32_t s_absolute_origin; -static uint8_t s_absolute_origin_locked; -static volatile uint8_t s_act_timer_armed; -static volatile uint8_t s_act_expired; -static volatile uint8_t s_act_waiting_for_pulse_boundary; -static volatile uint8_t s_keep_freq_after_act; -static volatile uint8_t s_wait_time_expired; -static uint8_t s_waiting_for_input_signal; -static volatile RunPhase_e s_phase; -static uint8_t s_continue_without_stopping; -static uint32_t s_next_seg_start_freq_hz; -static uint8_t s_next_seg_start_freq_valid; -static uint8_t s_stop_after_last_pulse; -static volatile uint8_t s_waiting_for_last_period; -static OS_EVENT *s_wake_sem; +volatile uint8_t g_plsr_busy; /* 运行忙标志(上位机监控) */ +volatile uint16_t g_plsr_cur_seg_idx; /* 当前段下标(0-based) */ +volatile int32_t g_plsr_accumulated_pulses; /* 全局累计脉冲(有符号) */ +static volatile RcState_e s_state; /* 主状态机:IDLE/DIR_WAIT/RUN/WAIT_COND */ +static volatile uint8_t s_forward; /* 当前段脉冲方向:1=正转,0=反转 */ +static volatile int32_t s_seg_pulses_done; /* 本段已发脉冲数 */ +static volatile int32_t s_seg_pulse_target; /* 本段目标脉冲数(绝对值) */ +static int32_t s_absolute_origin; /* 绝对定位坐标原点 */ +static uint8_t s_absolute_origin_locked; /* 原点是否已锁定(CLR 后重锁) */ +static volatile uint8_t s_act_timer_armed; /* ACT 定时器是否已启动 */ +static volatile uint8_t s_act_expired; /* ACT 到期请求(TickMs 消费) */ +static volatile uint8_t s_act_waiting_for_pulse_boundary; /* ACT 到期后等脉冲边界切段 */ +static volatile uint8_t s_keep_freq_after_act; /* ACT 切段后保持当前频率衔接 */ +static volatile uint8_t s_wait_time_expired; /* 段后 WAIT 时间到期请求 */ +static uint8_t s_waiting_for_input_signal; /* 段后等 WAIT/EXT 输入沿 */ +static volatile RunPhase_e s_phase; /* 段内相:加速/匀速/减速 */ +static uint8_t s_continue_without_stopping; /* 段间不停表衔接(FOLLOW/keep) */ +static uint32_t s_next_seg_start_freq_hz; /* 段间衔接起始频率 Hz */ +static uint8_t s_next_seg_start_freq_valid; /* 衔接频率是否有效 */ +static uint8_t s_stop_after_last_pulse; /* 末拍后完整停表(完成模式) */ +static volatile uint8_t s_waiting_for_last_period; /* 等末拍 UPDATE 再收尾 */ +static OS_EVENT *s_wake_sem; /* 唤醒 PlsrTask 的信号量 */ /* 策略层解析后交给 PlanSeg 的段端点 */ typedef struct { @@ -121,30 +121,30 @@ static void PlsrRunControlPlanSeg(uint32_t total, uint32_t f_from, /** @brief 运行控制初始化 */ void PlsrRunControlInit(void) { - s_state = RC_IDLE; - g_plsr_busy = 0U; - s_forward = 1U; - g_plsr_cur_seg_idx = 0U; - s_seg_pulses_done = 0; - s_seg_pulse_target = 0; - g_plsr_accumulated_pulses = 0; - s_absolute_origin = 0; - s_absolute_origin_locked = 0U; - s_continue_without_stopping = 0U; - s_next_seg_start_freq_hz = 0U; - s_next_seg_start_freq_valid = 0U; - g_plsr_accel_plan.accel_pulses = 0U; - g_plsr_accel_plan.decel_pulses = 0U; - g_plsr_accel_runtime.total_pulses = 0U; - s_stop_after_last_pulse = 0U; - s_waiting_for_last_period = 0U; - s_phase = PH_CONST; - s_act_timer_armed = 0U; - s_act_expired = 0U; - s_act_waiting_for_pulse_boundary = 0U; - s_keep_freq_after_act = 0U; - s_wait_time_expired = 0U; - s_waiting_for_input_signal = 0U; + s_state = RC_IDLE; /* 主状态机:空闲 */ + g_plsr_busy = 0U; /* 运行忙标志(上位机监控) */ + s_forward = 1U; /* 当前段脉冲方向:1=正转 */ + g_plsr_cur_seg_idx = 0U; /* 当前段下标(0-based) */ + s_seg_pulses_done = 0; /* 本段已发脉冲数 */ + s_seg_pulse_target = 0; /* 本段目标脉冲数(绝对值) */ + g_plsr_accumulated_pulses = 0; /* 全局累计脉冲(有符号) */ + s_absolute_origin = 0; /* 绝对定位坐标原点 */ + s_absolute_origin_locked = 0U; /* 原点是否已锁定(CLR 后重锁) */ + s_continue_without_stopping = 0U; /* 段间不停表衔接(FOLLOW/keep) */ + s_next_seg_start_freq_hz = 0U; /* 段间衔接起始频率 Hz */ + s_next_seg_start_freq_valid = 0U; /* 衔接频率是否有效 */ + g_plsr_accel_plan.accel_pulses = 0U; /* 规划:加速相脉冲预算 */ + g_plsr_accel_plan.decel_pulses = 0U; /* 规划:减速相脉冲预算 */ + g_plsr_accel_runtime.total_pulses = 0U; /* 当前相计划总脉冲 */ + s_stop_after_last_pulse = 0U; /* 末拍后完整停表(完成模式) */ + s_waiting_for_last_period = 0U; /* 等末拍 UPDATE 再收尾 */ + s_phase = PH_CONST; /* 段内相:加速/匀速/减速 */ + s_act_timer_armed = 0U; /* ACT 定时器是否已启动 */ + s_act_expired = 0U; /* ACT 到期请求(TickMs 消费) */ + s_act_waiting_for_pulse_boundary = 0U; /* ACT 到期后等脉冲边界切段 */ + s_keep_freq_after_act = 0U; /* ACT 切段后保持当前频率衔接 */ + s_wait_time_expired = 0U; /* 段后 WAIT 时间到期请求 */ + s_waiting_for_input_signal = 0U; /* 段后等 WAIT/EXT 输入沿 */ /* s_wake_sem 在 OSInit 后由 WakeInit 创建 */ } @@ -200,21 +200,21 @@ uint8_t PlsrStart(uint16_t start_seg) { uint16_t n; uint16_t first_seg; - uint32_t f_chk; + uint32_t f_chk;/* 解析后的首段目标频率;此处仅作合法性检查,结果不用 */ if (g_plsr_busy != 0U) { return 0U; } - n = PlsrParamGetSegCount(); + n = PlsrParamGetSegCount();/*获取段的数量*/ if (n < 1U) { return 0U; } if ((start_seg < 1U) || (start_seg > n)) { - start_seg = PlsrParamGetStartSeg(); + start_seg = PlsrParamGetStartSeg();/*获取起始段*/ } first_seg = (uint16_t)(start_seg - 1U); @@ -226,20 +226,20 @@ uint8_t PlsrStart(uint16_t start_seg) PlsrCommandSetFault(PLSR_ERR_FREQ_ILLEGAL); return 0U; } - s_continue_without_stopping = 0U; - s_next_seg_start_freq_valid = 0U; - s_next_seg_start_freq_hz = 0U; + s_continue_without_stopping = 0U;/* 清段间不停表衔接标志 */ + s_next_seg_start_freq_valid = 0U;/* 清段间衔接频率有效标志 */ + s_next_seg_start_freq_hz = 0U;/*段间衔接频率置零*/ /* * 绝对原点:仅在首次 Start(或 ClearAccPulse 之后的第一次)锁定。 * 相对跑完再切绝对,仍相对「第一次启动时刻」坐标,不以当前位置重定原点。 */ if (s_absolute_origin_locked == 0U) { - s_absolute_origin = g_plsr_accumulated_pulses; - s_absolute_origin_locked = 1U; + s_absolute_origin = g_plsr_accumulated_pulses;/*已经累计的脉冲*/ + s_absolute_origin_locked = 1U;/*绝对原点锁定标志*/ } - PlsrSignalIoClearEdges(); - PlsrRunControlBeginSeg(first_seg); + PlsrSignalIoClearEdges();/*清除io信号边沿*/ + PlsrRunControlBeginSeg(first_seg);/*根据段号开一段*/ return 1U; } @@ -290,7 +290,7 @@ uint8_t PlsrChangeFreq(uint32_t new_tgt_hz) g_plsr_config.accel_ms, g_plsr_config.decel_ms); s_seg_pulse_target = (int32_t)remain; s_seg_pulses_done = 0; - PlsrRunControlRefreshProfile(0U); + PlsrRunControlRefreshProfile(0U);/*刷新下一拍频率*/ return 1U; } @@ -313,15 +313,17 @@ void PlsrRunControlRestoreAccPulse(int32_t acc_pulse) /** @brief 毫秒任务节拍 */ void PlsrRunControlTickMs(void) { + /* act时间到期或者act切段后需要保持频率*/ if (s_act_expired != 0U) { s_act_expired = 0U; if ((s_state == RC_RUN) || (s_keep_freq_after_act != 0U)) { - PlsrRunControlActExpire(); + PlsrRunControlActExpire();/*act时间到期处理函数*/ } return; } + /*wait时间到期,清标志位,规划下一段*/ if (s_wait_time_expired != 0U) { s_wait_time_expired = 0U; @@ -331,28 +333,29 @@ void PlsrRunControlTickMs(void) } return; } + /*方向延时直接等待*/ if (s_state == RC_DIR_WAIT) { /* 精确延时只靠 TIM5;此处占位,避免任务空转改状态 */ return; } - + /*运行态先处理改频请求,如果时EXT/EXT或脉冲发送完成,需要读取下降沿*/ if (s_state == RC_RUN) { - PlsrPulseDriverApplyPending(); + PlsrPulseDriverApplyPending();//消费挂起改频 if ((g_plsr_segs[g_plsr_cur_seg_idx].wait_type == PLSR_WAIT_EXT) || (g_plsr_segs[g_plsr_cur_seg_idx].wait_type == PLSR_WAIT_EXT_OR_DONE)) { if (PlsrSignalIoTakeExtFalling() != 0U) { - PlsrRunControlCutSegToNext(); + PlsrRunControlCutSegToNext();/*EXT信号触发切段*/ return; } } return; } - + /*等待条件状态要读取下降沿,去下一段或者结束*/ if (s_state == RC_WAIT_COND) { if (s_waiting_for_input_signal != 0U) @@ -385,9 +388,9 @@ void PlsrRunControlOnDelayTimer(void) if (s_state == RC_DIR_WAIT) { s_state = RC_RUN; - PlsrRunControlRefreshProfile(1U); - PlsrRunControlArmActExtOnPulseStart(); - PlsrRunControlWakePost(); + PlsrRunControlRefreshProfile(1U);/*刷新频率*/ + PlsrRunControlArmActExtOnPulseStart();/*开始输出时:EXT 类清旧沿;ACT 类启动段内定时 */ + PlsrRunControlWakePost();/*释放信号量,唤醒plsr任务*/ return; } @@ -686,7 +689,7 @@ static void PlsrRunControlBeginSeg(uint16_t seg_idx) uint32_t f_tgt; uint32_t total; PlsrSegPlanEndpoints_t endpoints; - + /*如果段号大于总段数,直接结束输出*/ if (seg_idx >= PlsrParamGetSegCount()) { PlsrRunControlFinishAll(); @@ -694,9 +697,10 @@ static void PlsrRunControlBeginSeg(uint16_t seg_idx) } g_plsr_cur_seg_idx = seg_idx; - s_waiting_for_last_period = 0U; - cnt = g_plsr_segs[seg_idx].pulse_cnt; + s_waiting_for_last_period = 0U;/* 等末拍 UPDATE 再收尾标志 */ + cnt = g_plsr_segs[seg_idx].pulse_cnt;/*读取总脉冲数*/ + /*读取运行模式,绝对模式以启动位置为绝对原点*/ if (g_plsr_config.run_mode == PLSR_POS_ABSOLUTE) { /* 以首次启动锁定原点:move = 段目标 − 相对原点位置 */ @@ -704,7 +708,7 @@ static void PlsrRunControlBeginSeg(uint16_t seg_idx) } else { - move = cnt; + move = cnt;/*行对模式下位移量=脉冲数*/ } if (move == 0) @@ -713,14 +717,14 @@ static void PlsrRunControlBeginSeg(uint16_t seg_idx) g_plsr_busy = 1U; s_seg_pulse_target = 0; s_seg_pulses_done = 0; - PlsrRunControlAfterSegDone(); + PlsrRunControlAfterSegDone();/*段正常结束*/ return; } if (move >= 0) { - s_forward = 1U; - s_seg_pulse_target = move; + s_forward = 1U;/*设置方向标志,正向1,反向0*/ + s_seg_pulse_target = move;/*脉冲目标数=移动量*/ } else { @@ -732,11 +736,11 @@ static void PlsrRunControlBeginSeg(uint16_t seg_idx) if (move == (int32_t)(-2147483647L - 1L)) { PlsrCommandSetFault(PLSR_ERR_PULSE_RANGE); - PlsrRunControlFinishAll(); + PlsrRunControlFinishAll();/*全段结束*/ return; } - s_forward = 0U; - s_seg_pulse_target = -move; + s_forward = 0U;/* 反向移动 */ + s_seg_pulse_target = -move;/* 移动量负脉冲个数 */ } /* 0x04:本段(或默认速度)频率非法 */ @@ -752,10 +756,13 @@ static void PlsrRunControlBeginSeg(uint16_t seg_idx) (void)PlsrRunControlResolveSegPlanEndpoints(seg_idx, f_tgt, &endpoints); total = (uint32_t)s_seg_pulse_target; + + /*规划本段并锁 PSC / 进初始相*/ PlsrRunControlPlanSeg(total, endpoints.freq_start_hz, f_tgt, endpoints.freq_end_hz, endpoints.accel_ms, endpoints.decel_ms); - s_seg_pulses_done = 0; - g_plsr_busy = 1U; + + s_seg_pulses_done = 0;/*已发脉冲数清零*/ + g_plsr_busy = 1U;/*运行状态置1*/ { /* 用本段结束后的坐标判 keep,与 AfterSegDone 一致;结果锁进 s_stop_after_last_pulse */ int32_t end_pos = PlsrRunControlAbsLocalPos(); @@ -774,43 +781,48 @@ static void PlsrRunControlBeginSeg(uint16_t seg_idx) if (total == 0U) { - PlsrRunControlAfterSegDone(); + PlsrRunControlAfterSegDone();/*单段正常结束*/ return; } - + + /*段间不停表衔接(后续模式/ACT切段)*/ if (s_continue_without_stopping != 0U) { /* 分支 A:段间无缝(后续模式或 ACT切段) */ - PlsrPulseDriverClearOnePulseStop(); + PlsrPulseDriverClearOnePulseStop();/*清掉单脉冲停止*/ /* * 必须先 RC_RUN 再 RefreshProfile/Start:否则冷启动首拍 UPDATE 时 * OnPulseIsr 仍见非 RUN 直接 return,影子停在起跳频,第 1、2 拍同频。 */ s_state = RC_RUN; - s_continue_without_stopping = 0U; + s_continue_without_stopping = 0U;/*段间不停表标志置0*/ /* * FOLLOW 真不停表:do_start=0 只改频。 * ACT 经 OPM 边界停表后 g_plsr_pwm_running 已为 0:须 Start 重开,否则无脉冲卡死。 - */ + * 1需要开始pwm输出,0已经在运行。只刷新下一拍频率*/ PlsrRunControlRefreshProfile((g_plsr_pwm_running == 0U) ? 1U : 0U); + /*开始输出时:EXT 类清旧沿;ACT 类启动段内定时 */ PlsrRunControlArmActExtOnPulseStart(); } else if ((g_plsr_direction_valid != 0U) && (s_forward == g_plsr_direction_forward)) { /* 分支 B:真换向但本段与上一段同向,方向脚已正确,跳过延时 */ - PlsrPulseDriverSetDir(s_forward); + PlsrPulseDriverSetDir(s_forward);/*跳过方向延时*/ s_state = RC_RUN; - PlsrRunControlRefreshProfile(1U); + PlsrRunControlRefreshProfile(1U);/*传1,已运行,只刷新频率*/ + /*开始输出时:EXT 类清旧沿;ACT 类启动段内定时 */ PlsrRunControlArmActExtOnPulseStart(); } else { /* 分支 C:需要换向或首次开跑 — 先打方向,再决定立刻开或 DIR_WAIT */ - PlsrPulseDriverSetDir(s_forward); + PlsrPulseDriverSetDir(s_forward);/*设置方向*/ if (g_plsr_config.dir_delay_ms == 0U) { s_state = RC_RUN; + /*传1,已运行,只刷新频率*/ PlsrRunControlRefreshProfile(1U); + /*开始输出时:EXT 类清旧沿;ACT 类启动段内定时 */ PlsrRunControlArmActExtOnPulseStart(); } else @@ -820,9 +832,11 @@ static void PlsrRunControlBeginSeg(uint16_t seg_idx) */ s_state = RC_DIR_WAIT; PlsrRunControlWakeDrain(); + /*设置方向延时*/ PlsrSignalIoScheduleDelayMs((uint32_t)g_plsr_config.dir_delay_ms); if (g_plsr_accel_runtime.cur_freq_hz >= 1U) { + /*换向延时期间预装寄存器、CEN 保持关 */ PlsrPulseDriverPrepare(g_plsr_accel_runtime.cur_freq_hz); } } @@ -941,18 +955,21 @@ static void PlsrRunControlArmActExtOnPulseStart(void) { uint16_t act_time_ms; + /*EXT信号/EXT或脉冲发送完成,清掉X4,X5信号的边沿,防止误触*/ if ((g_plsr_segs[g_plsr_cur_seg_idx].wait_type == PLSR_WAIT_EXT) || (g_plsr_segs[g_plsr_cur_seg_idx].wait_type == PLSR_WAIT_EXT_OR_DONE)) { PlsrSignalIoClearEdges(); } - s_act_timer_armed = 0U; - s_act_expired = 0U; - s_act_waiting_for_pulse_boundary = 0U; - s_keep_freq_after_act = 0U; - s_wait_time_expired = 0U; + /*清掉ACT定时的相关标志*/ + s_act_timer_armed = 0U;/*启用定时器*/ + s_act_expired = 0U;/*act定时到期*/ + s_act_waiting_for_pulse_boundary = 0U;/*等待脉冲边界*/ + s_keep_freq_after_act = 0U;/*act切断后保持频率*/ + s_wait_time_expired = 0U;/*wait时间到期标志*/ + /*act时间切段置标志位,开定时*/ if (g_plsr_segs[g_plsr_cur_seg_idx].wait_type == PLSR_WAIT_ACT) { act_time_ms = g_plsr_segs[g_plsr_cur_seg_idx].act_ms; @@ -994,9 +1011,9 @@ static void PlsrRunControlActExpire(void) s_act_expired = 0U; s_wait_time_expired = 0U; s_state = RC_IDLE; - + /*同向且有有效频率则不停表衔接,否则停表清链,传入1需要频率衔接*/ PlsrRunControlApplyKeepOrStop(1U); - s_keep_freq_after_act = 0U; + s_keep_freq_after_act = 0U;/*保持频率衔接标志位置0*/ PlsrRunControlGotoNextOrFinish(g_plsr_cur_seg_idx); } @@ -1063,7 +1080,7 @@ static void PlsrRunControlEnterPostWaitOrNext(void) } /** - * @brief 段正常结束:诊断 → 链式频率 → FOLLOW keep 或停表 → EnterPostWaitOrNext + * @brief 单段正常结束:诊断 → 链式频率 → FOLLOW keep 或停表 → EnterPostWaitOrNext */ static void PlsrRunControlAfterSegDone(void) { @@ -1210,8 +1227,8 @@ static void PlsrRunControlOnApproachDone(void) /** * 解析段目标频率。 - * freq_hz==0 用公共默认速度;结果须落在 [1, 100000],否则返回 0(调用方写 0x04)。 - */ + * freq_hz==0 用返回default_freq;结果须落在 [1, 100000],否则返回 0(调用方写 0x04)。 + * 返回1/0表示频率能不能用,能用返回1,不能用返回0*/ static uint8_t PlsrRunControlGetSegTargetFreq(int32_t freq_hz, uint32_t default_spd, uint32_t *out_hz) @@ -1220,22 +1237,22 @@ static uint8_t PlsrRunControlGetSegTargetFreq(int32_t freq_hz, if (freq_hz < 0) { - return 0U; + return 0U;/*频率小于0,直接结束*/ } if (freq_hz == 0) { - f = default_spd; + f = default_spd;/*频率为零,替换为默认速度*/ } else { - f = (uint32_t)freq_hz; + f = (uint32_t)freq_hz;/*频率不为零,替换为传入的频率*/ } /* 合法范围:1Hz ~ 100kHz(含) */ if ((f < 1U) || (f > 100000U)) { - return 0U; + return 0U;/*频率范围不合法直接结束*/ } - *out_hz = f; + *out_hz = f;/*将最终的频率传回去*/ return 1U; } @@ -1409,7 +1426,7 @@ static void PlsrRunControlEnterConstHoldIsr(void) } /** - * 任务侧:按当前段内相 s_phase,决定开表/改频用哪个频率。 + * 任务侧:按当前段内相 s_phase,决定开表/改频用哪个频率。刷新频率 * @param do_start 1=需要 Start PWM(RefreshProfile(1));0=已在跑只改频 */ static void PlsrRunControlRefreshProfile(uint8_t do_start) @@ -1507,14 +1524,14 @@ static uint8_t PlsrRunControlResolveSegPlanEndpoints(uint16_t seg_idx, uint32_t endpoints->accel_ms = g_plsr_config.accel_ms; endpoints->decel_ms = g_plsr_config.decel_ms; - if ((s_continue_without_stopping != 0U) && (g_plsr_output_freq_hz >= 1U)) - { - endpoints->freq_start_hz = g_plsr_output_freq_hz; - } - else if ((g_plsr_pwm_running != 0U) && (g_plsr_output_freq_hz >= 1U)) + /*不停表衔接且输出频率>1或者下一段运行中,下一段的起始频率为当前输出频率*/ + if (((s_continue_without_stopping != 0U) || (g_plsr_pwm_running != 0U)) + && (g_plsr_output_freq_hz >= 1U)) { endpoints->freq_start_hz = g_plsr_output_freq_hz; } + + /*如果下一段的起始频率有效且>1,下一段的起始频率为起始频率 */ else if ((s_next_seg_start_freq_valid != 0U) && (s_next_seg_start_freq_hz >= 1U)) { /* 完成模式段末停表后:用本段落地频作起速(如 EXT_OR_DONE 的匀速峰值) */ @@ -1596,6 +1613,7 @@ static void PlsrRunControlPlanSeg(uint32_t total, uint32_t f_from, uint32_t f_min; uint32_t f_max; + /*传给曲线规划模块进行曲线规划*/ PlsrAccelCurvePlan(&g_plsr_accel_plan, total, f_from, @@ -1616,7 +1634,7 @@ static void PlsrRunControlPlanSeg(uint32_t total, uint32_t f_from, PlsrCommandSetFault(PLSR_ERR_FREQ_UNREACH); } - g_plsr_accel_runtime.total_pulses = 0U; + g_plsr_accel_runtime.total_pulses = 0U;/*开始运行前当前相计划步进的脉冲数清零*/ /* S/正弦:在任务上下文预建频率表,ISR 只查表 */ PlsrAccelPrebuildFreqTables(&g_plsr_accel_plan); @@ -1629,46 +1647,50 @@ static void PlsrRunControlPlanSeg(uint32_t total, uint32_t f_from, /* 本段可能出现的最低/最高频率,取 入口、目标、出口 三者的 min/max */ f_min = g_plsr_accel_plan.target_freq_hz; f_max = g_plsr_accel_plan.target_freq_hz; + /*先找入口的最大最小频率*/ if (f_start > f_max) { - f_max = f_start; + f_max = f_start;/*起始频率大于目标频率时,最大频率用起始频率*/ } if (f_start >= 1U) { if (f_start < f_min) { - f_min = f_start; + f_min = f_start;/*起始频率小于目标频率,最小频率使用起始频率*/ } } else { - f_min = 1U; + f_min = 1U;/* 否则最小频率为1 */ } + + /*找出口的最大最小频率*/ if (g_plsr_accel_plan.end_freq_hz > f_max) { - f_max = g_plsr_accel_plan.end_freq_hz; + f_max = g_plsr_accel_plan.end_freq_hz;/*出口频率大于最大值,则成为最大值*/ } if (g_plsr_accel_plan.end_freq_hz >= 1U) { if (g_plsr_accel_plan.end_freq_hz < f_min) { - f_min = g_plsr_accel_plan.end_freq_hz; + f_min = g_plsr_accel_plan.end_freq_hz;/*出口频率小于小值,则成为最小值*/ } } else { if (f_min > 1U) { - f_min = 1U; + f_min = 1U;/* 否则,最小值为1 */ } } + if (f_min < 1U) { - f_min = 1U; + f_min = 1U;/*如果最小值小于1,则最小值改为1*/ } if (f_max < f_min) { - f_max = f_min; + f_max = f_min;/*如果找出来的最大值小于最小值,让最大值等于最小值*/ } /* 后续同向不停表时 PWM 仍在跑:禁止重锁 PSC */ if (g_plsr_pwm_running == 0U) @@ -1687,12 +1709,12 @@ static void PlsrRunControlPlanSeg(uint32_t total, uint32_t f_from, } else if (f_start == g_plsr_accel_plan.target_freq_hz) { - s_phase = PH_CONST; + s_phase = PH_CONST;/*匀速段*/ PlsrAccelBeginConstSpeed(&g_plsr_accel_runtime, &g_plsr_accel_plan); } else { - s_phase = PH_APPROACH; + s_phase = PH_APPROACH;/*加速段*/ PlsrAccelBeginAccel(&g_plsr_accel_runtime, &g_plsr_accel_plan); } }