第一版代码,为了在EEPROM保存参数的时候走STM32的CRC,让Codex修改了一下,现在的效果是无法存储,codex表示原因是CRC方法不同,修改到一半今天的额度使用完了,有待后续解决CRC的bug

This commit is contained in:
2026-02-28 17:36:05 +08:00
commit b2fedd58b2
212 changed files with 208290 additions and 0 deletions

207
Interface/Int_TMC2209.c Normal file
View File

@@ -0,0 +1,207 @@
#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);
}
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);
}
}
}