前言
上篇描述了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 */
Pingback: Motor Control Workbench 程式架構 - AMS and STM32