前言

上篇描述了STM32 Motor Control Workbench所生成的主程式架構,這邊會接續說明3個依附在主架構下的核心任務流程與架構,主要分成3個部分安全任務、中頻任務、高頻任務。其中安全任務主要是針對溫度、電壓、電流去做保護,中頻任務是在執行速度環與狀態執行,最後高頻任務是在FOC演算法執行

安全任務

__weak void TSK_SafetyTask_PWMOFF(uint8_t bMotor)
{
  /* USER CODE BEGIN TSK_SafetyTask_PWMOFF 0 */

  /* USER CODE END TSK_SafetyTask_PWMOFF 0 */
 
  uint16_t CodeReturn = MC_NO_ERROR;  //錯誤Flag
  uint16_t errMask[NBR_OF_MOTORS] = {VBUS_TEMP_ERR_MASK};//壓力溫度Flag,初始化錯誤

  //檢測溫度是否超過
  CodeReturn |= errMask[bMotor] & NTC_CalcAvTemp(pTemperatureSensor[bMotor]); /* check for fault if FW protection is activated. It returns MC_OVER_TEMP or MC_NO_ERROR */

  //檢測電流是否過大
  CodeReturn |= PWMC_CheckOverCurrent(pwmcHandle[bMotor]);                    /* check for fault. It return MC_BREAK_IN or MC_NO_FAULTS
                                                                                 (for STM32F30x can return MC_OVER_VOLT in case of HW Overvoltage) */
  if(bMotor == M1)//馬達1
  {
    CodeReturn |=  errMask[bMotor] &RVBS_CalcAvVbus(pBusSensorM1);//檢測主電壓,獲取電壓狀態
  }

  //更新狀態信息
  STM_FaultProcessing(&STM[bMotor], CodeReturn, ~CodeReturn); /* Update the STM according error code */

  //獲取狀態值
  switch (STM_GetState(&STM[bMotor])) /* Acts on PWM outputs in case of faults */
  {
  case FAULT_NOW: //當前有錯誤
    PWMC_SwitchOffPWM(pwmcHandle[bMotor]);//关闭PWM输出
  
    FOC_Clear(bMotor); //初始化電壓電流變量。
                       //此外,它清除 qd 電流 PI 控制器、電壓傳感器和SpeednTorquecontroller

    MPM_Clear((MotorPowMeas_Handle_t*)pMPM[bMotor]);//清除測量緩衝區並初始化索引
    /* USER CODE BEGIN TSK_SafetyTask_PWMOFF 1 */

    /* USER CODE END TSK_SafetyTask_PWMOFF 1 */
    break;
  case FAULT_OVER://當故障消失時,應用程序打算保持的持久狀態。 
                  //後續狀態通常是 STOP_IDLE,一旦用戶確認故障條件,狀態機就會移動。
    PWMC_SwitchOffPWM(pwmcHandle[bMotor]);//關閉PWM輸出
	/* USER CODE BEGIN TSK_SafetyTask_PWMOFF 2 */

    /* USER CODE END TSK_SafetyTask_PWMOFF 2 */
    break;
  default:
    break;
  }
}

中頻任務

__weak void MC_Scheduler(void)
{
/* USER CODE BEGIN MC_Scheduler 0 */

/* USER CODE END MC_Scheduler 0 */

  if (bMCBootCompleted == 1)//初始化完成
  {
    if(hMFTaskCounterM1 > 0u)//任务計數大於0
    {
      hMFTaskCounterM1--;//遞减
    }
    else
    {
      TSK_MediumFrequencyTaskM1();//執行中頻任务
                                  //速度環以及狀態機執行
      /* USER CODE BEGIN MC_Scheduler 1 */

      /* USER CODE END MC_Scheduler 1 */
      hMFTaskCounterM1 = MF_TASK_OCCURENCE_TICKS;//任務計數,
                                                 //MF_TASK_OCCURENCE_TICKS=(SYS_TICK_FREQUENCY/SPEED_LOOP_FREQUENCY_HZ)-1u
                                                 //SYS_TICK_FREQUENCY=2000,SPEED_LOOP_FREQUENCY_HZ = 1000
    }
    if(hBootCapDelayCounterM1 > 0u) //驅動器啟動電容器對馬達 1 充电所需的延遲計數
    {
      hBootCapDelayCounterM1--;
    }
    if(hStopPermanencyCounterM1 > 0u)//馬達1 在 STOP 狀態下的持續時間
    {
      hStopPermanencyCounterM1--;
    }
  }
  else
  {
  }
}

高頻任務

