#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原来是转一圈,现在如果导程是8mm,3200次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); } 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) 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); } } }