首先,步进电机运行是以脉冲来运行。所以实际项目应该是给MCU一个信号,MCU判断给步进多少脉冲以此运行步进电机。实际中脉冲个数以及最小最大频率都是已知数。其实最终就是取得CCR的值。
一、计算速度表
上篇讲过怎样取得速度表,首先先算出加速到某一速度的总步数以及加速度,然后将加速度表计算出来。
根据位移公式S=1/6*a*t*t*t;得出位移为1的时间变化量
Ti = pow(6.0f * 1.0f / a, 1.0f / 3.0f);
Sumt += Ti;
根据速度公式V=1/2*a*T^2,得出速度变化量
DeltaV = 0.5f * a * Sumt * Sumt;
Speed.Form[0] = Speed.Vo + DeltaV;
for(i = 1; i < Speed.AccelTotalStep; i++)
{
Ti = 1.0f / Speed.Form[i-1];
if(i < Speed.INC_AccelTotalStep)//加加速
{
Sumt += Ti;
DeltaV = 0.5f * a * Sumt * Sumt;//根据时间得出当前初速度为0的速度
Speed.Form[i] = Speed.Vo + DeltaV;//加上当前速度得出值
if(i == Speed.INC_AccelTotalStep - 1)
{Sumt = fabsf(Sumt - T);}//取正数
}
else
{//加减速
Sumt += Ti;
temp = fabsf(T - Sumt);
DeltaV = 0.5f * K * temp * temp;
Speed.Form[i] = Speed.Vt - DeltaV;
}
}
二、得出速度表,代入
速度表得出当前的值,定时器设比较输出模式,设中断。
步数已知,最低最高速度都已知。
计算完速度表开启比较输出,开启中断,当ccr值与计数器匹配时触发中断,注意由于是比较输出所以两次中断为1次脉冲。
中断服务函数为:
if(i == 2)//进两次中断中断判断
{
i = 0;
switch(Stepper.status)
{
case action://运行
if(Stepper.pos >= (Speed.AccelTotalStep - 1))当加速度时间段时
{
Stepper.status = UNIFORM;
index -= 1;
break;
}
Stepper.pluse_time = (uint16_t)(T1_FREQ / Speed.Form[index] / 2U);
/2
index++;
//CCR的值
break;
case DECEL://减速
if(Stepper.pos >= (Speed.TotalStep - 1))
{
TIM_OC_Stop_IT(&TIM_TimeBaseStructure, MOTOR_PUL_CHANNEL_x);
memset((void*)Speed.Form, 0, sizeof(float) * FORM_LEN);
index = 0;
Stepper.status = STOP;停止
break;
}
Stepper.pluse_time = (uint16_t)(T1_FREQ / Speed.Form[index] / 2);
index--;
break;
case UNIFORM://匀速
if(Stepper.pos >= Speed.DecPoint)
{
Stepper.status = DECEL;
}
break
有不懂的可公众号留言!