Files

243 lines
7.7 KiB
C
Raw Permalink Normal View History

#include "Int_TMC2209.h"
/*
* TIM2 CH1 使 TOGGLE STEP
* STEP
*/
// 静态变量,记录分频状态
static uint8_t double_flag = 0;
void Int_TMC2209_init(void)
{
}
static void Int_TMC2209_set_steps(Stepper_t *stepper)
{
/* 将目标运动参数换算为总步数和梯形/三角速度曲线参数 */
// --- 参数单位定义 ---
// stepper->distance -> 代表目标距离 (mm)
// stepper->speed -> 代表目标速度 (mm/s)
// stepper->acc -> 代表加速度 (mm/s^2)
// stepper->start_speed -> 代表启动速度 (mm/s)
// 1. 计算总步数
// 总步数 = 距离(mm) * 每毫米步数
stepper->total_step = (uint32_t)(stepper->distance * STEPS_PER_MM);
// 2. 物理运动学公式计算加速距离
// 公式: x = (v^2 - v0^2) / 2a
// 单位全部统一为 mm, mm/s, mm/s^2
float v_target = stepper->speed; // mm/s
float v_start = stepper->start_speed; // mm/s
float accel = stepper->acc; // mm/s^2
// 防止除0错误
if (accel == 0 || v_target == 0)
return;
// 计算加速所需的距离 (mm)
float acc_distance_mm = (v_target * v_target - v_start * v_start) / (2.0f * accel);
// 将加速距离转换为加速步数
stepper->acc_step = (uint32_t)(acc_distance_mm * STEPS_PER_MM);
// 3. 规划梯形/三角形速度曲线
if (stepper->total_step < stepper->acc_step * 2)
{
// 距离太短,跑不到目标速度 -> 三角形加减速
stepper->acc_step = stepper->total_step / 2;
stepper->constant_step = 0;
debug_printf("Model: Triangle, AccStep: %d", stepper->acc_step);
}
else
{
// 距离足够 -> 梯形加减速
stepper->constant_step = stepper->total_step - stepper->acc_step * 2;
debug_printf("Model: Trapezoid, Acc: %d, Const: %d", stepper->acc_step, stepper->constant_step);
}
// 4. 计算每一步的速度增量 (mm/s per step)
// 逻辑:(目标速度 - 启动速度) / 加速步数
// 含义:每走一步,速度增加多少 mm/s
if (stepper->acc_step > 0)
{
stepper->speed_inc = (float)(v_target - v_start) / stepper->acc_step;
}
else
{
stepper->speed_inc = 0;
}
// 5. 初始化状态
stepper->step_count = 0;
stepper->current_speed = stepper->start_speed;
stepper->state = ACCELERATE;
}
void Int_stepper_run(void)
{
/* 仅用于调试的固定步进函数,不参与正式运行逻辑 */
// 此函数用于测试,硬编码了步数,建议根据新的 STEPS_PER_MM 修改这里
// 例如走 10mm:
// uint32_t steps = 10 * STEPS_PER_MM * 2; // *2 是因为 toggle
HAL_GPIO_WritePin(STEPPER123_EN_GPIO_Port, STEPPER123_EN_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(STEPPER1_DIR_GPIO_Port, STEPPER1_DIR_Pin, GPIO_PIN_SET);
// 这里的3200原来是转一圈现在如果导程是8mm3200次toggle (1600步) = 8mm
for (uint16_t i = 0; i < 3200; i++)
{
HAL_GPIO_TogglePin(STEPPER_1_STEP_GPIO_Port, STEPPER_1_STEP_Pin);
HAL_Delay(1);
}
}
void Int_TMC2209_start(Stepper_t *stepper, Encoder_t *encoder)
{
/* 启动流程:
* 1)
* 2) 使
* 3) 线
* 4) TIM2
*/
// 清零编码器值
encoder->pulses = 0;
encoder->overflow = 0;
__HAL_TIM_SET_COUNTER(&htim1, 0);
encoder->z = 0;
HAL_GPIO_WritePin(ENCODER_MODE_GPIO_Port, ENCODER_MODE_Pin, GPIO_PIN_RESET);
HAL_TIM_Encoder_Start(&htim1, TIM_CHANNEL_ALL);
// 使能驱动
HAL_GPIO_WritePin(STEPPER123_EN_GPIO_Port, STEPPER123_EN_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(STEPPER1_DIR_GPIO_Port, STEPPER1_DIR_Pin, stepper->dir);
// 复位分频标志位
double_flag = 0;
// 设置步数参数
Int_TMC2209_set_steps(stepper);
// [修改] 计算初始ARR (基于 mm/s)
// 最小速度保护防止ARR计算溢出
if (stepper->start_speed < 0.1f)
stepper->start_speed = 0.1f;
// 这里传入的是 mm/s
uint32_t arr = CALC_ARR(stepper->start_speed);
debug_printf("Start Speed: %.2f mm/s, ARR: %d", stepper->start_speed, arr);
__HAL_TIM_SET_COUNTER(&htim2, 0);
__HAL_TIM_SET_AUTORELOAD(&htim2, arr);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, arr / 2);
HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_1);
}
void Int_TMC2209_stop(void)
{
/* 停止流程停止STEP输出 -> 关闭驱动 -> 停止编码器计数 */
HAL_TIM_OC_Stop_IT(&htim2, TIM_CHANNEL_1);
HAL_GPIO_WritePin(STEPPER123_EN_GPIO_Port, STEPPER123_EN_Pin, GPIO_PIN_RESET);
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;
// --- 1. 实时限位保护拦截 ---
if (Int_TMC2209_CheckHomeStop(s))
return;
// --- 2. 定时更新步进电机速度 ---
Int_TMC2209_SpeedUpadte(s);
}
}