adeng2002 发表于 2012-10-16 16:40:38

各位大侠 ,STM32控制步进电机时遇到的一个问题,很不解

我用STM的普通定时器输出脉冲给步进驱动器,脉冲的个数是在定时中断中累加的。
运动控制代码放在MAIN的循环中。
在运行过程中发现进行某些速度的变换时有停顿现象,何原因??如何解决??
LED1是脉冲LED0是方向
这是运动控制代码
           while(1)
        {
        //        LED0=!LED0;
        //        delay_ms(200);
        if (KEY1==1)
        {
        LED3=0;
        }
                if (KEY1==0)
        {
        LED3=1;
        }
          
        if(Axis_1.StepNow==0)                               //走到200步
        {
        Axis1_Move(200,500,0,0,TRUE);
        }

//        //        delay_ms(1000);       
//                if(Axis_1.StepNow==800)
//                {
//                Axis1_Move(1600,1000,0,0,TRUE);       
//                }
                        if(Axis_1.StepNow==200)                        //走到400步
        {
                FrqCalculate(1000);
                Axis1_Move(400,750,0,0,TRUE);
        }
                                if(Axis_1.StepNow==400)          //这里有0.2秒的停顿
        {
                Axis1_Move(600,1000,0,0,TRUE);                   //走到600步
        }
                  if(Axis_1.StepNow==600)
        {
                Axis1_Move(800,1250,0,0,TRUE);
        }
        if(Axis_1.StepNow==800)
        {
                Axis1_Move(1000,1000,0,0,TRUE);
        }
        if(Axis_1.StepNow==1000)
        {
                Axis1_Move(1400,550,0,0,TRUE);
        }
                   if(Axis_1.StepNow==1400)                   //这里也有停顿 从550变到750无停顿 从540开始就有停顿
        {
                Axis1_Move(1600,750,0,0,TRUE);
        }
        }
这是轴配置代码
void Axis1_Move(u32 StepNumber,u32 MaxSpeed,u32 Accel,u32 decel,bool Direction)
{           if(StepNumber==Axis_1.StepNow|| Axis_1.MoveState==TRUE)
        {
                   return;       //直接返回
        }
   
       Axis_1.MaxSpeed=MaxSpeed;                  //最高速度
       Axis_1.Accel=Accel;                           //加速度
       Axis_1.decel=decel;                           //减速度
       Axis_1.Direction=Direction;
       
        FrqCalculate(MaxSpeed);   //频率值
        TIM3->ARR=Tim3_ARR;//设定计数器自动重装值   
        TIM3->PSC=Tim3_PSC;//预分频器
        if(StepNumber>Axis_1.StepNow)
        {               Axis_1.StepNumber=StepNumber-Axis_1.StepNow;       //移动步数
                   LED0= Direction;       //方向正向为正
        }
               if(StepNumber<Axis_1.StepNow)
        {                Axis_1.StepNumber=Axis_1.StepNow-StepNumber;
                   LED0= !Direction;       //方向正向为负
        }
Axis_1.MoveState=TRUE;
TIM3->CR1|=0x01;    //使能定时器3

}

这是中断代码
void TIM3_IRQHandler(void)
{                                                               
        if(TIM3->SR&0X0001)//溢出中断
        {
//        printf("\n enter timer interrupter \n");
if (KEY1==0&&LED0==FALSE)
        {
        Axis_1.StepNow=0;
        LED1=0;

                        TIM3->CR1&=0xFFFE;    //禁能定时器3
                       Axis_1.MoveState=FALSE;
                       number=0;
        }       
        else
        {

                if(number<Axis_1.StepNumber)
                {
                LED1=!LED1;
                if(LED1==TRUE)
                {
                number++;
//                printf("\n number=%d \n",number);
//                Axis_1.StepNow++;
                if(LED0==TRUE)
               {
                       Axis_1.StepNow++;
               }
               else
                       {
                               Axis_1.StepNow--;
                       }
//                       printf("\n Axis_1.StepNow=%d \n",Axis_1.StepNow);
                //printf("\n enter the timer break \n");
                }                       
                }
                        else
                {
                        LED1=0;
                        TIM3->CR1&=0xFFFE;    //禁能定时器3
                       Axis_1.MoveState=FALSE;
                       number=0;
                }                                                                                                   
        }       
        }                          
        TIM3->SR&=~(1<<0);//清除中断标志位           
}

qq302011 发表于 2012-10-16 17:07:18

没看懂,什么意思哈

adeng2002 发表于 2012-10-17 08:36:37

描述力差啊{:sweat:}
Axis1_Move(1000,1000,0,0,TRUE);
这个是控制电机移动的代码,第一个参数是控制位移量的,是绝对位移。第二个参数是速度值,每秒移动的脉冲数。后三个参数未用。
FrqCalculate(MaxSpeed);
这个是计算速度值的代码,计算后的值赋予ARR PSC寄存器。
最后使能定时器,输出脉冲。
在中断代码中计算脉冲输出的个数,到达目标值后禁能定时器。

adeng2002 发表于 2012-10-17 08:37:42

   if (KEY1==1)
      {
      LED3=0;
      }
                if (KEY1==0)
      {
      LED3=1;
      }
这段代码是不起作用的

adeng2002 发表于 2012-10-17 08:42:15

if(Axis_1.StepNow==200)                        //走到400步
      {
                FrqCalculate(1000);
                Axis1_Move(400,750,0,0,TRUE);
      }
                              if(Axis_1.StepNow==400)            //这里有0.2秒的停顿
      {
                Axis1_Move(600,1000,0,0,TRUE);                   //走到600步
      }
                  if(Axis_1.StepNow==600)
      {
                Axis1_Move(800,1250,0,0,TRUE);
      }
      if(Axis_1.StepNow==800)
      {
                Axis1_Move(1000,1000,0,0,TRUE);
      }
      if(Axis_1.StepNow==1000)
      {
                Axis1_Move(1400,550,0,0,TRUE);
      }
                   if(Axis_1.StepNow==1400)                   //这里也有停顿 从550变到750无停顿 从540开始就有停顿
      {
                Axis1_Move(1600,750,0,0,TRUE);
      }

这是运动控制代码

电机从位置零开始运动,到200位置的时候执行Axis1_Move(400,750,0,0,TRUE),即以750的速度移动到400位置处。
现在在运行的过程中发现有些语句的执行之间有明显的停顿。

adeng2002 发表于 2012-10-17 08:56:29

在750 到 1000的速度变化时有延时

zhangyb 发表于 2012-10-17 14:28:22

问题还没有找到么

wufuhai216 发表于 2012-10-17 17:31:51

楼主,不介意的话,共享代码大家参考一下,我现在也这在玩步进电机的。
页: [1]
查看完整版本: 各位大侠 ,STM32控制步进电机时遇到的一个问题,很不解