|
@@ -26,6 +26,7 @@ |
|
|
PLSR_RouteConfig_t g_plsr_route; // 全局PLSR路径控制结构体 |
|
|
PLSR_RouteConfig_t g_plsr_route; // 全局PLSR路径控制结构体 |
|
|
int32_t g_plsr_total_pulse_count = 0; // 全局累加脉冲计数器(程序运行期间持续累加,支持负数) |
|
|
int32_t g_plsr_total_pulse_count = 0; // 全局累加脉冲计数器(程序运行期间持续累加,支持负数) |
|
|
uint8_t g_plsr_ext_event_flag = 0; // 外部事件标志(0-无事件, 1-事件触发) |
|
|
uint8_t g_plsr_ext_event_flag = 0; // 外部事件标志(0-无事件, 1-事件触发) |
|
|
|
|
|
static uint8_t s_pulse_count_direction = 1; // 脉冲计数方向(1-递增, 0-递减),用于替代dir_logic判断计数方向 |
|
|
|
|
|
|
|
|
// ==================== PLSR内部变量 ==================== |
|
|
// ==================== PLSR内部变量 ==================== |
|
|
static uint32_t s_tim6_update_freq_us = 1000; // TIM6更新频率(微秒) |
|
|
static uint32_t s_tim6_update_freq_us = 1000; // TIM6更新频率(微秒) |
|
@@ -963,14 +964,14 @@ static void PLSR_UpdateGlobalPulseCount(int32_t current_pulse_count) |
|
|
if (current_pulse_count > s_last_total_pulse) { |
|
|
if (current_pulse_count > s_last_total_pulse) { |
|
|
int32_t pulse_increment = current_pulse_count - s_last_total_pulse; |
|
|
int32_t pulse_increment = current_pulse_count - s_last_total_pulse; |
|
|
|
|
|
|
|
|
if (g_plsr_route.dir_logic == 0) |
|
|
|
|
|
|
|
|
if (s_pulse_count_direction) |
|
|
{ |
|
|
{ |
|
|
// 方向逻辑为0:正逻辑,脉冲数递增 |
|
|
|
|
|
|
|
|
// 脉冲计数方向为1:递增 |
|
|
g_plsr_total_pulse_count += pulse_increment; |
|
|
g_plsr_total_pulse_count += pulse_increment; |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
// 方向逻辑为1:负逻辑,脉冲数递减(支持负数显示) |
|
|
|
|
|
|
|
|
// 脉冲计数方向为0:递减(支持负数显示) |
|
|
g_plsr_total_pulse_count -= pulse_increment; |
|
|
g_plsr_total_pulse_count -= pulse_increment; |
|
|
} |
|
|
} |
|
|
s_last_total_pulse = current_pulse_count; |
|
|
s_last_total_pulse = current_pulse_count; |
|
@@ -1030,15 +1031,8 @@ void Calculate_PluseNum_Simplified(PLSR_RouteConfig_t *route) |
|
|
uint32_t vt = current_section->target_freq; // 目标频率 |
|
|
uint32_t vt = current_section->target_freq; // 目标频率 |
|
|
uint32_t a = route->accel_rate; // 加速度 |
|
|
uint32_t a = route->accel_rate; // 加速度 |
|
|
uint32_t d = route->decel_rate; // 减速度 |
|
|
uint32_t d = route->decel_rate; // 减速度 |
|
|
int32_t total_pulses = 0; |
|
|
|
|
|
if(route->mode == PLSR_MODE_RELATIVE) |
|
|
|
|
|
{ |
|
|
|
|
|
total_pulses = current_section->target_pulse; // 总脉冲数 |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
total_pulses = current_section->target_pulse - route->pulse_count; // 总脉冲数 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 使用实际可发脉冲数,不再区分相对/绝对模式 |
|
|
|
|
|
int32_t total_pulses = current_section->actual_pulse; // 总脉冲数 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 防止除零错误 |
|
|
// 防止除零错误 |
|
@@ -1137,11 +1131,6 @@ void Calculate_PluseNum_Simplified(PLSR_RouteConfig_t *route) |
|
|
if (v_actual < vt) |
|
|
if (v_actual < vt) |
|
|
v_actual = vt; |
|
|
v_actual = vt; |
|
|
} |
|
|
} |
|
|
// else |
|
|
|
|
|
// { |
|
|
|
|
|
// // 数学上会减速到0或负值,设为0 |
|
|
|
|
|
// printf("减速到停止:全部%lu脉冲用于减速\n", total_pulses); |
|
|
|
|
|
// } |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
@@ -1185,15 +1174,10 @@ void Calculate_PluseNum(PLSR_RouteConfig_t *route) |
|
|
uint32_t vf = 0; // 最终频率(必须为0) |
|
|
uint32_t vf = 0; // 最终频率(必须为0) |
|
|
uint32_t a = route->accel_rate; // 加速度 |
|
|
uint32_t a = route->accel_rate; // 加速度 |
|
|
uint32_t d = route->decel_rate; // 减速度 |
|
|
uint32_t d = route->decel_rate; // 减速度 |
|
|
int32_t total_pulses = 0; |
|
|
|
|
|
if(route->mode == PLSR_MODE_RELATIVE) |
|
|
|
|
|
{ |
|
|
|
|
|
total_pulses = current_section->target_pulse; // 总脉冲数 |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
total_pulses = current_section->target_pulse - route->pulse_count; // 总脉冲数 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 使用已计算的actual_pulse作为总脉冲数 |
|
|
|
|
|
// 在PLSR_Section_StartNewSection中已经根据模式计算了actual_pulse |
|
|
|
|
|
int32_t total_pulses = current_section->actual_pulse; // 总脉冲数 |
|
|
|
|
|
|
|
|
// 防止除零错误 |
|
|
// 防止除零错误 |
|
|
if (a == 0) a = 1; |
|
|
if (a == 0) a = 1; |
|
@@ -1407,7 +1391,7 @@ void Calculate_PluseNum(PLSR_RouteConfig_t *route) |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
// 新增函数:处理段结束逻辑 |
|
|
|
|
|
|
|
|
|
|
|
void PLSR_HandleSectionEnd(void) |
|
|
void PLSR_HandleSectionEnd(void) |
|
|
{ |
|
|
{ |
|
|
// 清零所有部分的脉冲计数 |
|
|
// 清零所有部分的脉冲计数 |
|
@@ -1688,6 +1672,80 @@ void PLSR_Route_Stop(PLSR_RouteConfig_t* route) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @brief 设置脉冲方向端子状态 |
|
|
|
|
|
* @param[in] route 路径控制结构体指针 |
|
|
|
|
|
* @param[in] current_section 当前段配置指针 |
|
|
|
|
|
* @retval None |
|
|
|
|
|
* @note 根据脉冲方向逻辑和目标脉冲数设置方向端子状态 |
|
|
|
|
|
*/ |
|
|
|
|
|
// 存储上一段的方向信息,用于检测方向变化 |
|
|
|
|
|
static uint8_t s_last_direction = 0xFF; // 初始值设为无效值,确保第一次总是认为有方向变化 |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @brief 设置方向端子状态 |
|
|
|
|
|
* @param route 路径控制结构体指针 |
|
|
|
|
|
* @param current_section 当前段配置指针 |
|
|
|
|
|
* @return 如果方向发生变化,返回1;否则返回0 |
|
|
|
|
|
* @note 根据脉冲方向逻辑和目标脉冲数设置方向端子状态 |
|
|
|
|
|
*/ |
|
|
|
|
|
static uint8_t PLSR_SetDirectionPin(PLSR_RouteConfig_t* route, PLSR_SectionConfig_t* current_section) |
|
|
|
|
|
{ |
|
|
|
|
|
if (route == NULL || current_section == NULL) return 0; |
|
|
|
|
|
|
|
|
|
|
|
// 确定方向端子状态 |
|
|
|
|
|
GPIO_PinState dir_pin_state; |
|
|
|
|
|
|
|
|
|
|
|
// 根据计算后的实际可发脉冲数确定方向(正值为正向,负值为反向) |
|
|
|
|
|
// 在绝对模式下,actual_pulse已经计算为目标位置与当前位置的差值 |
|
|
|
|
|
uint8_t is_forward = (current_section->actual_pulse >= 0); |
|
|
|
|
|
|
|
|
|
|
|
// 检测方向是否发生变化 |
|
|
|
|
|
uint8_t direction_changed = (s_last_direction != 0xFF && s_last_direction != is_forward); |
|
|
|
|
|
|
|
|
|
|
|
// 更新上一段的方向信息 |
|
|
|
|
|
s_last_direction = is_forward; |
|
|
|
|
|
|
|
|
|
|
|
// 设置脉冲计数方向(与实际运动方向一致) |
|
|
|
|
|
s_pulse_count_direction = is_forward ? 1 : 0; |
|
|
|
|
|
|
|
|
|
|
|
// 根据方向逻辑确定方向端子状态 |
|
|
|
|
|
if (route->dir_logic == 0) { |
|
|
|
|
|
// 正逻辑:正向脉冲方向端子置ON(1),反向脉冲方向端子置OFF(0) |
|
|
|
|
|
dir_pin_state = is_forward ? GPIO_PIN_SET : GPIO_PIN_RESET; |
|
|
|
|
|
} else { |
|
|
|
|
|
// 负逻辑:正向脉冲方向端子置OFF(0),反向脉冲方向端子置ON(1) |
|
|
|
|
|
dir_pin_state = is_forward ? GPIO_PIN_RESET : GPIO_PIN_SET; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
switch (route->dir_port) |
|
|
|
|
|
{ |
|
|
|
|
|
case 0: |
|
|
|
|
|
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6, dir_pin_state); |
|
|
|
|
|
break; |
|
|
|
|
|
case 1: |
|
|
|
|
|
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_7, dir_pin_state); |
|
|
|
|
|
break; |
|
|
|
|
|
case 2: |
|
|
|
|
|
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_8, dir_pin_state); |
|
|
|
|
|
break; |
|
|
|
|
|
case 3: |
|
|
|
|
|
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_9, dir_pin_state); |
|
|
|
|
|
break; |
|
|
|
|
|
default: |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 如果设置了方向延时时间,则等待指定时间 |
|
|
|
|
|
if (route->dir_delay > 0) { |
|
|
|
|
|
// 使用HAL库延时函数,单位为毫秒 |
|
|
|
|
|
HAL_Delay(route->dir_delay); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 返回方向变化状态 |
|
|
|
|
|
return direction_changed; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* @brief 开始新段处理 |
|
|
* @brief 开始新段处理 |
|
|
* @param route: 路径控制结构体指针 |
|
|
* @param route: 路径控制结构体指针 |
|
@@ -1699,6 +1757,34 @@ 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]; |
|
|
|
|
|
|
|
|
|
|
|
// 统一使用相对模式计算实际可发脉冲数 |
|
|
|
|
|
if(g_plsr_route.mode == PLSR_MODE_ABSOLUTE) |
|
|
|
|
|
{ |
|
|
|
|
|
// 绝对模式:计算相对于当前位置的脉冲数 |
|
|
|
|
|
current_section->actual_pulse = current_section->target_pulse - g_plsr_total_pulse_count; |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
// 相对模式:直接使用目标脉冲数 |
|
|
|
|
|
current_section->actual_pulse = current_section->target_pulse; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 设置方向端子 - 使用计算后的actual_pulse确定方向 |
|
|
|
|
|
// 检测是否有方向变化 |
|
|
|
|
|
uint8_t direction_changed = PLSR_SetDirectionPin(route, current_section); |
|
|
|
|
|
|
|
|
|
|
|
// 如果方向发生变化,将当前频率设为0 |
|
|
|
|
|
// 这样可以确保在方向切换后,电机从停止状态开始加速,避免方向切换时的冲击 |
|
|
|
|
|
if (direction_changed) { |
|
|
|
|
|
route->current_freq = 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 将负脉冲数转换为正脉冲数用于计算 |
|
|
|
|
|
if(current_section->actual_pulse < 0) |
|
|
|
|
|
{ |
|
|
|
|
|
current_section->actual_pulse = -current_section->actual_pulse; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if(current_section->section_num == route->section_num) |
|
|
if(current_section->section_num == route->section_num) |
|
|
{ |
|
|
{ |
|
|
// 最后一段:使用完整的三部分计算(必须减速到0) |
|
|
// 最后一段:使用完整的三部分计算(必须减速到0) |
|
@@ -1925,6 +2011,7 @@ void PLSR_Section_SwitchNext(PLSR_RouteConfig_t* route, uint8_t is_pulse_complet |
|
|
if (is_pulse_complete) |
|
|
if (is_pulse_complete) |
|
|
{ |
|
|
{ |
|
|
// 脉冲完成触发:累加整个目标脉冲数 |
|
|
// 脉冲完成触发:累加整个目标脉冲数 |
|
|
|
|
|
// 使用原始的target_pulse而非actual_pulse,因为prevPulseCount需要记录原始目标值 |
|
|
route->prevPulseCount += current_section->target_pulse; |
|
|
route->prevPulseCount += current_section->target_pulse; |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
@@ -1933,7 +2020,6 @@ void PLSR_Section_SwitchNext(PLSR_RouteConfig_t* route, uint8_t is_pulse_complet |
|
|
route->prevPulseCount = g_plsr_total_pulse_count; |
|
|
route->prevPulseCount = g_plsr_total_pulse_count; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
// 绝对模式下prevPulseCount保持不变,因为每段的target_pulse已经是绝对位置 |
|
|
|
|
|
// 检查下一段是否有效 |
|
|
// 检查下一段是否有效 |
|
|
if(next_section_num == 0 && current_section->section_num == route->section_num) |
|
|
if(next_section_num == 0 && current_section->section_num == route->section_num) |
|
|
{ |
|
|
{ |
|
@@ -2077,16 +2163,22 @@ void PLSR_Accel_UpdateRates(PLSR_RouteConfig_t* route) |
|
|
if (route == NULL) return; |
|
|
if (route == NULL) return; |
|
|
|
|
|
|
|
|
// 计算加速度 (Hz/ms) |
|
|
// 计算加速度 (Hz/ms) |
|
|
if (route->default_accel_time_ms > 0) { |
|
|
|
|
|
|
|
|
if (route->default_accel_time_ms > 0) |
|
|
|
|
|
{ |
|
|
route->accel_rate = route->default_freq / route->default_accel_time_ms; |
|
|
route->accel_rate = route->default_freq / route->default_accel_time_ms; |
|
|
} else { |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
route->accel_rate = 0; // 避免除零错误 |
|
|
route->accel_rate = 0; // 避免除零错误 |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 计算减速度 (Hz/ms) |
|
|
// 计算减速度 (Hz/ms) |
|
|
if (route->default_decel_time_ms > 0) { |
|
|
|
|
|
|
|
|
if (route->default_decel_time_ms > 0) |
|
|
|
|
|
{ |
|
|
route->decel_rate = route->default_freq / route->default_decel_time_ms; |
|
|
route->decel_rate = route->default_freq / route->default_decel_time_ms; |
|
|
} else { |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
route->decel_rate = 0; // 避免除零错误 |
|
|
route->decel_rate = 0; // 避免除零错误 |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@@ -2199,15 +2291,9 @@ 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; |
|
|
|
|
|
if (route->mode == PLSR_MODE_RELATIVE) |
|
|
|
|
|
{ |
|
|
|
|
|
target_pulse = current_section->target_pulse + route->prevPulseCount; //1000 2000 3000 2->3 2000+1000 route->pulse_count>=3000 |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
target_pulse = current_section->target_pulse; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
int32_t target_pulse = current_section->actual_pulse; |
|
|
|
|
|
if(target_pulse < 0) target_pulse = -target_pulse; |
|
|
|
|
|
target_pulse += route->prevPulseCount; // 累加上次的脉冲计数 |
|
|
|
|
|
|
|
|
return (route->pulse_count >= target_pulse) ? 1 : 0; |
|
|
return (route->pulse_count >= target_pulse) ? 1 : 0; |
|
|
} |
|
|
} |
|
@@ -2255,7 +2341,7 @@ uint8_t PLSR_Section_CheckWaitCondition(PLSR_RouteConfig_t* route) |
|
|
// 外部事件或脉冲结束:两个条件任一满足即可继续 |
|
|
// 外部事件或脉冲结束:两个条件任一满足即可继续 |
|
|
// 这种模式允许外部事件提前结束段的执行 |
|
|
// 这种模式允许外部事件提前结束段的执行 |
|
|
return (PLSR_Wait_CheckExtEvent(route) || PLSR_Section_CheckPulseComplete(route)); |
|
|
return (PLSR_Wait_CheckExtEvent(route) || PLSR_Section_CheckPulseComplete(route)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
default: |
|
|
// 未知等待类型:默认返回真,允许继续执行 |
|
|
// 未知等待类型:默认返回真,允许继续执行 |
|
|
return 1; |
|
|
return 1; |
|
|