基于STM32步进电机加减速控制查表法

步进电机加减速查表法

1.流程图

2,代码段

1.码盘

const UNBIT16 CarAccelerationList[CAR_ACCELERATION_STEP_MAX + 1] =
{
    1897,786,603,508,448,405,372,347,326,308,
    293,280,268,258,249,241,234,227,221,215,
    210,205,200,196,192,188,184,181,178,175,
    172,169,166,164,162,159,157,155,153,151,
    149,147,146,144,142,141,139,138,136,135,
    133,132,131,130,129,127,126,125,124,123,
    122,121,120,119,118,117,116,115,115,114,
    113,112,111,111,110,109,108,108,107,106,
    106,105,104,104,103,103,102,101,101,100,
    100,99,99,98,98,97,97,96,96,95,
    95,94,94,93,93,92,92,91,91,91,
    90,90,89,89,89,88,88,88,87,87,
    86,86,86,85,85,85,84,84,84,83,83
};

2.速度改变段

void VerticalCarMotorSpeedCtr(UNBIT16 speed)
{
    if(speed > CAR_ACCELERATION_STEP_MAX)
    {
        VerticalCarMotorSpeed = CAR_ACCELERATION_STEP_MAX;
    }
    else
    {
        VerticalCarMotorSpeed = speed;
    }
    
    TIM3->PSC = (CarAccelerationList[VerticalCarMotorSpeed]/10 *7); //±äƵ£¬³õʼÊÇ1001
}

3.速度控制段(包含距离计算,方向确定,速度控制)

//Òƶ¯´¹Ö±Ð¡³µµ½Ä¿±êµØÖ·
UNBIT8 MoveVerticalCarToTargetAddr(UNBIT8 MoveCarAddr)
{
	  static UNBIT16 DistanceTemp;
    switch(MoveVerticalCarSta)
    {
        case MOVE_VerticalCAR_STA_INIT:
            MoveVerticalCarSta = MOVE_VerticalCAR_STA_ACT;
            VerticalCarPulseSta = 0;
            VerticalCarPulseNum = 0;
				    DistanceTemp = 0;
				    MoveVerticalCarLeftFlag = 0;
				    MoveVerticalCarRightFlag = 0;
				    MoveVerticalCarStep = 0;
				    DeviceCfg.SUBDIVIDE = 0;
				    DeviceCfg.MoveStep = 0;
				
            VerticalCarMotorSpeedCtr(0);
				
				    //¿ØÖÆÔ˶¯·½ÏòÒÔ¼°²éÕÒÐèÒªÔ˶¯¾àÀë¶Î
				    if(MoveCarAddr > DeviceCfg.sign) //ÕýÏòÒƶ¯
						{
							 stepping_motor_reversal();
							 MoveVerticalCarLeftFlag = 1;
							 MoveVerticalCarStep = MoveCarAddr - DeviceCfg.sign;
						}
						else
						{
							 stepping_motor_foreward();
							 MoveVerticalCarRightFlag = 1;
							 MoveVerticalCarStep = DeviceCfg.sign - MoveCarAddr;
						}
						
						//¼ÆËã×ܵÄÄ¿±ê²½Êý
						DeviceCfg.MaxStep = (MoveVerticalCarStep * STEP_MOTOR);
  
            break;
        case MOVE_VerticalCAR_STA_ACT:
           
    				CatchVerticalCarPulseFunc( ); //²¶×½Ð¡³µÂö³åÊý£¨Ã¿Ò»¸öϽµÑؼÇÒ»¸öÂö³å£©
				
				    if(VerticalCarPulseNum != 0)
            {
                if(DeviceCfg.MoveStep < 20)
                {
                    VerticalCarPulseNum = 0;
                }
            }
				
           if(DistanceTemp != DeviceCfg.MoveStep )
					 {			
              DistanceTemp	= DeviceCfg.MoveStep;					 
							if(DeviceCfg.MoveStep < DeviceCfg.MaxStep/2)  //²»µ½Ä¿±ê²½ÊýµÄÒ»°ã¶¼ÊǼÓËÙ
							{
								if(VerticalCarMotorSpeed < CAR_ACCELERATION_STEP_MAX){
										VerticalCarMotorSpeed ++;                        
										VerticalCarMotorSpeedCtr(VerticalCarMotorSpeed);
								}
							}
							else if(DeviceCfg.MoveStep > (DeviceCfg.MaxStep - CAR_ACCELERATION_STEP_MAX - 20))  //ÌáÇ°¼õËÙ
							{
								 if(VerticalCarMotorSpeed > 0)
								 {
										VerticalCarMotorSpeed --;
										VerticalCarMotorSpeedCtr(VerticalCarMotorSpeed);
								 }
							}
						}
					
							if(VerticalCarPulseNum == MoveVerticalCarStep)   //Èç¹û¾àÀë¶ÎºÍÂö³åÊýÏàµÈÁË
							{
								stepping_motor_stop();
								if(MoveVerticalCarLeftFlag == 1)   //¸üÐÂС³µµ±Ç°Î»ÖÃ
								{
									DeviceCfg.sign = (DeviceCfg.sign + VerticalCarPulseNum);
								}
								else
								{
									DeviceCfg.sign = (DeviceCfg.sign - VerticalCarPulseNum);
								}
								return 1;
							}
							else if(DeviceCfg.MoveStep > DeviceCfg.MaxStep + 100) //Èç¹ûС³µ²½Êý´óÓÚ×î´ó²½Êý¼Ó100£¬Ôò±¨´í²¢ÇÒֹͣǰ½ø
							{
								stepping_motor_stop();
								return 2;
							}
							return 0; 		
		}   
}