__weak uint8_t TSK_HighFrequencyTask(void)
{
  /* USER CODE BEGIN HighFrequencyTask 0 */

  /* USER CODE END HighFrequencyTask 0 */

  uint8_t bMotorNbr = 0;
  uint16_t hFOCreturn;

  uint16_t hState;  /*  only if sensorless main*/
  Observer_Inputs_t STO_Inputs; /*  only if sensorless main*/

  STO_Inputs.Valfa_beta = FOCVars[M1].Valphabeta;  /* only if sensorless*/
  if ( STM[M1].bState == SWITCH_OVER )
  {
    if (!REMNG_RampCompleted(pREMNG[M1]))
    {
      FOCVars[M1].Iqdref.q = REMNG_Calc(pREMNG[M1]);//執行斜率計算並返回狀態變量的當前值
    }
  }
  /* USER CODE BEGIN HighFrequencyTask SINGLEDRIVE_1 */

  /* USER CODE END HighFrequencyTask SINGLEDRIVE_1 */
  hFOCreturn = FOC_CurrControllerM1();//執行FOC核心算法,並返回執行完成的狀態
  /* USER CODE BEGIN HighFrequencyTask SINGLEDRIVE_2 */

  /* USER CODE END HighFrequencyTask SINGLEDRIVE_2 */
  if(hFOCreturn == MC_FOC_DURATION)//FOC執行錯誤
  {
    STM_FaultProcessing(&STM[M1], MC_FOC_DURATION, 0);//報錯
  }
  else//沒有錯誤
  {
    //檢查對齊和第一加速階段是否已完成
    bool IsAccelerationStageReached = RUC_FirstAccelerationStageReached(&RevUpControlM1);
    
    STO_Inputs.Ialfa_beta = FOCVars[M1].Ialphabeta; /*  only if sensorless*/
    
    //测量電壓
    STO_Inputs.Vbus = VBS_GetAvBusVoltage_d(&(pBusSensorM1->_Super)); /*  only for sensorless*/
    
    //獲取新的速度並更新估算的角度
    STO_PLL_CalcElAngle (&STO_PLL_M1, &STO_Inputs);
    
    //估算平均速度
    STO_PLL_CalcAvrgElSpeedDpp (&STO_PLL_M1); /*  Only in case of Sensor-less */
    
	 if (IsAccelerationStageReached == false)//如果檢查加速階段没有完成
    {
      STO_ResetPLL(&STO_PLL_M1);//覆為參數
    }
    
    //獲取馬達狀態
    hState = STM_GetState(&STM[M1]);
    
    if((hState == START) || (hState == SWITCH_OVER) || (hState == START_RUN)) /*  only for sensor-less*/
    {
      int16_t hObsAngle = SPD_GetElAngle(&STO_PLL_M1._Super);//獲取轉子角度
      VSS_CalcElAngle(&VirtualSpeedSensorM1,&hObsAngle);//更新轉子角度
    }
    /* USER CODE BEGIN HighFrequencyTask SINGLEDRIVE_3 */

    /* USER CODE END HighFrequencyTask SINGLEDRIVE_3 */
  }
  /* USER CODE BEGIN HighFrequencyTask 1 */

  /* USER CODE END HighFrequencyTask 1 */

  return bMotorNbr;
}

API使用

介紹完主要程式流程後接下來是去使用上層API使馬達轉動下表示已建立好API

主要是在程式When回圈內去設定以下2個涵式馬達就可以運轉起來

MC_ProgramSpeedRampMotor1(3000/6,1000); //設定轉速為3000
MC_StartMotor1();                                         //馬達運轉

範例參考

需要實現以下速度控制代碼參考如下

while (1)
  {
  /* USER CODE END WHILE */
   
  /* USER CODE BEGIN 3 */
   MC_ProgramSpeedRampMotor1(3000/6,1000); //設定轉速為3000
   MC_StartMotor1();                                         //馬達運轉
   HAL_Delay(10000);                                        //延時10S
   MC_ProgramSpeedRampMotor1(5000/6,1000); //設定轉速為5000
   HAL_Delay(10000);
   MC_ProgramSpeedRampMotor1(2000/6,1000); //設定轉速為2000
   HAL_Delay(10000);
   MC_StopMotor1();                                         //馬達停轉
   HAL_Delay(5000);                                         //延時5S
  }
  /* USER CODE END 3 */

1 thought on “Motor Control Workbench 程式架構-2”

  1. Pingback: Motor Control Workbench 程式架構 - AMS and STM32

Leave a Comment

Your email address will not be published. Required fields are marked *

Shopping Cart