Part Number: TMS320F28069M
Other Parts Discussed in Thread: MOTORWARE
Tool/software: Code Composer Studio
My project change form motorWare proj-13e to 2 motor control。 Each motor can run alone ,but can not Running simultaneously 。 first run motor 1 normal,then run motor 2 ,
Start when executing the following program ,Very large current , achieve 40A !!! ( #define USER_MOTOR_MAX_CURRENT (20.0))
// if we are forcing alignment, using the Rs Recalculation, align the eQEP angle with the rotor angle
if((EST_getState(obj->estHandle) == EST_State_Rs) && (USER_MOTOR_TYPE == MOTOR_Type_Pm))
{
ENC_setZeroOffset(encHandle[HAL_MTR1], (uint32_t)(HAL_getQepPosnMaximum(halHandle,HAL_MTR1) - HAL_getQepPosnCounts(halHandle,HAL_MTR1)));
}
for(;;)
{
// Waiting for enable system flag to be set
while(!(gMotorVars[motorNum].Flag_enableSys));
// Dis-able the Library internal PI. Iq has no reference now
if( gMotorVars[HAL_MTR1].Flag_enableUserParams == false )
{
CTRL_setFlag_enableSpeedCtrl(ctrlHandle[HAL_MTR1], true);
}
else
{
CTRL_setFlag_enableSpeedCtrl(ctrlHandle[HAL_MTR1], false);
}
if( gMotorVars[HAL_MTR2].Flag_enableUserParams == false )
{
CTRL_setFlag_enableSpeedCtrl(ctrlHandle[HAL_MTR2], true);
}
else
{
CTRL_setFlag_enableSpeedCtrl(ctrlHandle[HAL_MTR2], false);
}
// loop while the enable system flag is true
while(gMotorVars[motorNum].Flag_enableSys)
{
for(motorNum=HAL_MTR1; motorNum<=HAL_MTR2; motorNum++ )
{
CTRL_Obj *obj = (CTRL_Obj *)ctrlHandle[motorNum];
ST_Obj *stObj = (ST_Obj *)stHandle[motorNum];
// increment counters
gCounter_updateGlobals[motorNum]++;
// enable/disable the use of motor parameters being loaded from user.h
CTRL_setFlag_enableUserMotorParams(ctrlHandle[motorNum],gMotorVars[motorNum].Flag_enableUserParams);
// enable/disable Rs recalibration during motor startup
EST_setFlag_enableRsRecalc(obj->estHandle,gMotorVars[motorNum].Flag_enableRsRecalc);
// enable/disable automatic calculation of bias values
CTRL_setFlag_enableOffset(ctrlHandle[motorNum],gMotorVars[motorNum].Flag_enableOffsetcalc);
if(CTRL_isError(ctrlHandle[motorNum]))
{
// set the enable controller flag to false
CTRL_setFlag_enableCtrl(ctrlHandle[motorNum],false);
// set the enable system flag to false
gMotorVars[motorNum].Flag_enableSys = false;
// disable the PWM
HAL_disablePwm(halHandle,motorNum);
}
else
{
// update the controller state
bool flag_ctrlStateChanged = CTRL_updateState(ctrlHandle[motorNum]);
// enable or disable the control
CTRL_setFlag_enableCtrl(ctrlHandle[motorNum], gMotorVars[motorNum].Flag_Run_Identify);
if(flag_ctrlStateChanged)
{
CTRL_State_e ctrlState = CTRL_getState(ctrlHandle[motorNum]);
if(ctrlState == CTRL_State_OffLine)
{
// enable the PWM
HAL_enablePwm(halHandle,motorNum);
}
else if(ctrlState == CTRL_State_OnLine)
{
if(gMotorVars[motorNum].Flag_enableOffsetcalc == true)
{
// update the ADC bias values
HAL_updateAdcBias(halHandle,motorNum);
}
else
{
// set the current bias
HAL_setBias(halHandle,HAL_SensorType_Current,0,_IQ(I_A_offset),motorNum);
HAL_setBias(halHandle,HAL_SensorType_Current,1,_IQ(I_B_offset),motorNum);
HAL_setBias(halHandle,HAL_SensorType_Current,2,_IQ(I_C_offset),motorNum);
// set the voltage bias
HAL_setBias(halHandle,HAL_SensorType_Voltage,0,_IQ(V_A_offset),motorNum);
HAL_setBias(halHandle,HAL_SensorType_Voltage,1,_IQ(V_B_offset),motorNum);
HAL_setBias(halHandle,HAL_SensorType_Voltage,2,_IQ(V_C_offset),motorNum);
}
// Return the bias value for currents
gMotorVars[motorNum].I_bias.value[0] = HAL_getBias(halHandle,HAL_SensorType_Current,0,motorNum);
gMotorVars[motorNum].I_bias.value[1] = HAL_getBias(halHandle,HAL_SensorType_Current,1,motorNum);
gMotorVars[motorNum].I_bias.value[2] = HAL_getBias(halHandle,HAL_SensorType_Current,2,motorNum);
// Return the bias value for voltages
gMotorVars[motorNum].V_bias.value[0] = HAL_getBias(halHandle,HAL_SensorType_Voltage,0,motorNum);
gMotorVars[motorNum].V_bias.value[1] = HAL_getBias(halHandle,HAL_SensorType_Voltage,1,motorNum);
gMotorVars[motorNum].V_bias.value[2] = HAL_getBias(halHandle,HAL_SensorType_Voltage,2,motorNum);
// enable the PWM
HAL_enablePwm(halHandle,motorNum);
}
else if(ctrlState == CTRL_State_Idle)
{
// disable the PWM
HAL_disablePwm(halHandle,motorNum);
gMotorVars[motorNum].Flag_Run_Identify = false;
}
if((CTRL_getFlag_enableUserMotorParams(ctrlHandle[motorNum]) == true) &&
(ctrlState > CTRL_State_Idle) &&
(gMotorVars[motorNum].CtrlVersion.minor == 6))
{
// call this function to fix 1p6
USER_softwareUpdate1p6(ctrlHandle[motorNum]);
}
}
}
if(EST_isMotorIdentified(obj->estHandle))
{
// set the current ramp
EST_setMaxCurrentSlope_pu(obj->estHandle,gMaxCurrentSlope[motorNum]);
gMotorVars[motorNum].Flag_MotorIdentified = true;
// set the speed reference
CTRL_setSpd_ref_krpm(ctrlHandle[motorNum],gMotorVars[motorNum].SpeedRef_krpm);
// set the speed acceleration
CTRL_setMaxAccel_pu(ctrlHandle[motorNum],_IQmpy(MAX_ACCEL_KRPMPS_SF,gMotorVars[motorNum].MaxAccel_krpmps));
// enable the SpinTAC Speed Controller
if( ctrlMode[motorNum] == speed )
{
STVELCTL_setEnable(stObj->velCtlHandle, true);
STPOSCTL_setEnable(stObj->posCtlHandle, false);
}
else
{
STVELCTL_setEnable(stObj->velCtlHandle, false);
STPOSCTL_setEnable(stObj->posCtlHandle, true);
}
if(EST_getState(obj->estHandle) != EST_State_OnLine)
{
// if the estimator is not running, place SpinTAC into reset
STVELCTL_setEnable(stObj->velCtlHandle, false);
STPOSCTL_setEnable(stObj->posCtlHandle, false);
// If motor is not running, feed the position feedback into SpinTAC Position Move
STPOSMOVE_setPositionStart_mrev(stObj->posMoveHandle, STPOSCONV_getPosition_mrev(stObj->posConvHandle));
}
if(Flag_Latch_softwareUpdate[motorNum])
{
Flag_Latch_softwareUpdate[motorNum] = false;
USER_calcPIgains(ctrlHandle[motorNum]);
// initialize the watch window kp and ki current values with pre-calculated values
gMotorVars[motorNum].Kp_Idq = CTRL_getKp(ctrlHandle[motorNum],CTRL_Type_PID_Id);
gMotorVars[motorNum].Ki_Idq = CTRL_getKi(ctrlHandle[motorNum],CTRL_Type_PID_Id);
gMotorVars[motorNum].Kp_spd = CTRL_getKp(ctrlHandle[motorNum],CTRL_Type_PID_spd);
gMotorVars[motorNum].Ki_spd = CTRL_getKi(ctrlHandle[motorNum],CTRL_Type_PID_spd);
// initializes the value for GoalSpeed and TorqueRampTime
gMotorVars[motorNum].SpinTAC.VelIdGoalSpeed_krpm = _IQmpy(STVELID_getGoalSpeed(stObj->velIdHandle), _IQ(ST_SPEED_KRPM_PER_PU));
gMotorVars[motorNum].SpinTAC.VelIdTorqueRampTime_sec = STVELID_getTorqueRampTime_sec(stObj->velIdHandle);
STVELID_setSensorlessFeedback(stObj->velIdHandle, false);
// initialize the watch window Bw value with the default value
gMotorVars[motorNum].SpinTAC.VelCtlBw_radps = STVELCTL_getBandwidth_radps(stObj->velCtlHandle);
// initialize the watch window with maximum and minimum Iq reference
gMotorVars[motorNum].SpinTAC.VelCtlOutputMax_A = _IQmpy(STVELCTL_getOutputMaximum(stObj->velCtlHandle), _IQ(USER_IQ_FULL_SCALE_CURRENT_A));
gMotorVars[motorNum].SpinTAC.VelCtlOutputMin_A = _IQmpy(STVELCTL_getOutputMinimum(stObj->velCtlHandle), _IQ(USER_IQ_FULL_SCALE_CURRENT_A));
gMotorVars[motorNum].SpinTAC.PosCtlBw_radps = STPOSCTL_getBandwidth_radps(stObj->posCtlHandle);
// initialize the watch window with maximum and minimum Iq reference
gMotorVars[motorNum].SpinTAC.PosCtlOutputMax_A = _IQmpy(STPOSCTL_getOutputMaximum(stObj->posCtlHandle), _IQ(USER_IQ_FULL_SCALE_CURRENT_A));
gMotorVars[motorNum].SpinTAC.PosCtlOutputMin_A = _IQmpy(STPOSCTL_getOutputMinimum(stObj->posCtlHandle), _IQ(USER_IQ_FULL_SCALE_CURRENT_A));
}
}
else
{
Flag_Latch_softwareUpdate[motorNum] = true;
// the estimator sets the maximum current slope during identification
gMaxCurrentSlope[motorNum] = EST_getMaxCurrentSlope_pu(obj->estHandle);
}
// when appropriate, update the global variables
if(gCounter_updateGlobals[motorNum] >= NUM_MAIN_TICKS_FOR_GLOBAL_VARIABLE_UPDATE)
{
// reset the counter
gCounter_updateGlobals[motorNum] = 0;
updateGlobalVariables_motor(ctrlHandle[motorNum], stHandle[motorNum],motorNum);
}
if(gMotorVars[motorNum].Flag_enableUserParams == true)
{
// update Kp and Ki gains
updateKpKiGains(ctrlHandle[motorNum],motorNum);
}
else
{
if(CTRL_getMotorType(ctrlHandle[motorNum]) == MOTOR_Type_Induction)
{
// recalculate Kp and Ki gains to fix the R/L limitation of 2000.0, and Kp limit to 0.11
recalcKpKi(ctrlHandle[motorNum]);
// set electrical frequency limit to zero while identifying an induction motor
setFeLimitZero(ctrlHandle[motorNum]);
// calculate Dir_qFmt for acim motors
acim_Dir_qFmtCalc(ctrlHandle[motorNum]);
}
else
{
// recalculate Kp and Ki gains to fix the R/L limitation of 2000.0, and Kp limit to 0.11
// as well as recalculates gains based on estimator state to allow low inductance pmsm to id
recalcKpKiPmsm(ctrlHandle[motorNum]);
// calculate an Ls qFmt that allows ten times smaller inductance compared to Lhf
CTRL_calcMax_Ls_qFmt(ctrlHandle[motorNum], &gMax_Ls_qFmt);
gLs_pu = EST_getLs_d_pu(obj->estHandle);
gLs_qFmt = EST_getLs_qFmt(obj->estHandle);
}
}
// update Kp and Ki gains
// updateKpKiGains(ctrlHandle[motorNum],motorNum);
// set the SpinTAC (ST) bandwidth scale
STVELCTL_setBandwidth_radps(stObj->velCtlHandle, gMotorVars[motorNum].SpinTAC.VelCtlBw_radps);
// set the maximum and minimum values for Iq reference
STVELCTL_setOutputMaximums(stObj->velCtlHandle, _IQmpy(gMotorVars[motorNum].SpinTAC.VelCtlOutputMax_A, _IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A)), _IQmpy(gMotorVars[motorNum].SpinTAC.VelCtlOutputMin_A, _IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A)));
STPOSCTL_setBandwidth_radps(stObj->posCtlHandle, gMotorVars[motorNum].SpinTAC.PosCtlBw_radps);
// set the maximum and minimum values for Iq reference
STPOSCTL_setOutputMaximums(stObj->posCtlHandle, _IQmpy(gMotorVars[motorNum].SpinTAC.PosCtlOutputMax_A, _IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A)), _IQmpy(gMotorVars[motorNum].SpinTAC.PosCtlOutputMin_A, _IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A)));
// enable/disable the forced angle
EST_setFlag_enableForceAngle(obj->estHandle,gMotorVars[motorNum].Flag_enableForceAngle);
// enable or disable power warp
CTRL_setFlag_enablePowerWarp(ctrlHandle[motorNum],gMotorVars[motorNum].Flag_enablePowerWarp);
} // end of for(motorNum=HAL_MTR1; motorNum<=HAL_MTR2; motorNum++ ) loop
} // end of while(gFlag_enableSys) loop
// disable the PWM
HAL_disablePwm(halHandle,HAL_MTR1);
HAL_disablePwm(halHandle,HAL_MTR2);
// set the default controller parameters (Reset the control to re-identify the motor)
CTRL_setParams(ctrlHandle[HAL_MTR1],&gUserParams[HAL_MTR1]);
CTRL_setParams(ctrlHandle[HAL_MTR2],&gUserParams[HAL_MTR2]);
gMotorVars[HAL_MTR1].Flag_Run_Identify = false;
gMotorVars[HAL_MTR2].Flag_Run_Identify = false;
// setup the SpinTAC Components
ST_setupPosConv(stHandle[HAL_MTR1]);
ST_setupVelId(stHandle[HAL_MTR1]);
ST_setupVelCtl(stHandle[HAL_MTR1]);
ST_setupPosCtl(stHandle[HAL_MTR1]);
ST_setupPosMove(stHandle[HAL_MTR1]);
gMotorVars[HAL_MTR1].MaxVel_krpm = 0;
ST_setupPosConv(stHandle[HAL_MTR2]);
ST_setupVelId(stHandle[HAL_MTR2]);
ST_setupVelCtl(stHandle[HAL_MTR2]);
ST_setupPosCtl(stHandle[HAL_MTR2]);
ST_setupPosMove(stHandle[HAL_MTR2]);
gMotorVars[HAL_MTR2].MaxVel_krpm = 0;
} // end of for(;;) loop



