TA的每日心情 | 开心 2023-11-10 14:56 |
---|
签到天数: 141 天 连续签到: 1 天 [LV.7]常住居民III
|
楼主 |
发表于 2020-4-29 12:55:32
|
显示全部楼层
//定时器中断函数参考
/**
* 函数功能: 定时器中断服务函数
* 输入参数: 无
* 返 回 值: 无
* 说 明: 实现加减速过程
*/
void STEPMOTOR_TIMx_IRQHandler(void)//定时器中断处理
{
__IO uint16_t tim_count=0;
// 保存新(下)一个延时周期
uint16_t new_step_delay=0;
// 加速过程中最后一次延时(脉冲周期).
__IO static uint16_t last_accel_delay=0;
// 总移动步数计数器
__IO static uint32_t step_count = 0;
// 记录new_step_delay中的余数,提高下一步计算的精度
__IO static int32_t rest = 0;
//定时器使用翻转模式,需要进入两次中断才输出一个完整脉冲
__IO static uint8_t i=0;
if(__HAL_TIM_GET_IT_SOURCE(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx) !=RESET)
{
// 清楚定时器中断
__HAL_TIM_CLEAR_IT(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx);
// 设置比较值
tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);
__HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay);
i++; // 定时器中断次数计数值
if(i==2) // 2次,说明已经输出一个完整脉冲
{
i=0; // 清零定时器中断次数计数值
switch(srd.run_state) // 加减速曲线阶段
{
case STOP:
step_count = 0; // 清零步数计数器
rest = 0; // 清零余值
// 关闭通道
TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_DISABLE);
__HAL_TIM_CLEAR_FLAG(&htimx_STEPMOTOR, STEPMOTOR_TIM_FLAG_CCx);
STEPMOTOR_OUTPUT_DISABLE();
MotionStatus = 0; // 电机为停止状态
break;
case ACCEL:
step_count++; // 步数加1
if(srd.dir==CW)
{
step_position++; // 绝对位置加1
}
else
{
step_position--; // 绝对位置减1
}
srd.accel_count++; // 加速计数值加1
new_step_delay = srd.step_delay - (((2 *srd.step_delay) + rest)/(4 * srd.accel_count + 1));//计算新(下)一步脉冲周期(时间间隔)
rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差
if(step_count >= srd.decel_start)// 检查是够应该开始减速
{
srd.accel_count = srd.decel_val; // 加速计数值为减速阶段计数值的初始值
srd.run_state = DECEL; // 下个脉冲进入减速阶段
}
else if(new_step_delay <= srd.min_delay) // 检查是否到达期望的最大速度
{
last_accel_delay = new_step_delay; // 保存加速过程中最后一次延时(脉冲周期)
new_step_delay = srd.min_delay; // 使用min_delay(对应最大速度speed)
rest = 0; // 清零余值
srd.run_state = RUN; // 设置为匀速运行状态
}
break;
case RUN:
step_count++; // 步数加1
if(srd.dir==CW)
{
step_position++; // 绝对位置加1
}
else
{
step_position--; // 绝对位置减1
}
new_step_delay = srd.min_delay; // 使用min_delay(对应最大速度speed)
if(step_count >= srd.decel_start) // 需要开始减速
{
srd.accel_count = srd.decel_val; // 减速步数做为加速计数值
new_step_delay = last_accel_delay;// 加阶段最后的延时做为减速阶段的起始延时(脉冲周期)
srd.run_state = DECEL; // 状态改变为减速
}
break;
case DECEL:
step_count++; // 步数加1
if(srd.dir==CW)
{
step_position++; // 绝对位置加1
}
else
{
step_position--; // 绝对位置减1
}
srd.accel_count++;
new_step_delay = srd.step_delay - (((2 * srd.step_delay) + rest)/(4 * srd.accel_count + 1)); //计算新(下)一步脉冲周期(时间间隔)
rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差
//检查是否为最后一步
if(srd.accel_count >= 0)
{
srd.run_state = STOP;
}
break;
}
srd.step_delay = new_step_delay; // 为下个(新的)延时(脉冲周期)赋值
}
}
}
|
|