BLDC的双闭环老调不好,求帮助

2020-02-06 09:59发布

速度环和电流环调了好几天了,老是有问题,要么稳态偏差大,要么就振荡,片子是33FJ64MC508A,目前外部晶振为7.3728M,经PLL后得到16588800Hz的系统时钟,弄这个频率,主要是为了方便和VB6.0做串口通信,观察PID数据曲线的波特率为115200,我是1.25MS算一次速度环,算5次后算一次电流环,速度环的PID结果不作任何处理,直接作为电流环的设定值,占空比更新是在电流环里进行,刚开始请教别人说是算若干次电流环然后算一次速度环,我照这个思路来发现电机速度启振荡没法控制,然后我就改为算5次速度环才算一次电流环,这样情况有所好转,但老是有较大的稳态偏差,能从几十转/分跳到100多转/分,有时又能将速度锁定在几转/分之内,压缩包里是我的程序,做过的大侠帮我看看有哪里没对,也希望对新手有所帮助,当然我自己也是新手,共同进步哈
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
44条回答
asdmaill
2020-02-07 06:11
//----------------------------------------------------------------------
//速度闭环PID计算程序
//----------------------------------------------------------------------
void Speed_Pid(void)
{   
    //DesiredSpeed = Motor_Speed/14;
    if(Speed >= DesiredSpeed)    //计算偏差
    {
       SpeedError = Speed - DesiredSpeed;  //测量值大于给定值
       Flags.Speed_error_dir = 1;          //偏差为负数
    }
    else
    {
       SpeedError = DesiredSpeed - Speed;  //给定值大于测量值
       Flags.Speed_error_dir= 0;           //偏差为正负数
    }      
    Txbuff[4] = SpeedError >>8; //将速度偏差值存入发送缓存
    Txbuff[5] = SpeedError & 0x00FF;
    //Speed = 0x0000;   //得到偏差后,将测量到得数据清空

    if(Flags.Speed_error_dir ==0)    //偏差为正数,则积分数据和偏差相加
    {  
       SpeedIntegral = SpeedIntegral + SpeedError;  //对偏差进行积分
    }

    else  //偏差为负数,则积分数据和偏差相减  
    {
          if(SpeedIntegral>=SpeedError)  //积分大于偏差
          {
             SpeedIntegral = SpeedIntegral - SpeedError;
          }
          else //偏差大于积分
          {
             SpeedIntegral = SpeedError - SpeedIntegral;
          }
    }
           
    if(SpeedIntegral >2000)  //积分限幅
       {
         SpeedIntegral = 2000;
       }
    Speed_PID = (SpeedError + SpeedIntegral*0 )/100;
    Txbuff[8] = Speed_PID >>8;  //将电机速度PID数据存入发送缓存
    Txbuff[9] = Speed_PID & 0x00FF;
这是速度环的代码

//----------------------------------------------------------------
//电流闭环PID计算程序
//----------------------------------------------------------------
void Current_Pid(void)   
{   
    DesiredCurrent = Speed_PID;    //将速度环输出转换为电流环输入
    if(Current >= DesiredCurrent)   //计算电流偏差
    {
         CurrentError = Current - DesiredCurrent;  //测量值大于给定值
         Flags.Current_error_dir = 1;              //偏差为负
    }
    else
    {
         CurrentError = DesiredCurrent - Current;  //给定值大于测量值
         Flags.Current_error_dir= 0;               //偏差为正
    }      
    //Current = 0x0000;   //得到偏差后,将测量到的数据清空
    if(Flags.Speed_error_dir ==0)    //根据偏差方向,决定积分数据和偏差是相加还是相减
    {   
       CurrentIntegral = CurrentIntegral + CurrentError;  //对偏差进行积分
    }
    else
    {
       if(CurrentIntegral>=CurrentError)
       {
          CurrentIntegral = CurrentIntegral - CurrentError;
       }
       else
       {
          CurrentIntegral = CurrentError - CurrentIntegral;
       }
    }               
    if(CurrentIntegral >2000)  //积分限幅
       {
         CurrentIntegral = 2000;
       }
    Current_PID = (CurrentError + CurrentIntegral/20 )/20;
    if(Flags.Speed_error_dir==0)
    {
       if(DutyCycle >= 65000)
       {
          DutyCycle = 65535;
       }
       else
       {
          DutyCycle = Current_PID + DutyCycle;    //电机加速
          if(DutyCycle >=65000)
          {
             DutyCycle = 65535;
          }
       }
    }
    else                                        ////电机减速
    {
       if(DutyCycle >= Current_PID)
       {
          DutyCycle = DutyCycle - Current_PID;
       }
       else
       {
          DutyCycle = Current_PID - DutyCycle;
       }
    }
    PDC1 = DutyCycle;
    PDC2 = PDC1;
    PDC3 = PDC1;
    Txbuff[6] = DutyCycle >>8; //将电机占空比数据存入发送缓存
    Txbuff[7] = DutyCycle & 0x00FF;            
   这是电流环的代码

一周热门 更多>