Преглед на файлове

新增实际可发脉冲变量,统一绝对模式相对模式处理,增加方向延时逻辑,上位机测试正负逻辑以及其他都基本无误

master
JIU JIALIN преди 1 месец
родител
ревизия
726174c536
променени са 7 файла, в които са добавени 497 реда и са изтрити 630 реда
  1. +4
    -4
      PLSR/PLSR/Core/Inc/tim.h
  2. +0
    -3
      PLSR/PLSR/Core/Src/main.c
  3. +128
    -42
      PLSR/PLSR/Core/Src/tim.c
  4. +1
    -1
      PLSR/PLSR/Core/Src/usart.c
  5. +2
    -2
      PLSR/PLSR/EWARM/settings/test.1.dnx
  6. +362
    -578
      PLSR/PLSR/EWARM/test.1.dep
  7. Двоични данни
      PLSR/PLSR/EWARM/test.1/Exe/test.1.sim

+ 4
- 4
PLSR/PLSR/Core/Inc/tim.h Целия файл

@@ -140,6 +140,7 @@ typedef struct {
uint8_t section_num; // 段号(1-10)
uint32_t target_freq; // 目标频率(Hz)
int32_t target_pulse; // 目标脉冲数
int32_t actual_pulse; ///< 实际可发脉冲数
uint8_t next_section; // 下一段号(0表示结束)
PLSR_WaitCondition_t wait_condition; // 等待条件
} PLSR_SectionConfig_t;
@@ -155,7 +156,9 @@ typedef struct {
uint32_t start_freq; // 起始频率
uint32_t end_freq; // 结束频率
uint8_t output_port; // 输出端口选择
uint8_t dir_port; ///< 方向端口选择:0-正逻辑(脉冲递增),1-负逻辑(脉冲递减)
uint8_t dir_port; ///< 方向端口选择:
uint16_t dir_delay; //<方向延时时间
uint16_t dir_logic; //<脉冲方向逻辑,0-正逻辑(脉冲递增),1-负逻辑(脉冲递减)
PLSR_Mode_t mode; // 模式(相对/绝对)
PLSR_Direction_t direction; // 方向
PLSR_AccelConfig_t accel_config; // 加减速配置
@@ -184,8 +187,6 @@ typedef struct {
uint32_t freq_step; // 频率步长
uint32_t wait_start_tick; // 等待开始时间
uint32_t act_start_tick; // ACT开始时间
uint16_t dir_delay; //<方向延时时间
uint16_t dir_logic; //<脉冲方向逻辑
uint16_t section_num; //<脉冲总段数
uint16_t start_section; //<起始段数
uint32_t default_freq; //<脉冲默认速度
@@ -253,7 +254,6 @@ uint32_t PLSR_TIM6_GetUpdateFreq(void);
void PLSR_TIM6_Start(void); //<在路径开始
void PLSR_TIM6_Stop(void);

void PLSR_ChackWait_End(PLSR_RouteConfig_t* route); //<检查等待条件是否成立,满足条件进行段切换
uint8_t PLSR_Wait_CheckExtEvent(PLSR_RouteConfig_t* route); //<检查外部事件是否发生
void PLSR_SetExtEvent(PLSR_RouteConfig_t* route); //<设置外部事件标志
void PLSR_ClearExtEvent(PLSR_RouteConfig_t* route); //<清除外部事件标志


+ 0
- 3
PLSR/PLSR/Core/Src/main.c Целия файл

@@ -265,8 +265,6 @@ static void KeyTask(void *p_arg)
uint8_t startflag = 0;
// 初始化PLSR路径配置
PLSR_Route_Init(&g_plsr_route);
//PLSR_Route_Start(&g_plsr_route);
while (1)
{
if(ModbusSlave.holding_regs[0x2000] == 1) //按下发送脉冲按钮后,向0x3000地址写1,松手写2,设置地址偏移为0x1000,所以这里值为0x2000
@@ -281,7 +279,6 @@ static void KeyTask(void *p_arg)
PLSR_Route_Init(&g_plsr_route);
PLSR_Route_Start(&g_plsr_route);
startflag = 0;
//PLSR_Section_Process(&g_plsr_route);
}
}
OSTimeDlyHMSM(0, 0, 0, 10); /* 延时10ms */


+ 128
- 42
PLSR/PLSR/Core/Src/tim.c Целия файл

@@ -26,6 +26,7 @@
PLSR_RouteConfig_t g_plsr_route; // 全局PLSR路径控制结构体
int32_t g_plsr_total_pulse_count = 0; // 全局累加脉冲计数器(程序运行期间持续累加,支持负数)
uint8_t g_plsr_ext_event_flag = 0; // 外部事件标志(0-无事件, 1-事件触发)
static uint8_t s_pulse_count_direction = 1; // 脉冲计数方向(1-递增, 0-递减),用于替代dir_logic判断计数方向

// ==================== PLSR内部变量 ====================
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) {
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;
}
else
{
// 方向逻辑为1:负逻辑,脉冲数递减(支持负数显示)
// 脉冲计数方向为0:递减(支持负数显示)
g_plsr_total_pulse_count -= pulse_increment;
}
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 a = route->accel_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)
v_actual = vt;
}
// else
// {
// // 数学上会减速到0或负值,设为0
// printf("减速到停止:全部%lu脉冲用于减速\n", total_pulses);
// }
}
}
else
@@ -1185,15 +1174,10 @@ void Calculate_PluseNum(PLSR_RouteConfig_t *route)
uint32_t vf = 0; // 最终频率(必须为0)
uint32_t a = route->accel_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;
@@ -1407,7 +1391,7 @@ void Calculate_PluseNum(PLSR_RouteConfig_t *route)
}
}
// 新增函数:处理段结束逻辑
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 开始新段处理
* @param route: 路径控制结构体指针
@@ -1699,6 +1757,34 @@ void PLSR_Section_StartNewSection(PLSR_RouteConfig_t* route)
// 获取当前段的配置指针(段号从1开始,数组索引从0开始)
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)
{
// 最后一段:使用完整的三部分计算(必须减速到0)
@@ -1925,6 +2011,7 @@ void PLSR_Section_SwitchNext(PLSR_RouteConfig_t* route, uint8_t is_pulse_complet
if (is_pulse_complete)
{
// 脉冲完成触发:累加整个目标脉冲数
// 使用原始的target_pulse而非actual_pulse,因为prevPulseCount需要记录原始目标值
route->prevPulseCount += current_section->target_pulse;
}
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;
}
}
// 绝对模式下prevPulseCount保持不变,因为每段的target_pulse已经是绝对位置
// 检查下一段是否有效
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;
// 计算加速度 (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;
} else {
}
else
{
route->accel_rate = 0; // 避免除零错误
}
// 计算减速度 (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;
} else {
}
else
{
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 ||
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;
}
@@ -2255,7 +2341,7 @@ uint8_t PLSR_Section_CheckWaitCondition(PLSR_RouteConfig_t* route)
// 外部事件或脉冲结束:两个条件任一满足即可继续
// 这种模式允许外部事件提前结束段的执行
return (PLSR_Wait_CheckExtEvent(route) || PLSR_Section_CheckPulseComplete(route));
default:
// 未知等待类型:默认返回真,允许继续执行
return 1;


+ 1
- 1
PLSR/PLSR/Core/Src/usart.c Целия файл

@@ -59,7 +59,7 @@ void MX_USART1_UART_Init(void)

/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 19200;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_9B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_ODD;


+ 2
- 2
PLSR/PLSR/EWARM/settings/test.1.dnx Целия файл

@@ -12,12 +12,12 @@
<ByteLimit>50</ByteLimit>
</Stack>
<StLinkDriver>
<stlinkserialNo>46232557</stlinkserialNo>
<stlinkfoundProbes />
<CStepIntDis>_ 0</CStepIntDis>
<LeaveTargetRunning>_ 0</LeaveTargetRunning>
<stlinkResetStyle>0</stlinkResetStyle>
<stlinkResetStrategy>2</stlinkResetStrategy>
<stlinkserialNo>46232557</stlinkserialNo>
<stlinkfoundProbes />
</StLinkDriver>
<DebugChecksum>
<Checksum>2012208745</Checksum>


+ 362
- 578
PLSR/PLSR/EWARM/test.1.dep
Файловите разлики са ограничени, защото са твърде много
Целия файл


Двоични данни
PLSR/PLSR/EWARM/test.1/Exe/test.1.sim Целия файл


Зареждане…
Отказ
Запис