原创 步进电机驱动-dsPIC33F步进电机驱动程序解读-状态机轮转

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

 

/******************************************************************************
* Function:     StateMachine()
状态机函数,一共三个运行,关闭和初始化
*******************************************************************************/
void StateMachine(void)
{
    if(state == STATE_RUN)  //运行状态             
{
if( buttonCounter > BUTTON_FILTER)//按键识别
{
if((BUTTON_PIN == 1) && (speedOut < PI_ANTI_WINDUP_SPEED))
                        //按键确实按下,且速度不是很快的情况下。
{
buttonCounter = 0;       //按键识别完后,计数清零
                if(fullStepMode == FULLSTEP_TWO_PHASE_ON)      //如果是两相导通,则设置为波形模式
                {
                    fullStepMode = FULLSTEP_WAVE_DRIVE;     
                }
                else                                             
                {   
     if(stepSize >= MAX_STEP_RESOLUTION)//细分为64细分或者更高,则切换到整步模式
             {
     stateCopy = STATE_OFF;          //切换状态到OFF
     fullStepMode = FULLSTEP_TWO_PHASE_ON;  //设置到整步模式
                                        stepSize = ST_FULLSTEP;         //设置为整步
                                        stepSizeCopy = stepSize;           //同步一下变量
                                        stepSizeCount = (TABLE_SIZE)>>(stepSize);//整步模式,一步跨到最高的点
     }
     else    
     {
          stepSize++;   //按键一次,细分数+1               
                                         stepSizeCopy = stepSize;//同步参数
                                         stepSizeCount = (TABLE_SIZE)>>(stepSize);   //这个参数保存的是跨度,比如为1时 
                                                                                                                      //跨度为256,为2时,跨度为127.     
     }                                                     
                }         
}
}
//以上按键事件处理完。然后处理DMCI设置的参数改变
    if(stepSizeCopy != stepSize )
    {
            //如果细分是在整步到64细分的中间状态
         if(stepSizeCopy <=MAX_STEP_RESOLUTION && stepSizeCopy >= ST_FULLSTEP)
         {
   //在速度太大,超过抗饱和状态,就不允许进行细分切换
             if(speedOut <PI_ANTI_WINDUP_SPEED)
                {             
                 stepSize = stepSizeCopy;   //速度不大,将DMCI设置的参数读取                        
                 stepSizeCount = (TABLE_SIZE)>>(stepSize);  //设置跨度数据
             }                                                     
        }
        else     //如果是在整步和64细分状态下,则不能切换细分
        {
            stepSizeCopy = stepSize;        //返回现在的细分状态
        }
    }
            //如果DMCI请求一个电流模式的切换
    if (uGF.currentControlLoop != uGF.currentControlLoopCopy)
            {
                //这种模式下,需要关闭中断,关闭PWM,和复位定时器,总的来说,脱机。
                IEC0bits.T3IE = 0;      //关闭定时器中断
                IEC0bits.AD1IE = 0;  // 关闭AD中断
                //关闭PWM通道
         P2OVDCON = 0;
         P1OVDCON = 0;
                //关闭PWM和复位定时器
             P1TCONbits.PTEN = 0;
             P2TCONbits.PTEN = 0;
     P1TMR = 0;
     P2TMR = 0;
      //复位定时器
             T2CONbits.TON = 0;
               TMR2 =0;
               TMR3 =0;
          if (uGF.currentControlLoop==ON) 
            {
                maxRefValue = OPEN_LOOP_VOLTAGE;  //开环电压设置     
                CalcStep();                                                    //计算微步         
                uGF.currentControlLoop = OFF;                 //电流环控制关闭     
                uGF.currentControlLoopCopy = OFF;        //同步变量也关闭  
            }
            else                                        
            {
                maxRefValue = CLOSED_LOOP_CURRENT;     //闭环电流模式
                InitPI();                                                                  //初始化PI
                CalcStep();                                                            //计算微步
                uGF.currentControlLoop = ON;                         //电流环控制打开
                uGF.currentControlLoopCopy = ON;                //同步变量打开
            }
            //重启PWM进入RUN模式
                P1TCONbits.PTEN = 1;
         P2TCONbits.PTEN = 1;
            //以及重新打开关闭的中断和开启定时器
            IEC0bits.T3IE = 1;      
            IEC0bits.AD1IE = 1;
            T2CONbits.TON = 1; 
        }
 //如果按键或者DMCI要求切换状态
        if(state!=stateCopy )
        {
            state = STATE_OFF;   //只有切换到OFF状态才有效
            stateCopy = state;  //加载状态
           //关闭PWM
         P1TCONbits.PTEN = 0;
         P2TCONbits.PTEN = 0;  
            P2OVDCON = 0;
            P1OVDCON = 0;
            //速度到0
            speedOut = 0;
         }
    //定时器溢出
     if(uGF.timer1_InterruptFlag)
{
                    SpeedPositionControl();                 
                    uGF.timer1_InterruptFlag = 0;
}
}
//状态机RUN状态完毕
else
if (state==STATE_OFF)           
{
if( buttonCounter > BUTTON_FILTER)
{
if(BUTTON_PIN == 1)     
{
                 buttonCounter = 0;     
    stateCopy = STATE_RUN;  
}
}
            //以上处理按键,切换到RUN状态
if(state!=stateCopy)
                    {           
                    state = STATE_RUN;          //只能切换到RUN状态
                    state=stateCopy;     //同步一下状态
                    CalcStep();                     
            CalcDecay();                    
                    InitPI();//复位一下PI
                 //使能PWM输出
                    P1TCONbits.PTEN = 1;
            P2TCONbits.PTEN = 1;
            //定时器1中断,调用速度和位置控制器
            uGF.timer1_InterruptFlag =1;
        }
    else
    //初始化状态
    if (state==STATE_INIT)  
{
InitControlMode();
InitStepper();
InitPI();
state = STATE_OFF;     //切换到OFF状态
stateCopy = state;       //同步变量
}
}
 
/******************************************************************************
* Function:     CalcDecay()
此函数根据查找表,设置寄存器的值,用来设置衰减的模式
*******************************************************************************/
void CalcDecay()
{
    int temp; 
    #ifdef BIPOLAR//两相混合式电机
        temp = 0;
     temp = decayTableBipolar[setDir2][decay2];//表1-1,此时为00001010 00001010
     ovdPwm2 = temp >> 2;                    
     ovdPwm1 = decayTableBipolar[setDir1][decay1]+(temp<<4); 
     //根据temp计算出ovdPwm1的值,在setPWM中赋值给寄存器。
}
/******************************************************************************
* Function:     SetPWM()
//根据计算的值设置占空比等寄存器。
*******************************************************************************/
void SetPWM()
{
P2OVDCON = ovdPwm2;
P1OVDCON = ovdPwm1; 
     P1DC1 = pwmOut1;
     P1DC2 = pwmOut1;
     P1DC3 = pwmOut2;
     P2DC1 = pwmOut2;
}
 

文章评论0条评论)

登录后参与讨论
我要评论
0
26
关闭 站长推荐上一条 /2 下一条