×
单片机 > 单片机程序设计 > 详情

AVR446_Linear speed control of stepper motor步进电机曲线分析

发布时间:2024-05-08 发布时间:
|

1.1. 单片机代码处理

// 定义定时器预分频,定时器实际时钟频率为:72MHz/(STEPMOTOR_TIMx_PRESCALER+1)

#define STEPMOTOR_TIM_PRESCALER 3 // 步进电机驱动器细分设置为: 32 细

// 定义定时器周期,输出比较模式周期设置为0xFFFF

#define STEPMOTOR_TIM_PERIOD 0xFFFF

#define FALSE 0

#define TRUE 1

#define CW 0 // 顺时针

#define CCW 1 // 逆时针

#define STOP 0 // 加减速曲线状态:停止

#define ACCEL 1 // 加减速曲线状态:加速阶段

#define DECEL 2 // 加减速曲线状态:减速阶段

#define RUN 3 // 加减速曲线状态:匀速阶段

#define T1_FREQ (SystemCoreClock/(STEPMOTOR_TIM_PRESCALER+1)) // 频率ft值

#define FSPR 200 //步进电机单圈步数

#define MICRO_STEP 32 // 步进电机驱动器细分数

#define SPR (FSPR*MICRO_STEP) // 旋转一圈需要的脉冲数

// 数学常数

#define ALPHA ((float)(2*3.14159/SPR)) // α= 2*pi/spr//

#define A_T_x10 ((float)(10*ALPHA*T1_FREQ))

#define T1_FREQ_148 ((float)((T1_FREQ*0.676)/10)) // 0.676为误差修正值

#define A_SQ ((float)(2*100000*ALPHA))

#define A_x200 ((float)(200*ALPHA))

/**

* 函数功能: 相对位置运动:运动给定的步数

* 输入参数: step:移动的步数 (正数为顺时针,负数为逆时针).

accel 加速度,实际值为accel*0.1*rad/sec^2

decel 减速度,实际值为decel*0.1*rad/sec^2

speed 最大速度,实际值为speed*0.1*rad/sec

* 返 回 值: 无

* 说 明: 以给定的步数移动步进电机,先加速到最大速度,然后在合适位置开始

* 减速至停止,使得整个运动距离为指定的步数。如果加减速阶段很短并且

* 速度很慢,那还没达到最大速度就要开始减速

*/

void STEPMOTOR_AxisMoveRel(__IO int32_t step, __IO uint32_t accel, __IO uint32_t decel, __IO uint32_t speed)

{

__IO uint16_t tim_count;

// 达到最大速度时的步数

__IO uint32_t max_s_lim;

// 必须要开始减速的步数(如果加速没有达到最大速度)

__IO uint32_t accel_lim;

if(step < 0) // 步数为负数

{

srd.dir = CCW; // 逆时针方向旋转

STEPMOTOR_DIR_REVERSAL();

step =-step; // 获取步数绝对值

}

else

{

srd.dir = CW; // 顺时针方向旋转

STEPMOTOR_DIR_FORWARD();

}

if(step == 1) // 步数为1

{

srd.accel_count = -1; // 只移动一步

srd.run_state = DECEL; // 减速状态.

srd.step_delay = 1000; // 短延时

}

else if(step != 0) // 如果目标运动步数不为0

{

// 我们的驱动器用户手册有详细的计算及推导过程

// 设置最大速度极限, 计算得到min_delay用于定时器的计数器的值。

// min_delay = (alpha / tt)/ w

srd.min_delay = (int32_t)(A_T_x10/speed);

// 通过计算第一个(c0) 的步进延时来设定加速度,其中accel单位为0.1rad/sec^2

// step_delay = 1/tt * sqrt(2*alpha/accel)

// step_delay = ( tfreq*0.676/10 )*10 * sqrt( (2*alpha*100000) / (accel*10) )/100

srd.step_delay = (int32_t)((T1_FREQ_148 * sqrt(A_SQ / accel))/10);

// 计算多少步之后达到最大速度的限制

// max_s_lim = speed^2 / (2*alpha*accel)

max_s_lim = (uint32_t)(speed*speed/(A_x200*accel/10));

// 如果达到最大速度小于0.5步,我们将四舍五入为0

// 但实际我们必须移动至少一步才能达到想要的速度

if(max_s_lim == 0){

max_s_lim = 1;

}

// 计算多少步之后我们必须开始减速

// n1 = (n1+n2)decel / (accel + decel)

accel_lim = (uint32_t)(step*decel/(accel+decel));

// 我们必须加速至少1步才能才能开始减速.

if(accel_lim == 0){

accel_lim = 1;

}

// 使用限制条件我们可以计算出减速阶段步数

if(accel_lim <= max_s_lim){

srd.decel_val = accel_lim - step;

}

else{

srd.decel_val = -(max_s_lim*accel/decel);

}

// 当只剩下一步我们必须减速

if(srd.decel_val == 0){

srd.decel_val = -1;

}

// 计算开始减速时的步数

srd.decel_start = step + srd.decel_val;

// 如果最大速度很慢,我们就不需要进行加速运动

if(srd.step_delay <= srd.min_delay){

srd.step_delay = srd.min_delay;

srd.run_state = RUN;

}

else{

srd.run_state = ACCEL;

}

// 复位加速度计数值

srd.accel_count = 0;

}

MotionStatus = 1; // 电机为运动状态

tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR); __HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay); // 设置定时器比较值

TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_ENABLE);// 使能定时器通道

STEPMOTOR_OUTPUT_ENABLE();

}

1.2. VS2008仿真曲线()

  1. 假设运动无限远距离,速度一般,计算达到最大速度的理论步数与实际步数

  2. 其中速度 加速度 减速度 都是放大10倍的

[1] [2] [3]
AVR446_Linearspeedcontrolofsteppermotor步进电机曲线分析

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
Keil(MDK-ARM)系列教程(七)_菜单