对称“梯型”加减速算法实现

梯形加减速速度曲线      

   采用“梯形”加减速算法,在运动过程中分成以下四个状态:空闲状态,加速状态,匀速状态与减速状态。

                                                                                                  图1  梯形加减速速度曲线

加减速算法实现

                                               

                                                                                    图2 加减速实现算法

脉冲产生单元:用来产生指定频率的脉冲信号。

脉冲计数单元:用来记录各个运动状态下输出的脉冲个数。

脉宽计算单元:根据总的脉冲个数及记录的各个运动状态下的脉冲输出个数,进行状态跳转及速度计算。

脉冲产生单元

初始化STM32定时器,在定时器中断里面,翻转IO口,输出脉冲信号。

//初始化定时器功能,用来翻转IO信号,产生脉冲输出信号
void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
	
	//定时器TIM3初始化
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
 
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

	//中断优先级NVIC设置
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //先占优先级1级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级0级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

	TIM_Cmd(TIM3, DISABLE);  //不使能TIMx					 
}
//设置定时器值,用来产生指定频率的脉冲信号
void Motor0TimeSet(unsigned int ARR,bool TimeEnable)
{	
	TIM3->ARR = (uint16_t)ARR;   
	if(TimeEnable) TIM_Cmd(TIM3, ENABLE);
	else TIM_Cmd(TIM3, DISABLE);
}
//翻转IO
void TIM3_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  
		MotorPulsePinOut(&MotorControl[0]);
	}
}

脉冲计数单元

用来记录各个阶段输出的脉冲信号;根据设置的值和输出脉冲进行加减速状态切换。

                                                                     

                                                                             图 3  加减速状态切换

void MotorRunState(MOTOR_CTRL *Motor)
{
    switch(Motor->NowState.RunState)
    {
		case MIDLE://开始
			Motor->NowState.AllowMaxAddStep = Motor->SetData.RunStep/2;
			Motor->NowState.RunState = MACC;
		break;
		case MACC://加速状态
			Motor->NowState.AddStep ++;
			Motor->NowState.RunStep ++;
			if(Motor->NowState.AddStep >= Motor->NowState.AllowMaxAddStep)//三角形加速
				Motor->NowState.RunState = MDEC;
			else if(Motor->NowState.Speed >= Motor->SetData.SpeedMax)
				Motor->NowState.RunState = MKEEP;
		break;
		case MKEEP://最大速度阶段
			Motor->NowState.RunStep ++;
			if(Motor->NowState.AddStep >= Motor->SetData.RunStep - Motor->NowState.RunStep)
				Motor->NowState.RunState = MDEC;
		break;
		case MDEC://减速阶段
			Motor->NowState.RunStep ++;
			if(Motor->NowState.RunStep >= Motor->SetData.RunStep)//脉冲输出完成
			{
                Motor->TimeSet_Call_Back(Motor->NowState.TimeCountNum,false);//关闭定时器,停止脉冲信号输出
				Motor->NowState.SysState = MOV_IDLE;
				Motor->NowState.Consequence = 0; //执行结果
			}
		}
		if(Motor->NowState.SysState)Motor->TimeSet_Call_Back(Motor->NowState.TimeCountNum,true);//设置下一次脉冲输出频率
  }

速度计算单元

           根据当前处于电机加减速的那个状态,进行速度计算。采用定时1MS计算一次速度的方式。

                                                    

                                                                                                图 4 速度计算模块

void MotorCalculateSpeed(MOTOR_CTRL *Motor)
{
	switch(Motor->NowState.RunState)
	{
		case MIDLE:
			Motor->NowState.Speed = Motor->SetData.Speed0;
		break;
		case MACC:
			Motor->NowState.Speed += Motor->SetData.SpeedAdd;
			if(Motor->NowState.Speed > Motor->SetData.SpeedMax)
				Motor->NowState.Speed = Motor->SetData.SpeedMax;
		break;
		case MKEEP:
			Motor->NowState.Speed = Motor->SetData.SpeedMax;
		break;
		case MDEC:
			Motor->NowState.Speed -= Motor->SetData.SpeedAdd;
			if(Motor->NowState.Speed < Motor->SetData.Speed0)
				Motor->NowState.Speed = Motor->SetData.Speed0;
		break;
	}
	
	if(Motor->NowState.Busy)
	{		
		Motor->NowState.TimeCountNum = 1000*1000/Motor->NowState.Speed;//计算定时器应该重装的值
		Motor->NowState.MotorRunTime++;//统计电机运行时间
	}
}

  • 5
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值