4.传感器监测

void CatchVerticalCarPulseFunc(void)
{
   switch(VerticalCarPulseSta)
    {
        case 0:
            if(GetVerticalCarPlaceSta( ) == SENSOR_COVER)
            {
                VerticalCarPulseSta = 1;
                DeviceCfg.MoveVerticalCarLoseStep = 8;
            }
            break;
        case 1:
            if(GetVerticalCarPlaceSta( ) == SENSOR_DISCOVER)
            {
                VerticalCarPulseSta = 0;
            }
            else if(DeviceCfg.MoveVerticalCarLoseStep == 0) 
            {
                VerticalCarPulseSta = 2;
            }
            break;
        case 2:
            if(GetVerticalCarPlaceSta( ) == SENSOR_DISCOVER)
            {
                VerticalCarPulseSta = 3;
                DeviceCfg.MoveVerticalCarLoseStep = 8;
            }
            break;
        case 3:
            if(GetVerticalCarPlaceSta( ) == SENSOR_COVER)
            {
                VerticalCarPulseSta = 2;
            }
            else if(DeviceCfg.MoveVerticalCarLoseStep == 0)
            {
                VerticalCarPulseNum ++;
                VerticalCarPulseSta = 0;
            }
            break;
    }
}

5.中断部分

void TIM3_IRQHandler(void)   //ϸ·ÖΪ2																	
{
    if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET) {   			//¼ì²éTIM3¸üÐÂÖжϷ¢ÉúÓë·ñ
        TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);      				//Çå³ýTIMx¸üÐÂÖжϱêÖ¾ 
			  DeviceCfg.SUBDIVIDE = (DeviceCfg.SUBDIVIDE++); //¿ØÖÆϸ·Ö
	    	if(DeviceCfg.MoveVerticalCarLoseStep > 0)
 				{
					DeviceCfg.MoveVerticalCarLoseStep--;  //µÍµçƽÂö³åÊýÁ¿
				}					
       if( DeviceCfg.SUBDIVIDE == 8){ //µ±×ßÁËÒ»²½µÄʱºò½øÈë¸ÄÌõ¼þ
				 DeviceCfg.SUBDIVIDE = 0; //ÖØмÆËãÂö³åÊýÁ¿ 
				 DeviceCfg.MoveStep  = DeviceCfg.MoveStep + 1;  //²½Êý¼Ñ¼Ñ
			 }
		}
}

6.定时器初始化段

void TIM3_Configuration(void) {
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);                //TIM3_CH1Òý½ÅÖØÓ³Éä

    TIM_TimeBaseStructure.TIM_Period = 99;
    TIM_TimeBaseStructure.TIM_Prescaler = 86;                         //ÉèÖÃÓÃÀ´×÷ΪTIMxʱÖÓƵÂʳýÊýµÄÔ¤·ÖƵֵ  ²»·ÖƵ
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;                     //ÉèÖÃʱÖÓ·Ö¸î:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;      //TIMÏòÉϼÆÊýģʽ
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);                  //¸ù¾ÝTIM_TimeBaseInitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯TIMxµÄʱ¼ä»ùÊýµ¥Î»


    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;                //Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆģʽ2
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;    //±È½ÏÊä³öʹÄÜ
    TIM_OCInitStructure.TIM_Pulse = 50;                       //ÉèÖôý×°È벶»ñ±È½Ï¼Ä´æÆ÷µÄÂö³åÖµ£¬³õʼµÄÕ¼¿Õ±È
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;        //Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
    TIM_OC1Init(TIM3, &TIM_OCInitStructure);                         //¸ù¾ÝTIM_OCInitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèTIMx
    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);                //ʹÄÜTIMxÔÚCCR2ÉϵÄԤװÔؼĴæÆ÷
                                                                     //ÉÏÃæÁ½¾äÖеÄOC2È·¶¨ÁËÊÇchannle¼¸£¬ÒªÊÇOC3ÔòÊÇchannel 3
	  
	  TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);                          //ʹÄÜÖ¸¶¨µÄTIM3ÖжÏ,ÔÊÐí¸üÐÂÖжÏ
	  
    TIM_ARRPreloadConfig(TIM3, ENABLE);                              //ʹÄÜTIMxÔÚARRÉϵÄԤװÔؼĴæÆ÷

    TIM_Cmd(TIM3, DISABLE);                                           //ʹÄÜTIMxÍâÉè

    TIM_CtrlPWMOutputs(TIM3, ENABLE);                                // ´ò¿ªPWM
}

3.总结

1.步进电机加减速,首先要确定三要素,电机移动的方向,电机运动的距离步数,电机的速度控制。如果有传感器还需要传感器的高低电平计数。

2.同步:有带传感器的需要传感器和电机运动进行同步,变速和步数需要同步。不能使电机一下加速到最大值或者减速到最小值。一步一个速度进行控制。

3.最后退出加减速时,需要实时更新当前位置变化

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

st奔跑的小绵羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值