|
@@ -29,8 +29,6 @@ uint8_t g_plsr_ext_event_flag = 0; // 外部事件标志 |
|
|
|
|
|
|
|
|
// ==================== PLSR内部变量 ==================== |
|
|
// ==================== PLSR内部变量 ==================== |
|
|
static uint32_t s_tim6_update_freq_us = 1000; // TIM6更新频率(微秒) |
|
|
static uint32_t s_tim6_update_freq_us = 1000; // TIM6更新频率(微秒) |
|
|
static uint32_t s_current_pwm_freq = 0; // 当前PWM频率 |
|
|
|
|
|
static uint8_t s_pwm_running = 0; // PWM运行状态 |
|
|
|
|
|
// static uint32_t s_target_pulse_count = 0; // 目标脉冲计数 - 暂时注释掉未使用的变量 |
|
|
// static uint32_t s_target_pulse_count = 0; // 目标脉冲计数 - 暂时注释掉未使用的变量 |
|
|
|
|
|
|
|
|
// ==================== 等待时间相关变量 ==================== |
|
|
// ==================== 等待时间相关变量 ==================== |
|
@@ -46,15 +44,7 @@ static volatile uint8_t s_freq_update_pending = 0; // 频率更新挂起标志 |
|
|
static volatile uint16_t s_next_prescaler = 0; // 下一个预分频器值 |
|
|
static volatile uint16_t s_next_prescaler = 0; // 下一个预分频器值 |
|
|
static volatile uint32_t s_next_period = 0; // 下一个周期值 |
|
|
static volatile uint32_t s_next_period = 0; // 下一个周期值 |
|
|
static volatile uint8_t s_task_notification_flag = 0; // 任务通知标志 |
|
|
static volatile uint8_t s_task_notification_flag = 0; // 任务通知标志 |
|
|
static uint32_t s_pulse_check_counter = 0; // 脉冲检查计数器 |
|
|
|
|
|
// ==================== PLSR辅助函数声明 ==================== |
|
|
|
|
|
static void PLSR_Section_StartNewSection(PLSR_RouteConfig_t* route); |
|
|
|
|
|
static void PLSR_Accel_CalculateSteps(PLSR_RouteConfig_t* route, uint32_t time_ms, uint8_t is_accel); |
|
|
|
|
|
static void PLSR_Section_ProcessConstSpeed(PLSR_RouteConfig_t* route); |
|
|
|
|
|
static void PLSR_Section_ProcessWait(PLSR_RouteConfig_t* route); |
|
|
|
|
|
static uint8_t PLSR_Section_CheckPulseComplete(PLSR_RouteConfig_t* route); |
|
|
|
|
|
static void PLSR_Section_CheckTransition(PLSR_RouteConfig_t* route); |
|
|
|
|
|
static void PLSR_CalculateTimerParams(uint32_t frequency, uint16_t* prescaler, uint32_t* period); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== PLSR等待条件处理函数实现 ==================== |
|
|
// ==================== PLSR等待条件处理函数实现 ==================== |
|
|
|
|
|
|
|
@@ -104,7 +94,7 @@ void PLSR_Wait_StartTimer(PLSR_RouteConfig_t* route) |
|
|
* @retval 1: 时间到达, 0: 时间未到 |
|
|
* @retval 1: 时间到达, 0: 时间未到 |
|
|
* @note 检查WAIT_TIME条件是否满足 |
|
|
* @note 检查WAIT_TIME条件是否满足 |
|
|
*/ |
|
|
*/ |
|
|
uint8_t PLSR_Wait_CheckTimeCondition(PLSR_RouteConfig_t* route) |
|
|
|
|
|
|
|
|
uint8_t PLSR_Wait_CheckTime(PLSR_RouteConfig_t* route) |
|
|
{ |
|
|
{ |
|
|
if (route == NULL) return 0; |
|
|
if (route == NULL) return 0; |
|
|
|
|
|
|
|
@@ -120,27 +110,6 @@ uint8_t PLSR_Wait_CheckTimeCondition(PLSR_RouteConfig_t* route) |
|
|
return 0; // 等待时间未到 |
|
|
return 0; // 等待时间未到 |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @brief 检查ACT时间条件 |
|
|
|
|
|
* @param route: 路径控制结构体指针 |
|
|
|
|
|
* @retval 1: ACT时间到达, 0: ACT时间未到 |
|
|
|
|
|
* @note 检查ACT_TIME条件是否满足 |
|
|
|
|
|
*/ |
|
|
|
|
|
uint8_t PLSR_Wait_CheckActTime(PLSR_RouteConfig_t* route) |
|
|
|
|
|
{ |
|
|
|
|
|
if (route == NULL) return 0; |
|
|
|
|
|
|
|
|
|
|
|
// 检查ACT时间标志位 |
|
|
|
|
|
if (s_act_time_flag) { |
|
|
|
|
|
// 清除标志位和停止计时器 |
|
|
|
|
|
s_act_time_flag = 0; |
|
|
|
|
|
s_act_time_target = 0; |
|
|
|
|
|
PLSR_TIM6_Stop(); |
|
|
|
|
|
return 1; // ACT时间已到 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return 0; // ACT时间未到 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* @brief 检查外部事件条件 |
|
|
* @brief 检查外部事件条件 |
|
@@ -199,7 +168,7 @@ void PLSR_SetSectionCondition(PLSR_RouteConfig_t* route, uint8_t section_num, ui |
|
|
* @param None |
|
|
* @param None |
|
|
* @retval 系统时钟计数(ms) |
|
|
* @retval 系统时钟计数(ms) |
|
|
*/ |
|
|
*/ |
|
|
uint32_t PLSR_GetSystemTick(void) |
|
|
|
|
|
|
|
|
uint32_t PLSR_GetWaitTick(void) |
|
|
{ |
|
|
{ |
|
|
return s_wait_time_counter; |
|
|
return s_wait_time_counter; |
|
|
} |
|
|
} |
|
@@ -221,66 +190,6 @@ uint8_t PLSR_CheckTaskNotification(void) |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @brief 任务级段处理函数 |
|
|
|
|
|
* @param route 路径控制结构体指针 |
|
|
|
|
|
* |
|
|
|
|
|
* 该函数在UCOSII任务中调用,负责处理段切换逻辑。 |
|
|
|
|
|
* 与中断级的频率更新分离,避免中断处理时间过长。 |
|
|
|
|
|
*/ |
|
|
|
|
|
void PLSR_Task_SectionProcess(PLSR_RouteConfig_t* route) |
|
|
|
|
|
{ |
|
|
|
|
|
// 参数有效性检查 |
|
|
|
|
|
if (route == NULL) return; |
|
|
|
|
|
if (route->route_state != PLSR_ROUTE_RUNNING) return; |
|
|
|
|
|
|
|
|
|
|
|
// 段号有效性检查 |
|
|
|
|
|
if (route->current_section_num == 0 || route->current_section_num > PLSR_MAX_SECTIONS) { |
|
|
|
|
|
PLSR_Route_Stop(route); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 处理特殊等待条件(ACT_TIME和EXT_EVENT需要实时处理) |
|
|
|
|
|
if(route->section[route->current_section_num-1].wait_condition.wait_type == PLSR_WAIT_ACT_TIME |
|
|
|
|
|
|| route->section[route->current_section_num-1].wait_condition.wait_type == PLSR_WAIT_EXT_EVENT) |
|
|
|
|
|
{ |
|
|
|
|
|
PLSR_Section_ProcessWait(route); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 根据当前运行状态执行相应的处理逻辑 |
|
|
|
|
|
switch (route->run_state) |
|
|
|
|
|
{ |
|
|
|
|
|
case PLSR_STATE_IDLE: |
|
|
|
|
|
// 空闲状态:开始新段处理 |
|
|
|
|
|
PLSR_Section_StartNewSection(route); |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case PLSR_STATE_ACCEL: |
|
|
|
|
|
// 加速状态:加速处理在TIM10中断中进行,任务中只检查状态转换 |
|
|
|
|
|
PLSR_Section_CheckTransition(route); |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case PLSR_STATE_CONST: |
|
|
|
|
|
// 匀速状态:保持目标频率运行 |
|
|
|
|
|
PLSR_Section_ProcessConstSpeed(route); |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case PLSR_STATE_DECEL: |
|
|
|
|
|
// 减速状态:减速处理在TIM10中断中进行,任务中只检查状态转换 |
|
|
|
|
|
PLSR_Section_CheckTransition(route); |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case PLSR_STATE_WAIT: |
|
|
|
|
|
// 等待状态:处理等待条件 |
|
|
|
|
|
PLSR_Section_ProcessWait(route); |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
|
// 未知状态:重置为空闲状态 |
|
|
|
|
|
route->run_state = PLSR_STATE_IDLE; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 辅助函数声明已在文件开头声明 |
|
|
// 辅助函数声明已在文件开头声明 |
|
|
|
|
|
|
|
@@ -816,9 +725,6 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle) |
|
|
*/ |
|
|
*/ |
|
|
void PLSR_PWM_Init(void) |
|
|
void PLSR_PWM_Init(void) |
|
|
{ |
|
|
{ |
|
|
// PWM初始化已在MX_TIM10_Init中完成 |
|
|
|
|
|
s_current_pwm_freq = 0; |
|
|
|
|
|
s_pwm_running = 0; |
|
|
|
|
|
|
|
|
|
|
|
MX_TIM10_Init(); |
|
|
MX_TIM10_Init(); |
|
|
MX_TIM11_Init(); |
|
|
MX_TIM11_Init(); |
|
@@ -841,15 +747,13 @@ void PLSR_PWM_Init(void) |
|
|
*/ |
|
|
*/ |
|
|
void PLSR_PWM_Start(void) |
|
|
void PLSR_PWM_Start(void) |
|
|
{ |
|
|
{ |
|
|
if (!s_pwm_running) |
|
|
|
|
|
|
|
|
if (g_plsr_route.run_state == PLSR_ROUTE_RUNNING) //<只有在路径运行状态下才可以进行pwm输出 |
|
|
{ |
|
|
{ |
|
|
// 启动PWM输出和更新中断 |
|
|
// 启动PWM输出和更新中断 |
|
|
HAL_TIM_PWM_Start_IT(&htim10, TIM_CHANNEL_1); |
|
|
HAL_TIM_PWM_Start_IT(&htim10, TIM_CHANNEL_1); |
|
|
|
|
|
|
|
|
// 启动TIM2脉冲计数器 |
|
|
// 启动TIM2脉冲计数器 |
|
|
PLSR_Counter_Start(); |
|
|
PLSR_Counter_Start(); |
|
|
|
|
|
|
|
|
s_pwm_running = 1; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -861,46 +765,34 @@ void PLSR_PWM_Start(void) |
|
|
*/ |
|
|
*/ |
|
|
void PLSR_PWM_Stop(void) |
|
|
void PLSR_PWM_Stop(void) |
|
|
{ |
|
|
{ |
|
|
if (s_pwm_running) { |
|
|
|
|
|
|
|
|
if (g_plsr_route.run_state == PLSR_ROUTE_COMPLETED) |
|
|
|
|
|
{ |
|
|
// 停止PWM输出 |
|
|
// 停止PWM输出 |
|
|
HAL_TIM_PWM_Stop(&htim10, TIM_CHANNEL_1); |
|
|
HAL_TIM_PWM_Stop(&htim10, TIM_CHANNEL_1); |
|
|
|
|
|
|
|
|
// 停止TIM2计数器 |
|
|
// 停止TIM2计数器 |
|
|
HAL_TIM_Base_Stop(&htim2); // TIM2恢复用于脉冲计数 |
|
|
HAL_TIM_Base_Stop(&htim2); // TIM2恢复用于脉冲计数 |
|
|
|
|
|
|
|
|
s_pwm_running = 0; |
|
|
|
|
|
s_current_pwm_freq = 0; |
|
|
|
|
|
|
|
|
g_plsr_route.run_state = PLSR_ROUTE_IDLE; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* @brief 计算定时器参数 |
|
|
|
|
|
* @param frequency: 目标频率(Hz) |
|
|
|
|
|
* @param prescaler: 预分频器值指针 |
|
|
|
|
|
* @param period: 周期值指针 |
|
|
|
|
|
* @retval None |
|
|
|
|
|
* @note 根据目标频率计算TIM10的预分频器和周期值 |
|
|
|
|
|
|
|
|
* @brief 立即设置PWM频率(直接更新,用于初始化) |
|
|
|
|
|
* @param frequency 目标频率(Hz) |
|
|
*/ |
|
|
*/ |
|
|
static void PLSR_CalculateTimerParams(uint32_t frequency, uint16_t* prescaler, uint32_t* period) |
|
|
|
|
|
|
|
|
void PLSR_PWM_SetFrequency(uint32_t frequency) |
|
|
{ |
|
|
{ |
|
|
// STM32F4系列定时器时钟频率(通常为84MHz,具体取决于系统配置) |
|
|
|
|
|
|
|
|
uint16_t prescaler = 0; // 预分频器值 |
|
|
|
|
|
uint32_t period = 0; // 自动重载值(周期) |
|
|
uint32_t timer_clock = 168000000; |
|
|
uint32_t timer_clock = 168000000; |
|
|
|
|
|
|
|
|
// 定时器频率计算原理: |
|
|
|
|
|
// 输出频率 = 定时器时钟频率 / ((预分频器 + 1) * (自动重装载值 + 1)) |
|
|
|
|
|
// 因此:(预分频器 + 1) * (自动重装载值 + 1) = 定时器时钟频率 / 目标频率 |
|
|
|
|
|
|
|
|
|
|
|
// 频率为0时停止PWM输出 |
|
|
|
|
|
if (frequency == 0) { |
|
|
|
|
|
PLSR_PWM_Stop(); // 直接停止PWM输出 |
|
|
|
|
|
*prescaler = 0; |
|
|
|
|
|
*period = 0; |
|
|
|
|
|
|
|
|
// 频率范围检查 |
|
|
|
|
|
if(frequency < PLSR_PWM_FREQ_MIN || frequency > PLSR_PWM_FREQ_MAX) |
|
|
|
|
|
{ |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 计算总的计数值:定时器时钟频率除以目标频率 |
|
|
|
|
|
|
|
|
// 计算总的计数值:定时器时钟频率除以目标频率 |
|
|
uint32_t total_count = timer_clock / frequency; |
|
|
uint32_t total_count = timer_clock / frequency; |
|
|
|
|
|
|
|
|
// 遍历所有可能的预分频器值,寻找合适的组合 |
|
|
// 遍历所有可能的预分频器值,寻找合适的组合 |
|
@@ -913,102 +805,16 @@ static void PLSR_CalculateTimerParams(uint32_t frequency, uint16_t* prescaler, u |
|
|
// 检查自动重装载值是否在有效范围内(1-65536,寄存器值0-65535) |
|
|
// 检查自动重装载值是否在有效范围内(1-65536,寄存器值0-65535) |
|
|
if (arr <= 65535 && arr >= 1) { |
|
|
if (arr <= 65535 && arr >= 1) { |
|
|
// 找到合适的组合,转换为寄存器值(实际值减1) |
|
|
// 找到合适的组合,转换为寄存器值(实际值减1) |
|
|
*prescaler = psc - 1; // 预分频器寄存器值 = 实际预分频值 - 1 |
|
|
|
|
|
*period = arr - 1; // 自动重装载寄存器值 = 实际重装载值 - 1 |
|
|
|
|
|
|
|
|
prescaler = psc - 1; // 预分频器寄存器值 = 实际预分频值 - 1 |
|
|
|
|
|
period = arr - 1; // 自动重装载寄存器值 = 实际重装载值 - 1 |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 如果找不到合适的值组合,使用默认的1kHz配置 |
|
|
|
|
|
// 预分频器 = 83 (实际分频84),自动重装载 = 999 (实际计数1000) |
|
|
|
|
|
// 输出频率 = 84MHz / (84 * 1000) = 1kHz |
|
|
|
|
|
*prescaler = 83; // 84MHz / 84 = 1MHz |
|
|
|
|
|
*period = 999; // 1MHz / 1000 = 1kHz |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @brief 设置PWM频率 |
|
|
|
|
|
* @param frequency: PWM频率 (1Hz-100kHz) |
|
|
|
|
|
* @retval None |
|
|
|
|
|
* @note 动态设置TIM10的PWM输出频率,占空比固定为50% |
|
|
|
|
|
*/ |
|
|
|
|
|
/** |
|
|
|
|
|
* @brief 设置PLSR PWM输出频率 |
|
|
|
|
|
* @param frequency 目标频率(Hz) |
|
|
|
|
|
* |
|
|
|
|
|
* 该函数负责动态设置TIM10的PWM输出频率,主要用于PLSR脉冲控制。 |
|
|
|
|
|
* 函数会自动计算最佳的定时器参数,并在不中断运行状态的情况下更新频率。 |
|
|
|
|
|
* |
|
|
|
|
|
* 处理流程: |
|
|
|
|
|
* 1. 频率范围检查 - 确保频率在允许范围内 |
|
|
|
|
|
* 2. 计算定时器参数 - 调用PLSR_CalculateTimerParams计算最佳预分频器和周期值 |
|
|
|
|
|
* 3. 状态保护 - 记录当前运行状态,必要时先停止PWM |
|
|
|
|
|
* 4. 参数更新 - 更新预分频器、自动重载值和比较值 |
|
|
|
|
|
* 5. 寄存器同步 - 重置计数器并触发更新事件 |
|
|
|
|
|
* 6. 状态恢复 - 如果之前在运行,重新启动PWM |
|
|
|
|
|
* 7. 记录更新 - 更新当前频率记录 |
|
|
|
|
|
*/ |
|
|
|
|
|
/** |
|
|
|
|
|
* @brief 安全设置PWM频率(通过中断更新) |
|
|
|
|
|
* @param frequency 目标频率(Hz) |
|
|
|
|
|
* |
|
|
|
|
|
* 该函数不直接更新定时器参数,而是设置待更新的参数, |
|
|
|
|
|
* 实际更新在TIM10中断中完成,确保原子性和波形连续性。 |
|
|
|
|
|
*/ |
|
|
|
|
|
void PLSR_PWM_SetFrequency(uint32_t frequency) |
|
|
|
|
|
{ |
|
|
|
|
|
uint16_t prescaler = 0; // 预分频器值 |
|
|
|
|
|
uint32_t period = 0; // 自动重载值(周期) |
|
|
|
|
|
|
|
|
|
|
|
// 频率范围检查 - 确保频率在1hz到100khz范围内 |
|
|
|
|
|
if(frequency < PLSR_PWM_FREQ_MIN || frequency > PLSR_PWM_FREQ_MAX) |
|
|
|
|
|
{ |
|
|
|
|
|
return; // 频率超出范围,直接返回,不做任何修改 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 计算最佳定时器参数 - 根据目标频率计算预分频器和周期值 |
|
|
|
|
|
PLSR_CalculateTimerParams(frequency, &prescaler, &period); |
|
|
|
|
|
|
|
|
|
|
|
// 设置待更新的参数(在中断中会检查并更新) |
|
|
|
|
|
s_next_prescaler = prescaler; |
|
|
|
|
|
s_next_period = period; |
|
|
|
|
|
|
|
|
|
|
|
// 设置更新挂起标志,中断中会检查此标志并执行更新 |
|
|
|
|
|
s_freq_update_pending = 1; |
|
|
|
|
|
|
|
|
|
|
|
// 更新当前频率记录 - 保存新的频率值供其他函数查询使用 |
|
|
|
|
|
s_current_pwm_freq = frequency; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @brief 立即设置PWM频率(直接更新,用于初始化) |
|
|
|
|
|
* @param frequency 目标频率(Hz) |
|
|
|
|
|
* |
|
|
|
|
|
* 该函数直接更新定时器参数,仅用于初始化或紧急情况。 |
|
|
|
|
|
* 正常运行时应使用PLSR_PWM_SetFrequency()。 |
|
|
|
|
|
*/ |
|
|
|
|
|
void PLSR_PWM_SetFrequency_Immediate(uint32_t frequency) |
|
|
|
|
|
{ |
|
|
|
|
|
uint16_t prescaler = 0; // 预分频器值 |
|
|
|
|
|
uint32_t period = 0; // 自动重载值(周期) |
|
|
|
|
|
|
|
|
|
|
|
// 频率范围检查 |
|
|
|
|
|
if(frequency < PLSR_PWM_FREQ_MIN || frequency > PLSR_PWM_FREQ_MAX) |
|
|
|
|
|
{ |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 计算定时器参数 |
|
|
|
|
|
PLSR_CalculateTimerParams(frequency, &prescaler, &period); |
|
|
|
|
|
|
|
|
|
|
|
// 直接更新定时器参数 |
|
|
// 直接更新定时器参数 |
|
|
__HAL_TIM_SET_PRESCALER(&htim10, prescaler); |
|
|
__HAL_TIM_SET_PRESCALER(&htim10, prescaler); |
|
|
__HAL_TIM_SET_AUTORELOAD(&htim10, period); |
|
|
__HAL_TIM_SET_AUTORELOAD(&htim10, period); |
|
|
__HAL_TIM_SET_COMPARE(&htim10, TIM_CHANNEL_1, period / 2); |
|
|
|
|
|
|
|
|
|
|
|
// 更新当前频率记录 |
|
|
|
|
|
s_current_pwm_freq = frequency; |
|
|
|
|
|
|
|
|
__HAL_TIM_SET_COMPARE(&htim10, TIM_CHANNEL_1, period / 2); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// ==================== PLSR TIM6频率配置函数实现 ==================== |
|
|
// ==================== PLSR TIM6频率配置函数实现 ==================== |
|
@@ -1082,102 +888,19 @@ void PLSR_TIM6_Stop(void) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @brief 获取当前PWM频率 |
|
|
|
|
|
* @param None |
|
|
|
|
|
* @retval 当前PWM频率(Hz) |
|
|
|
|
|
*/ |
|
|
|
|
|
uint32_t PLSR_PWM_GetFrequency(void) |
|
|
|
|
|
{ |
|
|
|
|
|
return s_current_pwm_freq; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @brief 设置PWM占空比 |
|
|
|
|
|
* @param duty_percent: 占空比百分比 (0-100) |
|
|
|
|
|
* @retval None |
|
|
|
|
|
*/ |
|
|
|
|
|
void PLSR_PWM_SetDutyCycle(uint8_t duty_percent) |
|
|
|
|
|
{ |
|
|
|
|
|
if (duty_percent > 100) duty_percent = 100; |
|
|
|
|
|
|
|
|
|
|
|
uint32_t period = __HAL_TIM_GET_AUTORELOAD(&htim10); |
|
|
|
|
|
uint32_t pulse = (period * duty_percent) / 100; |
|
|
|
|
|
|
|
|
|
|
|
__HAL_TIM_SET_COMPARE(&htim10, TIM_CHANNEL_1, pulse); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @brief 定时器周期结束中断回调函数 |
|
|
|
|
|
* @param htim 定时器句柄指针 |
|
|
|
|
|
* @note TIM6中断频率由PLSR_TIM6_SetUpdateFreq函数设置,直接影响加减速算法的执行精度 |
|
|
|
|
|
* @note 该函数在中断上下文中执行,应保持处理时间尽可能短 |
|
|
|
|
|
*/ |
|
|
|
|
|
// 全局变量用于TIM10中断与任务通信 |
|
|
|
|
|
// 频率更新相关静态变量已在文件开头声明 |
|
|
|
|
|
|
|
|
|
|
|
#define PLSR_TASK_CHECK_INTERVAL 100 // 每100个脉冲通知任务一次 |
|
|
|
|
|
|
|
|
|
|
|
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) |
|
|
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) |
|
|
{ |
|
|
{ |
|
|
// 检查中断源 - 处理TIM10的PWM更新中断 |
|
|
// 检查中断源 - 处理TIM10的PWM更新中断 |
|
|
if(htim->Instance == TIM10) |
|
|
if(htim->Instance == TIM10) |
|
|
{ |
|
|
{ |
|
|
// 1. 脉冲计数 - 每个PWM脉冲完成时计数 |
|
|
|
|
|
g_plsr_route.pulse_count++; |
|
|
g_plsr_route.pulse_count++; |
|
|
|
|
|
|
|
|
// 2. 加减速过程中的频率参数更新 |
|
|
|
|
|
if(g_plsr_route.run_state == PLSR_STATE_ACCEL || g_plsr_route.run_state == PLSR_STATE_DECEL) |
|
|
|
|
|
{ |
|
|
|
|
|
PLSR_Accel_Process(&g_plsr_route); // 在中断中进行加减速处理 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 3. 检查是否需要频率更新 |
|
|
|
|
|
if(s_freq_update_pending) |
|
|
|
|
|
{ |
|
|
|
|
|
// 原子性频率参数更新 |
|
|
|
|
|
__HAL_TIM_SET_PRESCALER(&htim10, s_next_prescaler); |
|
|
|
|
|
__HAL_TIM_SET_AUTORELOAD(&htim10, s_next_period); |
|
|
|
|
|
__HAL_TIM_SET_COMPARE(&htim10, TIM_CHANNEL_1, s_next_period / 2); |
|
|
|
|
|
|
|
|
|
|
|
// 清除更新标志 |
|
|
|
|
|
s_freq_update_pending = 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 4. 定期通知任务进行段处理 |
|
|
|
|
|
s_pulse_check_counter++; |
|
|
|
|
|
if(s_pulse_check_counter >= PLSR_TASK_CHECK_INTERVAL) |
|
|
|
|
|
{ |
|
|
|
|
|
s_pulse_check_counter = 0; |
|
|
|
|
|
s_task_notification_flag = 1; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// TIM6用于等待时间计时 |
|
|
// TIM6用于等待时间计时 |
|
|
if(htim->Instance == TIM6) |
|
|
if(htim->Instance == TIM6) |
|
|
{ |
|
|
{ |
|
|
// 等待时间计数器递增 |
|
|
|
|
|
if(s_wait_time_flag == 0 && s_wait_time_target > 0) |
|
|
|
|
|
{ |
|
|
|
|
|
uint32_t temp_counter = s_wait_time_counter + 1; |
|
|
|
|
|
s_wait_time_counter = temp_counter; |
|
|
|
|
|
if(temp_counter >= s_wait_time_target) |
|
|
|
|
|
{ |
|
|
|
|
|
s_wait_time_flag = 1; |
|
|
|
|
|
s_task_notification_flag = 1; // 通知任务进行段切换 |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(s_act_time_flag == 0 && s_act_time_target > 0) |
|
|
|
|
|
{ |
|
|
|
|
|
uint32_t temp_counter = s_act_time_counter + 1; |
|
|
|
|
|
s_act_time_counter = temp_counter; |
|
|
|
|
|
if(temp_counter >= s_act_time_target) |
|
|
|
|
|
{ |
|
|
|
|
|
s_act_time_flag = 1; |
|
|
|
|
|
s_task_notification_flag = 1; // 通知任务进行段切换 |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -1203,12 +926,11 @@ void PLSR_Route_Set(PLSR_RouteConfig_t* route) |
|
|
for (uint8_t i = 0; i < route->section_num; i++) |
|
|
for (uint8_t i = 0; i < route->section_num; i++) |
|
|
{ |
|
|
{ |
|
|
|
|
|
|
|
|
route->section[i].section_num = i+1; |
|
|
|
|
|
|
|
|
route->section[i].section_num = i + 1; |
|
|
route->section[i].target_freq = (((uint32_t)ModbusSlave.holding_regs[256+(6*i)]) | (uint32_t)ModbusSlave.holding_regs[257+(6*i)]<<16); |
|
|
route->section[i].target_freq = (((uint32_t)ModbusSlave.holding_regs[256+(6*i)]) | (uint32_t)ModbusSlave.holding_regs[257+(6*i)]<<16); |
|
|
route->section[i].target_pulse = (((uint32_t)ModbusSlave.holding_regs[258+(6*i)]) | (uint32_t)ModbusSlave.holding_regs[259+(6*i)]<<16); |
|
|
route->section[i].target_pulse = (((uint32_t)ModbusSlave.holding_regs[258+(6*i)]) | (uint32_t)ModbusSlave.holding_regs[259+(6*i)]<<16); |
|
|
route->section[i].wait_condition.wait_type = ModbusSlave.holding_regs[260+(6*i)]; |
|
|
route->section[i].wait_condition.wait_type = ModbusSlave.holding_regs[260+(6*i)]; |
|
|
route->section[i].next_section = ModbusSlave.holding_regs[261+(6*i)]; |
|
|
route->section[i].next_section = ModbusSlave.holding_regs[261+(6*i)]; |
|
|
route->section[i].section_state = PLSR_SECTION_IDLE; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -1241,16 +963,6 @@ void PLSR_Route_Init(PLSR_RouteConfig_t* route) |
|
|
/** |
|
|
/** |
|
|
* @brief 启动PLSR路径执行 |
|
|
* @brief 启动PLSR路径执行 |
|
|
* @param route 路径控制结构体指针 |
|
|
* @param route 路径控制结构体指针 |
|
|
* |
|
|
|
|
|
* 该函数负责启动PLSR路径的执行过程,从第一段开始按照预设的参数进行运动控制。 |
|
|
|
|
|
* 包括状态检查、参数初始化、硬件启动和第一段处理的完整启动流程。 |
|
|
|
|
|
* |
|
|
|
|
|
* 启动流程: |
|
|
|
|
|
* 1. 参数和状态检查 - 确保路径有效且未在运行 |
|
|
|
|
|
* 2. 路径状态初始化 - 设置运行状态和初始参数 |
|
|
|
|
|
* 3. 硬件资源启动 - 重置计数器,启动PWM和定时器 |
|
|
|
|
|
* 4. 第一段处理 - 立即开始处理第一段的运动逻辑 |
|
|
|
|
|
* |
|
|
|
|
|
* @note 如果起始频率为0,PWM不会启动,适用于等待外部触发的场景 |
|
|
* @note 如果起始频率为0,PWM不会启动,适用于等待外部触发的场景 |
|
|
*/ |
|
|
*/ |
|
|
void PLSR_Route_Start(PLSR_RouteConfig_t* route) |
|
|
void PLSR_Route_Start(PLSR_RouteConfig_t* route) |
|
@@ -1259,7 +971,8 @@ void PLSR_Route_Start(PLSR_RouteConfig_t* route) |
|
|
if (route == NULL) return; |
|
|
if (route == NULL) return; |
|
|
|
|
|
|
|
|
// 状态检查 - 避免重复启动 |
|
|
// 状态检查 - 避免重复启动 |
|
|
if (route->route_state == PLSR_ROUTE_RUNNING) return; |
|
|
|
|
|
|
|
|
if (route->route_state == PLSR_ROUTE_RUNNING) |
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
//启动时初始化用户可配置参数. |
|
|
//启动时初始化用户可配置参数. |
|
|
PLSR_Route_Set(route); |
|
|
PLSR_Route_Set(route); |
|
@@ -1268,6 +981,7 @@ void PLSR_Route_Start(PLSR_RouteConfig_t* route) |
|
|
route->current_section_num = route->start_section; //< 从起始段开始执行 |
|
|
route->current_section_num = route->start_section; //< 从起始段开始执行 |
|
|
route->current_freq = route->start_freq; //< 设置当前频率为起始频率 |
|
|
route->current_freq = route->start_freq; //< 设置当前频率为起始频率 |
|
|
route->pulse_count = 0; //< 清零脉冲计数 |
|
|
route->pulse_count = 0; //< 清零脉冲计数 |
|
|
|
|
|
route->run_state = PLSR_STATE_IDLE; //< 设置运行状态为空闲 |
|
|
|
|
|
|
|
|
// PWM输出初始化 - 根据起始频率决定是否启动 |
|
|
// PWM输出初始化 - 根据起始频率决定是否启动 |
|
|
if (route->start_freq > 0) { |
|
|
if (route->start_freq > 0) { |
|
@@ -1333,7 +1047,7 @@ void PLSR_Section_Process(PLSR_RouteConfig_t* route) |
|
|
if(route->section[route->current_section_num-1].wait_condition.wait_type == PLSR_WAIT_ACT_TIME |
|
|
if(route->section[route->current_section_num-1].wait_condition.wait_type == PLSR_WAIT_ACT_TIME |
|
|
||route->section[route->current_section_num-1].wait_condition.wait_type == PLSR_WAIT_EXT_EVENT) |
|
|
||route->section[route->current_section_num-1].wait_condition.wait_type == PLSR_WAIT_EXT_EVENT) |
|
|
{ |
|
|
{ |
|
|
PLSR_Section_ProcessWait(route); |
|
|
|
|
|
|
|
|
PLSR_ChackWait_End(route); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 根据当前运行状态执行相应的处理逻辑 |
|
|
// 根据当前运行状态执行相应的处理逻辑 |
|
@@ -1362,15 +1076,11 @@ void PLSR_Section_Process(PLSR_RouteConfig_t* route) |
|
|
// 根据减速算法逐步降低频率到目标值 |
|
|
// 根据减速算法逐步降低频率到目标值 |
|
|
PLSR_Accel_Process(route); |
|
|
PLSR_Accel_Process(route); |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case PLSR_STATE_WAIT: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case PLSR_STATE_WAIT: //脉冲发送完成/或停止都会被设为等待状态 |
|
|
// 等待状态:处理等待条件 |
|
|
// 等待状态:处理等待条件 |
|
|
// 检查时间、外部事件或其他等待条件是否满足 |
|
|
|
|
|
PLSR_Section_ProcessWait(route); |
|
|
|
|
|
|
|
|
PLSR_ChackWait_End(route); |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
default: |
|
|
// 未知状态:重置为空闲状态 |
|
|
// 未知状态:重置为空闲状态 |
|
|
route->run_state = PLSR_STATE_IDLE; |
|
|
route->run_state = PLSR_STATE_IDLE; |
|
@@ -1384,14 +1094,11 @@ void PLSR_Section_Process(PLSR_RouteConfig_t* route) |
|
|
* @retval None |
|
|
* @retval None |
|
|
* @note 初始化新段的参数并确定初始状态 |
|
|
* @note 初始化新段的参数并确定初始状态 |
|
|
*/ |
|
|
*/ |
|
|
static void PLSR_Section_StartNewSection(PLSR_RouteConfig_t* route) |
|
|
|
|
|
|
|
|
void PLSR_Section_StartNewSection(PLSR_RouteConfig_t* route) |
|
|
{ |
|
|
{ |
|
|
// 获取当前段的配置指针(段号从1开始,数组索引从0开始) |
|
|
// 获取当前段的配置指针(段号从1开始,数组索引从0开始) |
|
|
PLSR_SectionConfig_t* current_section = &route->section[route->current_section_num - 1]; |
|
|
PLSR_SectionConfig_t* current_section = &route->section[route->current_section_num - 1]; |
|
|
|
|
|
|
|
|
// 设置当前段状态为运行状态,标记段已开始执行 |
|
|
|
|
|
current_section->section_state = PLSR_SECTION_RUNNING; |
|
|
|
|
|
|
|
|
|
|
|
// 设置本段的目标频率到路径控制结构体中 |
|
|
// 设置本段的目标频率到路径控制结构体中 |
|
|
route->target_freq = current_section->target_freq; |
|
|
route->target_freq = current_section->target_freq; |
|
|
|
|
|
|
|
@@ -1436,11 +1143,10 @@ void PLSR_Section_SwitchNext(PLSR_RouteConfig_t* route) |
|
|
PLSR_SectionConfig_t* current_section = &route->section[route->current_section_num - 1]; |
|
|
PLSR_SectionConfig_t* current_section = &route->section[route->current_section_num - 1]; |
|
|
uint8_t next_section_num = current_section->next_section; |
|
|
uint8_t next_section_num = current_section->next_section; |
|
|
|
|
|
|
|
|
// 设置当前段状态为完成 |
|
|
|
|
|
current_section->section_state = PLSR_SECTION_COMPLETED; |
|
|
|
|
|
route->target_count += current_section->target_pulse; |
|
|
|
|
|
|
|
|
route->target_count += current_section->target_pulse; |
|
|
// 检查下一段是否有效 |
|
|
// 检查下一段是否有效 |
|
|
if (next_section_num == 0 || next_section_num > PLSR_MAX_SECTIONS) { |
|
|
|
|
|
|
|
|
if (next_section_num == 0 || next_section_num > PLSR_MAX_SECTIONS) |
|
|
|
|
|
{ |
|
|
// 路径结束 |
|
|
// 路径结束 |
|
|
route->route_state = PLSR_ROUTE_COMPLETED; |
|
|
route->route_state = PLSR_ROUTE_COMPLETED; |
|
|
PLSR_Route_Stop(route); |
|
|
PLSR_Route_Stop(route); |
|
@@ -1455,55 +1161,6 @@ void PLSR_Section_SwitchNext(PLSR_RouteConfig_t* route) |
|
|
route->current_freq = current_section->target_freq; |
|
|
route->current_freq = current_section->target_freq; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @brief 检查等待条件是否满足 |
|
|
|
|
|
* @param route: 路径控制结构体指针 |
|
|
|
|
|
* @retval 1: 条件满足, 0: 条件未满足 |
|
|
|
|
|
*/ |
|
|
|
|
|
uint8_t PLSR_Section_CheckWaitCondition(PLSR_RouteConfig_t* route) |
|
|
|
|
|
{ |
|
|
|
|
|
// 参数有效性检查:路径指针不能为空 |
|
|
|
|
|
if (route == NULL) return 0; |
|
|
|
|
|
|
|
|
|
|
|
// 获取当前段的配置和等待条件指针 |
|
|
|
|
|
PLSR_SectionConfig_t* current_section = &route->section[route->current_section_num - 1]; |
|
|
|
|
|
PLSR_WaitCondition_t* wait_cond = ¤t_section->wait_condition; |
|
|
|
|
|
|
|
|
|
|
|
// 根据等待条件类型进行相应的检查 |
|
|
|
|
|
switch (wait_cond->wait_type) { |
|
|
|
|
|
case PLSR_WAIT_PLUSEEND: |
|
|
|
|
|
|
|
|
|
|
|
return PLSR_Section_CheckPulseComplete(route); |
|
|
|
|
|
|
|
|
|
|
|
case PLSR_WAIT_TIME: |
|
|
|
|
|
// 等待指定时间条件:检查是否达到设定的等待时间 |
|
|
|
|
|
return PLSR_Wait_CheckTimeCondition(route); |
|
|
|
|
|
|
|
|
|
|
|
case PLSR_WAIT_CONDITION: |
|
|
|
|
|
// 等待条件标志:检查用户设置的条件标志位 |
|
|
|
|
|
// 该标志可通过PLSR_SetSectionCondition函数设置 |
|
|
|
|
|
return wait_cond->condition_flag; |
|
|
|
|
|
|
|
|
|
|
|
case PLSR_WAIT_ACT_TIME: |
|
|
|
|
|
// ACT时间条件:检查是否达到ACT(动作)时间 |
|
|
|
|
|
return PLSR_Wait_CheckActTime(route); |
|
|
|
|
|
|
|
|
|
|
|
case PLSR_WAIT_EXT_EVENT: |
|
|
|
|
|
// 外部事件条件:等待外部事件触发 |
|
|
|
|
|
// 外部事件可通过PLSR_SetExtEvent函数设置 |
|
|
|
|
|
return PLSR_Wait_CheckExtEvent(route); |
|
|
|
|
|
|
|
|
|
|
|
case PLSR_WAIT_EXT_OR_END: |
|
|
|
|
|
// 外部事件或脉冲结束:两个条件任一满足即可继续 |
|
|
|
|
|
// 这种模式允许外部事件提前结束段的执行 |
|
|
|
|
|
return (PLSR_Wait_CheckExtEvent(route) || 1); |
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
|
// 未知等待类型:默认返回真,允许继续执行 |
|
|
|
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* @brief 计算匀速段可发送的脉冲数 |
|
|
* @brief 计算匀速段可发送的脉冲数 |
|
|
* @param route: 路径控制结构体指针 |
|
|
* @param route: 路径控制结构体指针 |
|
@@ -1515,46 +1172,6 @@ void PLSR_Section_CalculateConstPulse(PLSR_RouteConfig_t* route) |
|
|
// 参数有效性检查:路径指针不能为空 |
|
|
// 参数有效性检查:路径指针不能为空 |
|
|
if (route == NULL) return; |
|
|
if (route == NULL) return; |
|
|
|
|
|
|
|
|
//// 获取当前段的配置指针 |
|
|
|
|
|
//PLSR_SectionConfig_t* current_section = &route->section[route->current_section_num - 1]; |
|
|
|
|
|
|
|
|
|
|
|
// 根据路径模式计算本段需要执行的总脉冲数 |
|
|
|
|
|
// uint32_t total_pulse; // 暂时注释掉未使用的变量 |
|
|
|
|
|
// if (route->mode == PLSR_MODE_RELATIVE) |
|
|
|
|
|
// { |
|
|
|
|
|
// // 相对模式:直接使用段配置中的目标脉冲数 |
|
|
|
|
|
// total_pulse = current_section->target_pulse; |
|
|
|
|
|
// } |
|
|
|
|
|
// else |
|
|
|
|
|
// { |
|
|
|
|
|
// // 绝对模式:计算从当前位置到目标位置需要的脉冲数 |
|
|
|
|
|
// // 如果目标位置已达到或超过,则无需发送脉冲 |
|
|
|
|
|
// total_pulse = (current_section->target_pulse > route->pulse_count) ? |
|
|
|
|
|
// (current_section->target_pulse - route->pulse_count) : 0; |
|
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
|
|
// // 计算加减速过程中消耗的脉冲数,方便计算何时进入匀速阶段 |
|
|
|
|
|
// //有问题,步数不等价于脉冲数. |
|
|
|
|
|
// uint32_t accel_decel_pulse = 0; |
|
|
|
|
|
// if (current_section->wait_condition.wait_type != PLSR_WAIT_PLUSEEND && |
|
|
|
|
|
// current_section->wait_condition.wait_type != PLSR_WAIT_EXT_OR_END) |
|
|
|
|
|
// { |
|
|
|
|
|
// // 加减速脉冲数 = 加速步数 + 减速步数 |
|
|
|
|
|
// // 每一步对应一个脉冲周期 |
|
|
|
|
|
// accel_decel_pulse = route->accel_step_count + route->decel_step_count; |
|
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
|
|
// // 计算匀速段可以发送的脉冲数 |
|
|
|
|
|
// // 匀速脉冲数 = 总脉冲数 - 加减速脉冲数 |
|
|
|
|
|
// if (total_pulse > accel_decel_pulse) |
|
|
|
|
|
// { |
|
|
|
|
|
// route->const_pulse_count = total_pulse - accel_decel_pulse; |
|
|
|
|
|
// } |
|
|
|
|
|
// else |
|
|
|
|
|
// { |
|
|
|
|
|
// // 如果加减速脉冲数已经超过或等于总脉冲数,则无匀速段 |
|
|
|
|
|
// route->const_pulse_count = 0; |
|
|
|
|
|
// } |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// ==================== PLSR加减速算法函数实现 ==================== |
|
|
// ==================== PLSR加减速算法函数实现 ==================== |
|
@@ -1611,18 +1228,22 @@ static void PLSR_Accel_CalculateSteps(PLSR_RouteConfig_t* route, uint32_t time_m |
|
|
|
|
|
|
|
|
// 计算频率差值,根据加速或减速模式确定计算方式 |
|
|
// 计算频率差值,根据加速或减速模式确定计算方式 |
|
|
uint32_t freq_diff; |
|
|
uint32_t freq_diff; |
|
|
if (is_accel) { |
|
|
|
|
|
|
|
|
if (is_accel) |
|
|
|
|
|
{ |
|
|
// 加速模式:计算目标频率与当前频率的差值(目标频率应大于当前频率) |
|
|
// 加速模式:计算目标频率与当前频率的差值(目标频率应大于当前频率) |
|
|
freq_diff = (route->target_freq > route->current_freq) ? |
|
|
freq_diff = (route->target_freq > route->current_freq) ? |
|
|
(route->target_freq - route->current_freq) : 0; |
|
|
(route->target_freq - route->current_freq) : 0; |
|
|
} else { |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
// 减速模式:计算当前频率与目标频率的差值(当前频率应大于目标频率) |
|
|
// 减速模式:计算当前频率与目标频率的差值(当前频率应大于目标频率) |
|
|
freq_diff = (route->current_freq > route->target_freq) ? |
|
|
freq_diff = (route->current_freq > route->target_freq) ? |
|
|
(route->current_freq - route->target_freq) : 0; |
|
|
(route->current_freq - route->target_freq) : 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 如果频率差为0,说明无需加减速,清零相关参数并返回 |
|
|
// 如果频率差为0,说明无需加减速,清零相关参数并返回 |
|
|
if (freq_diff == 0) { |
|
|
|
|
|
|
|
|
if (freq_diff == 0) |
|
|
|
|
|
{ |
|
|
route->accel_step_count = 0; |
|
|
route->accel_step_count = 0; |
|
|
route->decel_step_count = 0; |
|
|
route->decel_step_count = 0; |
|
|
route->freq_step = 0; |
|
|
route->freq_step = 0; |
|
@@ -1665,15 +1286,6 @@ static void PLSR_Accel_CalculateSteps(PLSR_RouteConfig_t* route, uint32_t time_m |
|
|
* @retval None |
|
|
* @retval None |
|
|
* @note 在TIM6中断中调用,处理加减速过程 |
|
|
* @note 在TIM6中断中调用,处理加减速过程 |
|
|
*/ |
|
|
*/ |
|
|
/** |
|
|
|
|
|
* @brief PLSR加减速处理函数 |
|
|
|
|
|
* @param route: 路径控制结构体指针 |
|
|
|
|
|
* @retval None |
|
|
|
|
|
* @note 处理加速和减速过程,支持三种算法:线性、曲线、正弦 |
|
|
|
|
|
* 加速过程:从起始频率逐步增加到目标频率 |
|
|
|
|
|
* 减速过程:从当前频率逐步减少到目标频率 |
|
|
|
|
|
* 每次调用减少一个步数,直到步数为0时完成加减速 |
|
|
|
|
|
*/ |
|
|
|
|
|
void PLSR_Accel_Process(PLSR_RouteConfig_t* route) |
|
|
void PLSR_Accel_Process(PLSR_RouteConfig_t* route) |
|
|
{ |
|
|
{ |
|
|
// 参数有效性检查 |
|
|
// 参数有效性检查 |
|
@@ -1828,10 +1440,13 @@ void PLSR_Accel_Process(PLSR_RouteConfig_t* route) |
|
|
new_freq = route->target_freq; |
|
|
new_freq = route->target_freq; |
|
|
|
|
|
|
|
|
// 如果目标频率为0,停止PWM输出并直接进入等待状态 |
|
|
// 如果目标频率为0,停止PWM输出并直接进入等待状态 |
|
|
if (route->target_freq == 0) { |
|
|
|
|
|
|
|
|
if (route->target_freq == 0) |
|
|
|
|
|
{ |
|
|
PLSR_PWM_Stop(); // 停止PWM输出 |
|
|
PLSR_PWM_Stop(); // 停止PWM输出 |
|
|
route->run_state = PLSR_STATE_WAIT; // 直接进入等待状态 |
|
|
route->run_state = PLSR_STATE_WAIT; // 直接进入等待状态 |
|
|
} else { |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
route->run_state = PLSR_STATE_CONST; // 进入匀速状态 |
|
|
route->run_state = PLSR_STATE_CONST; // 进入匀速状态 |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -1841,46 +1456,28 @@ void PLSR_Accel_Process(PLSR_RouteConfig_t* route) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// ==================== 频率更新和状态检查 ==================== |
|
|
|
|
|
// 如果频率发生变化,设置频率更新标志 |
|
|
|
|
|
if (new_freq != route->current_freq) |
|
|
|
|
|
{ |
|
|
|
|
|
route->current_freq = new_freq; // 更新当前频率 |
|
|
|
|
|
// 计算新的定时器参数并设置更新标志 |
|
|
|
|
|
uint16_t prescaler; |
|
|
|
|
|
uint32_t period; |
|
|
|
|
|
PLSR_CalculateTimerParams(new_freq, &prescaler, &period); |
|
|
|
|
|
s_next_prescaler = prescaler; |
|
|
|
|
|
s_next_period = period; |
|
|
|
|
|
s_freq_update_pending = 1; // 设置频率更新标志 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 脉冲计数已在TIM10中断中自动更新 |
|
|
|
|
|
|
|
|
|
|
|
// 检查是否需要切换状态或段 |
|
|
|
|
|
// 当状态改变或脉冲完成时,进行状态转换检查 |
|
|
// 当状态改变或脉冲完成时,进行状态转换检查 |
|
|
if (PLSR_Section_CheckPulseComplete(route)) |
|
|
if (PLSR_Section_CheckPulseComplete(route)) |
|
|
{ |
|
|
{ |
|
|
PLSR_Section_CheckTransition(route); |
|
|
|
|
|
|
|
|
route->run_state = PLSR_STATE_WAIT; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* @brief 匀速状态处理 |
|
|
* @brief 匀速状态处理 |
|
|
* @param route: 路径控制结构体指针 |
|
|
* @param route: 路径控制结构体指针 |
|
|
* @retval None |
|
|
* @retval None |
|
|
* @note 处理匀速运行状态 |
|
|
* @note 处理匀速运行状态 |
|
|
*/ |
|
|
*/ |
|
|
static void PLSR_Section_ProcessConstSpeed(PLSR_RouteConfig_t* route) |
|
|
|
|
|
|
|
|
void PLSR_Section_ProcessConstSpeed(PLSR_RouteConfig_t* route) |
|
|
{ |
|
|
{ |
|
|
if (route == NULL) return; |
|
|
if (route == NULL) return; |
|
|
|
|
|
|
|
|
// 脉冲计数已在TIM10中断中自动更新 |
|
|
|
|
|
|
|
|
|
|
|
// 检查是否需要进入减速或完成段 |
|
|
|
|
|
|
|
|
//检查段脉冲是否发完,若完成进入等待模式 |
|
|
if (PLSR_Section_CheckPulseComplete(route)) |
|
|
if (PLSR_Section_CheckPulseComplete(route)) |
|
|
{ |
|
|
{ |
|
|
PLSR_Section_CheckTransition(route); |
|
|
|
|
|
|
|
|
route->route_state = PLSR_STATE_WAIT; //如果发完进入等待条件 |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -1890,7 +1487,7 @@ static void PLSR_Section_ProcessConstSpeed(PLSR_RouteConfig_t* route) |
|
|
* @retval None |
|
|
* @retval None |
|
|
* @note 处理等待状态逻辑 |
|
|
* @note 处理等待状态逻辑 |
|
|
*/ |
|
|
*/ |
|
|
static void PLSR_Section_ProcessWait(PLSR_RouteConfig_t* route) |
|
|
|
|
|
|
|
|
void PLSR_ChackWait_End(PLSR_RouteConfig_t* route) |
|
|
{ |
|
|
{ |
|
|
if (route == NULL) return; |
|
|
if (route == NULL) return; |
|
|
|
|
|
|
|
@@ -1907,7 +1504,7 @@ static void PLSR_Section_ProcessWait(PLSR_RouteConfig_t* route) |
|
|
* @param route: 路径控制结构体指针 |
|
|
* @param route: 路径控制结构体指针 |
|
|
* @retval 1: 完成, 0: 未完成 |
|
|
* @retval 1: 完成, 0: 未完成 |
|
|
*/ |
|
|
*/ |
|
|
static uint8_t PLSR_Section_CheckPulseComplete(PLSR_RouteConfig_t* route) |
|
|
|
|
|
|
|
|
uint8_t PLSR_Section_CheckPulseComplete(PLSR_RouteConfig_t* route) |
|
|
{ |
|
|
{ |
|
|
if (route == NULL) return 0; |
|
|
if (route == NULL) return 0; |
|
|
|
|
|
|
|
@@ -1915,8 +1512,8 @@ static uint8_t PLSR_Section_CheckPulseComplete(PLSR_RouteConfig_t* route) |
|
|
|
|
|
|
|
|
// 根据等待条件类型检查 |
|
|
// 根据等待条件类型检查 |
|
|
if (current_section->wait_condition.wait_type == PLSR_WAIT_PLUSEEND || |
|
|
if (current_section->wait_condition.wait_type == PLSR_WAIT_PLUSEEND || |
|
|
current_section->wait_condition.wait_type == PLSR_WAIT_EXT_OR_END) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
current_section->wait_condition.wait_type == PLSR_WAIT_EXT_OR_END) |
|
|
|
|
|
{ |
|
|
uint32_t target_pulse; |
|
|
uint32_t target_pulse; |
|
|
if (route->mode == PLSR_MODE_RELATIVE) |
|
|
if (route->mode == PLSR_MODE_RELATIVE) |
|
|
{ |
|
|
{ |
|
@@ -1934,49 +1531,51 @@ static uint8_t PLSR_Section_CheckPulseComplete(PLSR_RouteConfig_t* route) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* @brief 检查段转换条件 |
|
|
|
|
|
|
|
|
* @brief 检查等待条件是否满足 |
|
|
* @param route: 路径控制结构体指针 |
|
|
* @param route: 路径控制结构体指针 |
|
|
* @retval None |
|
|
|
|
|
|
|
|
* @retval 1: 条件满足, 0: 条件未满足 |
|
|
*/ |
|
|
*/ |
|
|
static void PLSR_Section_CheckTransition(PLSR_RouteConfig_t* route) |
|
|
|
|
|
|
|
|
uint8_t PLSR_Section_CheckWaitCondition(PLSR_RouteConfig_t* route) |
|
|
{ |
|
|
{ |
|
|
if (route == NULL) return; |
|
|
|
|
|
|
|
|
// 参数有效性检查:路径指针不能为空 |
|
|
|
|
|
if (route == NULL) return 0; |
|
|
|
|
|
|
|
|
|
|
|
// 获取当前段的配置和等待条件指针 |
|
|
PLSR_SectionConfig_t* current_section = &route->section[route->current_section_num - 1]; |
|
|
PLSR_SectionConfig_t* current_section = &route->section[route->current_section_num - 1]; |
|
|
|
|
|
PLSR_WaitCondition_t* wait_cond = ¤t_section->wait_condition; |
|
|
|
|
|
|
|
|
// 根据等待条件类型决定转换逻辑 |
|
|
|
|
|
switch (current_section->wait_condition.wait_type) |
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
// 根据等待条件类型进行相应的检查 |
|
|
|
|
|
switch (wait_cond->wait_type) { |
|
|
case PLSR_WAIT_PLUSEEND: |
|
|
case PLSR_WAIT_PLUSEEND: |
|
|
// 脉冲结束直接切换 |
|
|
|
|
|
PLSR_Section_SwitchNext(route); |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
return PLSR_Section_CheckPulseComplete(route); |
|
|
|
|
|
|
|
|
case PLSR_WAIT_TIME: |
|
|
case PLSR_WAIT_TIME: |
|
|
|
|
|
// 等待指定时间条件:检查是否达到设定的等待时间 |
|
|
|
|
|
return PLSR_Wait_CheckTime(route); |
|
|
|
|
|
|
|
|
case PLSR_WAIT_CONDITION: |
|
|
case PLSR_WAIT_CONDITION: |
|
|
|
|
|
// 该标志可通过PLSR_SetSectionCondition函数设置 |
|
|
|
|
|
return wait_cond->condition_flag; |
|
|
|
|
|
|
|
|
case PLSR_WAIT_ACT_TIME: |
|
|
case PLSR_WAIT_ACT_TIME: |
|
|
|
|
|
// ACT时间条件:检查是否达到ACT(动作)时间 |
|
|
|
|
|
return PLSR_Wait_CheckTime(route); |
|
|
|
|
|
|
|
|
case PLSR_WAIT_EXT_EVENT: |
|
|
case PLSR_WAIT_EXT_EVENT: |
|
|
|
|
|
// 外部事件条件:等待外部事件触发 |
|
|
|
|
|
// 外部事件可通过PLSR_SetExtEvent函数设置 |
|
|
|
|
|
return PLSR_Wait_CheckExtEvent(route); |
|
|
|
|
|
|
|
|
case PLSR_WAIT_EXT_OR_END: |
|
|
case PLSR_WAIT_EXT_OR_END: |
|
|
// 进入等待状态 |
|
|
|
|
|
route->run_state = PLSR_STATE_WAIT; |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
// 外部事件或脉冲结束:两个条件任一满足即可继续 |
|
|
|
|
|
// 这种模式允许外部事件提前结束段的执行 |
|
|
|
|
|
return (PLSR_Wait_CheckExtEvent(route) || 1); |
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
|
// 未知等待类型:默认返回真,允许继续执行 |
|
|
|
|
|
return 1; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// ==================== PLSR计数器控制函数实现 ==================== |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @brief 初始化PLSR计数器 |
|
|
|
|
|
* @param None |
|
|
|
|
|
* @retval None |
|
|
|
|
|
* @note 初始化TIM2作为外部脉冲计数器 |
|
|
|
|
|
*/ |
|
|
|
|
|
void PLSR_Counter_Init(void) |
|
|
|
|
|
{ |
|
|
|
|
|
// TIM2初始化已在MX_TIM2_Init中完成 |
|
|
|
|
|
// 这里可以添加额外的计数器配置 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* @brief 启动PLSR计数器 |
|
|
* @brief 启动PLSR计数器 |
|
|
* @param None |
|
|
* @param None |
|
|