Files

237 lines
6.3 KiB
C
Raw Permalink Normal View History

#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 (xzero_active == 1u)
{
/* 引脚有效即锁存命中,避免短脉冲漏检。 */
stepper->x_zero = 1u;
}
if (s_home_active)
{
if (stepper->x_zero == 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))
{
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;
}
}
}