【嵌入式电机控制#18】有刷直流串级控制

发布于:2025-07-30 ⋅ 阅读:(18) ⋅ 点赞:(0)

一、串级控制

        在控制理论中,串级控制是改善控制性能的一大有效方法。

        

        所谓串级控制,就是采用多个控制器串联工作,外控制器输出作为内环的输入,而内环控制器输出去控制执行器,从而提升控制效果。

        这种设计方法极大提升了控制系统的抗干扰能力

        对于电机控制系统而言,速度+电流的闭环控制,增加了对电流本身的控制,不至于在特殊时刻超调。同时,两个控制器协同工作,提高了响应时间

二、引入电流闭环后的问题        

        1.电流截至控制

        2. 积分限幅

        不详细展开讲了,这些前面都涉及到

三、双闭环

        内环:对时间要求高,实时响应需求高,采样频率高

        外环:对时间要求较低,采样频率较低。

        为什么电流需要放到内环?

        第二次工业革命时期,人类主要采用的是单电压控制。后来由于工业、军事领域对控制电路负载调制率响应速度的不断提高,电压环显得不再可靠。

        为什么电压不可靠?大家是否还记得第一次学自动控制原理时的一道例题,

        某LC系统如下:

                           

        电源电压为,

                                                 

        电容电流、电感电压在单位阶跃信号输入下的零状态响应,

                                                     

        则推导出电容两端电压为,

                                                 

        其中,

                                                                    

        两边做拉氏变换并化简得,

                                                                    

        由于是单位阶跃信号,则输入与输出之间的传递函数为,

                                                

        它很明显是个二阶系统

        电压是一个经过电感电容(近似二阶系统)后的表现值,系统滞后性很大,环路控制较慢。

        然而电流,却是直接经过一阶环节形成的,对系统变化的敏感度较高。

        根据控制量的物理形成规律,我们设计出了电压(转速)外环,电流内环的控制方法。

        当然,也有些情况下会出现电流外环,电压内环的系统,这里不做过多讲解。

四、重要控制框架介绍

        接下来介绍位置速度电流三闭环系统的控制框架,

