Files
linear-Slide/Application/app_key.c

237 lines
6.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "app_key.h"
#include <stddef.h>
/* 按键行为说明:
* K1 单击 -> 回零(朝光电开关方向,低速)
* K2 长按/松开 -> JOG+ 启动 / 减速停止
* K3 长按/松开 -> JOG- 启动 / 减速停止
* K4 单击 -> 速度档位循环
* K5 单击 -> 立即停止
*/
#define SPEED_LEVEL_COUNT (3u)
#define JOG_SPEED_LOW_MM_S (5.0f)
#define JOG_SPEED_MID_MM_S (25.0f)
#define JOG_SPEED_HIGH_MM_S (60.0f)
#define HOME_SPEED_MM_S (5.0f)
#define HOME_TRAVEL_MM (500.0f)
static const float s_speed_levels[SPEED_LEVEL_COUNT] = {
JOG_SPEED_LOW_MM_S,
JOG_SPEED_MID_MM_S,
JOG_SPEED_HIGH_MM_S,
};
static uint8_t s_speed_idx = 0u;
static uint8_t s_jog_key = KEY_NONE;
static uint8_t s_home_active = 0u;
/* 光电零位开关:低电平有效。 */
static uint8_t key_home_switch_active(void)
{
return (HAL_GPIO_ReadPin(X_ZERO_GPIO_Port, X_ZERO_Pin) == GPIO_PIN_RESET) ? 1u : 0u;
}
/* 根据方向和已走步数估算当前位置mm。 */
static float key_estimate_pos_mm(const Stepper_t *stepper)
{
float moved_mm = (float)stepper->step_count / STEPS_PER_MM;
if (stepper->dir == GPIO_PIN_RESET)
{
return last_move_start_pos_mm + moved_mm;
}
return last_move_start_pos_mm - moved_mm;
}
static void local_motion_start(Stepper_t *stepper, GPIO_PinState dir, float speed_mm_s, float travel_mm)
{
if (stepper == NULL)
{
return;
}
if (speed_mm_s < 0.1f)
{
speed_mm_s = 0.1f;
}
if (stepper->state != STOP)
{
Int_TMC2209_stop();
stepper->state = STOP;
}
stepper->dir = dir;
stepper->distance = travel_mm;
stepper->speed = (uint16_t)speed_mm_s;
stepper->acc = 50;
stepper->dec = 50;
stepper->start_speed = 1.0f;
stepper->run_flag = 1u;
last_move_start_pos_mm = current_absolute_pos_mm;
Int_TMC2209_start(stepper, &encoder_1);
}
/* 将当前运动切换为减速停止。 */
static void local_motion_stop_decel(Stepper_t *stepper)
{
if (stepper == NULL)
{
return;
}
if (stepper->state == STOP)
{
stepper->run_flag = 0u;
return;
}
stepper->total_step = stepper->step_count + stepper->acc_step;
if (stepper->state == ACCELERATE || stepper->state == CONSTANT)
{
stepper->state = DECELERATE;
}
stepper->run_flag = 0u;
}
/* 立即停止通道:用于 STOP 按键和 HOME 完成后的收尾。 */
static void local_motion_estop(Stepper_t *stepper)
{
if (stepper == NULL)
{
return;
}
Int_TMC2209_stop();
stepper->state = STOP;
stepper->run_flag = 0u;
s_jog_key = KEY_NONE;
s_home_active = 0u;
}
/* 运行时守卫:运动中执行限位判断与 HOME 触发判断。 */
static void key_guard_check(Stepper_t *stepper)
{
float est_pos_mm = 0.0f;
uint8_t xzero_active = 0u;
if (stepper == NULL || stepper->state == STOP)
{
return;
}
est_pos_mm = key_estimate_pos_mm(stepper);
current_absolute_pos_mm = est_pos_mm;
xzero_active = key_home_switch_active();
if ((stepper->x_zero == 1u) && (xzero_active == 0u))
{
/* 若引脚当前未触发,清除可能因抖动造成的 EXTI 残留置位。 */
stepper->x_zero = 0u;
}
if (s_home_active)
{
if ((stepper->x_zero == 1u) && (xzero_active == 1u))
{
local_motion_estop(stepper);
stepper->x_zero = 0u;
debug_printf("[KEY] HOME done");
}
return;
}
if ((s_jog_key == KEY_2) && (est_pos_mm >= SOFT_LIMIT_MAX_MM))
{
local_motion_stop_decel(stepper);
current_absolute_pos_mm = SOFT_LIMIT_MAX_MM;
debug_printf("[KEY] JOG+ reach soft limit %.1f mm", SOFT_LIMIT_MAX_MM);
}
else if ((s_jog_key == KEY_3) &&
((stepper->x_zero == 1u) && (xzero_active == 1u)))
{
local_motion_stop_decel(stepper);
stepper->x_zero = 0u;
debug_printf("[KEY] JOG- reach home boundary");
}
}
void App_key_run(Stepper_t *stepper)
{
Int_Key_Task();
key_guard_check(stepper);
KeyAction_t action;
while (Int_Key_PopAction(&action))
{
switch (action.key)
{
case KEY_1:
if (action.evt == KEY_EVT_CLICK)
{
s_jog_key = KEY_NONE;
s_home_active = 1u;
stepper->x_zero = 0u;
local_motion_start(stepper, GPIO_PIN_SET, HOME_SPEED_MM_S, HOME_TRAVEL_MM);
debug_printf("[KEY] HOME start @ %.1f mm/s", HOME_SPEED_MM_S);
}
break;
case KEY_2:
if (action.evt == KEY_EVT_LONG_START)
{
s_home_active = 0u;
s_jog_key = KEY_2;
local_motion_start(stepper, GPIO_PIN_RESET, s_speed_levels[s_speed_idx], HOME_TRAVEL_MM);
debug_printf("[KEY] JOG+ start @ %.1f mm/s", s_speed_levels[s_speed_idx]);
}
else if (action.evt == KEY_EVT_RELEASE && s_jog_key == KEY_2)
{
local_motion_stop_decel(stepper);
s_jog_key = KEY_NONE;
debug_printf("[KEY] JOG+ release -> decel stop");
}
break;
case KEY_3:
if (action.evt == KEY_EVT_LONG_START)
{
s_home_active = 0u;
s_jog_key = KEY_3;
stepper->x_zero = 0u;
local_motion_start(stepper, GPIO_PIN_SET, s_speed_levels[s_speed_idx], HOME_TRAVEL_MM);
debug_printf("[KEY] JOG- start @ %.1f mm/s", s_speed_levels[s_speed_idx]);
}
else if (action.evt == KEY_EVT_RELEASE && s_jog_key == KEY_3)
{
local_motion_stop_decel(stepper);
s_jog_key = KEY_NONE;
debug_printf("[KEY] JOG- release -> decel stop");
}
break;
case KEY_4:
if (action.evt == KEY_EVT_CLICK)
{
s_speed_idx++;
if (s_speed_idx >= SPEED_LEVEL_COUNT)
{
s_speed_idx = 0u;
}
debug_printf("[KEY] SPEED -> %.1f mm/s", s_speed_levels[s_speed_idx]);
}
break;
case KEY_5:
if (action.evt == KEY_EVT_CLICK)
{
local_motion_estop(stepper);
debug_printf("[KEY] STOP");
}
break;
default:
break;
}
}
}