v1.1添加按键功能的中文日志说明,改进了零点逻辑,之前回零成功后再次下发回零还会移动然后撞到限位开关,现在会正确保持在零点

This commit is contained in:
编程浩
2026-03-02 14:57:34 +08:00
parent b2fedd58b2
commit 25d82ccd66
8 changed files with 1821 additions and 1535 deletions

View File

@@ -1,6 +1,6 @@
#include "Int_TMC2209.h"
/*
/*
* TIM2 CH1 使用 TOGGLE 模式输出 STEP
* 每次中断只翻转一次电平,两个中断才构成一个完整 STEP 脉冲。
*/
@@ -143,65 +143,100 @@ void Int_TMC2209_stop(void)
HAL_TIM_Encoder_Stop(&htim1, TIM_CHANNEL_ALL);
}
uint8_t Int_TMC2209_CheckHomeStop(Stepper_t *stepper)
{
// 检测当前是否在零点,如果是,则禁止向零点方向移动
if (HAL_GPIO_ReadPin(X_ZERO_GPIO_Port, X_ZERO_Pin) == GPIO_PIN_RESET)
{
// 只有当方向是朝着零点移动时 (dir == 1),才强制停止
if (stepper->dir == GPIO_PIN_SET)
{
stepper->state = STOP;
stepper->current_speed = 0;
Int_TMC2209_stop(); // 停止定时器脉冲输出
// 标记:如果正在执行回零操作,这里可以清零坐标
stepper->step_count = 0;
return 1; // 直接退出中断,不再生成这个脉冲
}
// 如果 s->dir == 0 (远离零点),代码会继续往下走,从而允许电机退出限位区
}
return 0;
}
void Int_TMC2209_SpeedUpadte(Stepper_t *stepper)
{
// 根据加减速算法更新速度(当前采用梯形算法)
double_flag++;
// 必须满2次中断1个完整脉冲才进行计算
if (double_flag < 2)
return;
stepper->step_count++;
double_flag = 0;
// --- 状态机管理 ---
switch (stepper->state)
{
case ACCELERATE:
// 加速阶段
stepper->current_speed += stepper->speed_inc; // 这里的 speed_inc 单位是 mm/s per step
if (stepper->step_count >= stepper->acc_step || stepper->current_speed >= stepper->speed)
{
stepper->current_speed = stepper->speed;
stepper->state = CONSTANT;
}
break;
case CONSTANT:
// 匀速阶段
if (stepper->step_count >= (stepper->total_step - stepper->acc_step))
stepper->state = DECELERATE;
break;
case DECELERATE:
// 减速阶段
stepper->current_speed -= stepper->speed_inc;
if (stepper->current_speed < stepper->start_speed)
stepper->current_speed = stepper->start_speed;
if (stepper->step_count >= stepper->total_step)
{
stepper->state = STOP;
Int_TMC2209_stop(); // 内部会关闭中断所以这里直接return即可
return;
}
break;
case STOP:
Int_TMC2209_stop();
return;
}
// --- 更新硬件 ---
if (stepper->state != STOP)
{
// 传入 mm/s计算新的 ARR
uint32_t new_arr = CALC_ARR(stepper->current_speed);
__HAL_TIM_SET_AUTORELOAD(&htim2, new_arr);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, new_arr / 2);
}
}
extern Stepper_t stepper_1;
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
/* TIM2中断中完成步进脉冲计数、速度状态机更新和ARR重装载 */
if (htim->Instance == TIM2)
{
Stepper_t *s = &stepper_1;
double_flag++;
// 必须满2次中断1个完整脉冲才进行计算
if (double_flag < 2)
// --- 1. 实时限位保护拦截 ---
if (Int_TMC2209_CheckHomeStop(s))
return;
s->step_count++;
double_flag = 0;
// --- 状态机管理 ---
switch (s->state)
{
case ACCELERATE:
s->current_speed += s->speed_inc; // 这里的 speed_inc 单位是 mm/s per step
if (s->step_count >= s->acc_step || s->current_speed >= s->speed)
{
s->current_speed = s->speed;
s->state = CONSTANT;
}
break;
case CONSTANT:
if (s->step_count >= (s->total_step - s->acc_step))
s->state = DECELERATE;
break;
case DECELERATE:
s->current_speed -= s->speed_inc;
if (s->current_speed < s->start_speed)
s->current_speed = s->start_speed;
if (s->step_count >= s->total_step)
{
s->state = STOP;
Int_TMC2209_stop(); // 内部会关闭中断所以这里直接return即可
return;
}
break;
case STOP:
Int_TMC2209_stop();
return;
}
// --- 更新硬件 ---
if (s->state != STOP)
{
// 传入 mm/s计算新的 ARR
uint32_t new_arr = CALC_ARR(s->current_speed);
__HAL_TIM_SET_AUTORELOAD(&htim2, new_arr);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, new_arr / 2);
}
// --- 2. 定时更新步进电机速度 ---
Int_TMC2209_SpeedUpadte(s);
}
}