PID_TypeDef  cPID,sPID,lPID; 
void HAL_SYSTICK_Callback(void)
{
  __IO int32_t ADC_Resul= 0;
  __IO float Volt_Result = 0;
  __IO float ADC_CurrentValue;	
    // ADC结果,电压结果,adc电流值初始化

  if(uwTick % 100 == 0)
  {    //距离环中断
    //计算计数器绝对计数值
    Sample_Pulse = (OverflowCount*CNT_MAX) + (int32_t)__HAL_TIM_GET_COUNTER(&htimx_Encoder);
    //进行距离PID
    if(Start_flag == 1)
    {
    //获得了速度占空比
      tmpPWM_DutySpd = LocPIDCalc(Sample_Pulse);
      
    //速度占空比不能超过设定最大值
      if(tmpPWM_DutySpd >= TARGET_SPEED)
        tmpPWM_DutySpd = TARGET_SPEED;
      if(tmpPWM_DutySpd <= -TARGET_SPEED)
        tmpPWM_DutySpd = -TARGET_SPEED;
    }
  }

  if(uwTick % 100 == 0)
  {
    //速度环中断
    //这里不能用获取counter再清零的方式算转速,因为我们还要算绝对位置
    //所以用两次绝对量做差算速度
    Sample_Pulse = (OverflowCount*CNT_MAX) + (int32_t)__HAL_TIM_GET_COUNTER(&htimx_Encoder);
    Spd_PPS = Sample_Pulse - LastSample_Pulse;
    LastSample_Pulse = Sample_Pulse ;
    
    //计算实际转速 脉冲总数/PPR/减速比/倍频系数 * 频率 * 单位换算
    Spd_RPM = ((((float)Spd_PPS/(float)PPR)*10.0f)*(float)60);//µ¥Î»ÊÇrpm
    
    //进行速度PID计算
    if(Start_flag == 1)
    {
      sPID.SetPoint = tmpPWM_DutySpd;
      tmpPWM_Duty = SpdPIDCalc(Spd_RPM);
      
     
      if(tmpPWM_Duty < 0)
      {
        Motor_Dir = CW;
        BDDCMOTOR_DIR_CW();
        tmpPWM_Duty = -tmpPWM_Duty;
        
      }
      else
      {
        Motor_Dir = CCW;
        BDDCMOTOR_DIR_CCW();
      }
      
      //电流占空比只能是正数,在依据占空比正负进行方向控制的同时,取绝对值
        //进行电流限幅
      if(tmpPWM_Duty >= TARGET_CURRENT)
        tmpPWM_Duty = TARGET_CURRENT;
    }
  }
  
  if(uwTick % 40 == 0)
  {
    ADC_Resul = AverSum/AverCnt ;
    //这个前面说过了
    OffsetCnt_Flag++;
    if(OffsetCnt_Flag >= 16)
    {
      if(OffsetCnt_Flag == 16)
      {
        OffSetHex /= OffsetCnt_Flag-1;
      }
      OffsetCnt_Flag = 32;
      ADC_Resul -= OffSetHex;
    }
    else 
      OffSetHex += ADC_Resul;
  
    Volt_Result = ( (float)( (float)(ADC_Resul) * VOLT_RESOLUTION) );
    ADC_CurrentValue = (float)( (Volt_Result / GAIN) / SAMPLING_RES);
    if(Volt_Result<0)
      Volt_Result = 0;
    AverCnt = 0;
    AverSum = 0;
    
    //最后的区别就在于我们电流PID输入量以速度环输出为准
    if(Start_flag == 1)
    {  
      cPID.SetPoint = tmpPWM_Duty ;
      PWM_Duty = CurPIDCalc( (int32_t)ADC_CurrentValue);
      if(PWM_Duty >= BDCMOTOR_DUTY_FULL)
        PWM_Duty = BDCMOTOR_DUTY_FULL;
      if(PWM_Duty <=0)
          PWM_Duty = 0;
      __HAL_TIM_SET_COMPARE(&htimx_BDCMOTOR,TIM_CHANNEL_1,PWM_Duty);
    }
    printf("LOC:%d Sped: %2.2f r/m Curr: %d mA \n",Sample_Pulse,
              Spd_RPM ,(int32_t)ADC_CurrentValue);
  }
}

        需要注意的是,它这里采用了占空比直接等价换算为速度的计算方式,在实际工程中大家可能需要进行合理的换算(下一小段开始简单讲述这个问题)。

        因为此章节结束后,一定会有些同学已经开始上手做项目,我将在这里梳理一遍控制系统的设计顺序,避免让大家犯错。

五、控制系统设计的前期准备

        设计一个控制系统,我们首先要搞清楚控制量是什么。在速度控制中,我们就是采取速度输入为控制量。

        其次,我们需要确定控制对象,在速度环中我们采用电机转速为控制对象。

        然后,分析执行器在开环工作下输入与控制对象的关系,这个过程称为开环建模

        开环建模不可能建立完全准确的模型,这也就让PID算法应运而生。但是,较为准确的开环建模可以与闭环构成 前馈-反馈复合控制系统,利用系统输入与输出之间较为准确的关系,快速将输出给到目标值附近,减轻了闭环系统的负担。

        对于常见的直流有刷电机,我们可以默认电机两端电压和转速是近似线性的。这意味着我们可以把占空比平均的分配到转速刻度上,换句话说我们的PWM定时器ARR可以是转速的常数倍。规则设定后,每次进行PID转PWM输出前必须进行换算。

        对于无刷、永磁等结构复杂的电机,内部硬件结构变化多端,品类区分繁杂,所以在进行闭环系统设计前我们必须进行一次较为严谨的开环建模,以提升控制性能。

六、总结 

        本专栏前半部分内容全部完结,此部分主要讲述在直流有刷背景下的经典控制算法的电机应用,是后续六步控制、FOC、弱磁等更高级控制算法的基础。

        在后续内容中,我们将揭开PID黑盒模型的外衣,利用电机中相位、磁通等更近实质的物理量,实现性能更强的控制           

        

               


网站公告

今日签到

点亮在社区的每一天
去签到