原创 步进电机驱动-dsPIC33F步进电机驱动程序解读-速度与位置控制器1

2014-4-3 09:22 2381 26 26 分类: 工业电子 文集: 步进电机驱动笔记

 

/*******************************************************************************
* Function:     SpeedPositionControl()
速度和位置控制器,在定时器1中断中调用。
*******************************************************************************/
void SpeedPositionControl(void)
{
     long ltemp;     //速度计算中间量储存
     int maxSpeed;   //最大速度中间量存储
     //开环模式下,根据两种不同的速度源设置maxSpeed 参数
    if(uGF.currentControlLoop == OFF)
    {
        if(uGF.speedSource == POT_REF_SPEED)    //速度由POT设置,速度源有两个,一个是POT,一个是DMCI
        {
            maxSpeed = potSpeed>>5;         //最大速度和POT速度转换
        }
        else  //如果速度源是DMCI,则最大速度为-1024~1024,并进行了范围限制
        {
            if(dmciSpeed > 1024)            
                maxSpeed = 1024;             
            else if(dmciSpeed < -1024)
                maxSpeed = -1024;
            else
                maxSpeed = dmciSpeed;
        }
    }
    else       //PI闭环模式下,直接根据不同速度源赋值
    {
        if(uGF.speedSource == POT_REF_SPEED)    
        {
            maxSpeed = potSpeed;
        }
        else                          
        {
            maxSpeed = dmciSpeed; 
        }
        //限制最大速度在 2400 RPM
        if(maxSpeed > 20000)         
        maxSpeed = 20000;
        else
        if(maxSpeed < -20000)     
        maxSpeed = -20000;
        //不同的细分下,限制速度不同,在PI里面计算出速度的限制值。
         if((abs(speedOut)>>2)>(32767>>(stepSize)))//如果speedout=20000,16细分
         {
                if(maxSpeed>0)//假如maxSpeed=10000
                {
                    maxSpeed = 32767>>(stepSize-2);  //此时限制到maxSpeed=8191,根据细分值限制,
                    if(speedOut > maxSpeed)       //如果实际速度比限制值大,则将输出调到限制的最大值
                        speedOut = maxSpeed;    
                }    
                else //负向的逻辑相同,如果超出范围,则调整至限制的速度范围
                {    
                    maxSpeed = -(32767>>(stepSize-2));
                    if(speedOut < maxSpeed)
                        speedOut = maxSpeed;
                }
         }//PI的速度限制完毕
    }
//如果位置控制的参数改变了,则进行更新,并且将位置设置为起点
    if (uGF.positionControlCopy != uGF.positionControl)
    {
        uGF.positionControl = uGF.positionControlCopy;
        position = 0;
    }
//如果位置控制模式切换为速度控制,则将刚刚计算的maxSpeed赋值给全局变量。
    if(uGF.positionControl == SPEED_CONTROL)    
    {
        speedRef = maxSpeed;
    }    
//位置控制器,注意算法
    else
{
        //DMCI如果发来位置的参考变化
     if (dmciPositionRefCopy != dmciPositionRef)
     {
         dmciPositionRef = dmciPositionRefCopy;  //更新变量   
         positionRef = (long)dmciPositionRef*dmicPosRefScale;
            //位置的倍数计算出来,赋值给位置参考变量,这里倍数为64
     }
            posError = positionRef - position;
           //如果控制的位置还小于一个整步,则直接速度降至停机,否则采用一个什么样的速度来达到设定的位
          //置,要进行计算
if((posError < stepSizeCount) && (posError > -stepSizeCount))
{
    speedRef = 0;
}
else   
{    
         //最大速度必须大于0
         if(maxSpeed<0)
             maxSpeed = -maxSpeed;
       //确保溢出不会发生,也就是说,如果是设定的位置跟当前位置差距太大,直接采用最大的速度去趋                近所设定的位置
         ltemp = (long)(abs(speedOut))*POS_OVERFLOW_CHECK;
         if (posError > ltemp)
         {
              speedRef = maxSpeed;
         }
         else
         if (posError <- ltemp)
         {
              speedRef = -maxSpeed;
         }        
         else        //减速点到达,切换到P控制器,这个时候才采用可变增益位置控制。也就是速度可变。
        
             long posGain;
             //从下面的图就可以看出来,就是为了设定一个什么样的速度去趋近设定的位置。
                           //
             posGain =((long)*decelerationRate/((long)abs(speedOut)));
            if(posGain==0)  
                posGain =1;
            speedRef = (posError*posGain)>>15;
            //通过上面的公式计算出速度的参考值。并且通过下面的算法来限制这个参考值的范围。
            if (speedRef > maxSpeed)
                    speedRef = maxSpeed;
                 else if(speedRef <- maxSpeed)
                    speedRef = -maxSpeed;
                 else if(speedRef <= MINIMUM_SPEED && speedRef>0)
                    speedRef = MINIMUM_SPEED+1;
                 else if(speedRef >=- MINIMUM_SPEED && speedRef<0)
                    speedRef = -MINIMUM_SPEED-1;
         }     
        }
}
 
//速度控制器
    ltemp = (speedRef - speedOut);
  //先计算实际输出的速度和设置的参考速度差距
if(speedOut >0)
{
if(ltemp > accelerationRate)             
{
speedOut +=  accelerationRate;
}//如果速度差比较多,则每次增加一个加速率。
else                                        
if( ltemp < -decelerationRate)
{
speedOut -=  decelerationRate;
}//如果是减速,同样是没次减小一个减速率
else  //否则直接跳掉设定的速度                                
{
speedOut = speedRef;
}
}
else  //方向相反,计算方法一样
{
     if(ltemp < -accelerationRate)  
     {
     speedOut -=  accelerationRate;
     }
     else                                     
     if( ltemp > decelerationRate)
     {
     speedOut +=  decelerationRate;
     }
     else                             
     {
     speedOut = speedRef;
     }
}
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
26
关闭 站长推荐上一条 /3 下一条