Hi Team,
The BLDC driver is written based on level 2 in the BLDC-sensored process officially given by TI.
_iq iqVaIn;
_iq iqVbIn;
_iq IDCfdbk;
d_pwm=_IQ(1);
D_com=_IQ(0.333333333333333); //120 degree commutation
// ------------------------------------------------------------------------------
// ADC conversion and offset adjustment
// ------------------------------------------------------------------------------
iqVaIn = _IQ15toIQ((AdcResult.ADCRESULT4<<3)-BemfA_offset);
iqVbIn = _IQ15toIQ((AdcResult.ADCRESULT5<<3)-BemfA_offset);
IDCfdbk= (_IQ15toIQ(AdcResult.ADCRESULT7<<3)-IDC_offset)<<1;
d_pwm= _IQ(0.6);
Connect inputs of the HALL module and call the Hall sensor read macro.
// ------------------------------------------------------------------------------
HALL3_READ_MACRO(hall1)
if (hall1.Revolutions>=30)
ClosedFlag=TRUE;
if (hall1.CmtnTrigHall==0x7FFF) /*The following code is executed only when the hall module detects the commutation enable signal, which means that the calculation is performed once in each commutation cycle, that is, at the moment when a new commutation cycle begins.*/
{
speed2.TimeStamp = VirtualTimer; /*input of speed2*/
SPEED_PR_MACRO1(speed2)
if (hall1.Revolutions<=5){ /*because filter is fifth order so it needs five previous period value*/
speed3.EventPeriod=speed2.EventPeriod_n_1;
speed3.SUflag=TRUE;
}else{
speed3.currenttheta=rg1.Angle;
speed3.HallGpio=hall1.HallGpioAccepted;
speed3.EventPeriod=speed2.EventPeriod_n;
speed3.SUflag=FALSE;
}
SE_MACRO1(speed3)/*calculate speed*/
}
rg1.Freq = speed3.nextspeed;/*Assign the value of velocity to rg1.Freq*/
RG_MACRO(rg1)/*calculate angle*/
fa1.Angle= rg1.Out; /* motor A 0 */
fa1.phiv=_IQ(-0);/*advancing firing angle is zero*/ /* motor D 48V ~0.9/0.7Nm -0.508 */
FA_MACRO(fa1) /*add phiv with actual angle*/ /* motor C 48V ~0.7Nm -0.05 */
theta= (fa1.Out);
theta_ref1= _IQmpy(D_com,_IQ(0.5));
theta_ref2= D_com-_IQ(0.333333333333333);
if (ClosedFlag == FALSE)
{
pwmcntl1.Duty1 = _IQmpy(_IQ((hall1.HallGpioAccepted==2)||(hall1.HallGpioAccepted==3)),d_pwm);
pwmcntl1.Duty2 = _IQ(1)-(_IQ((hall1.HallGpioAccepted==5)||(hall1.HallGpioAccepted==4)));
pwmcntl1.Duty3 = _IQmpy(_IQ((hall1.HallGpioAccepted==1)||(hall1.HallGpioAccepted==5)),d_pwm);
pwmcntl1.Duty4 = _IQ(1)-(_IQ((hall1.HallGpioAccepted==6)||(hall1.HallGpioAccepted==2)));
pwmcntl1.Duty5 = _IQmpy(_IQ((hall1.HallGpioAccepted==4)||(hall1.HallGpioAccepted==6)),d_pwm);
pwmcntl1.Duty6 = _IQ(1)-(_IQ((hall1.HallGpioAccepted==3)||(hall1.HallGpioAccepted==1)));
}
else{
pwmcntl1.Duty1 = _IQ((theta>=_IQ(0.25)-theta_ref1) && (theta<_IQ(0.25)))+_IQmpy( d_pwm,_IQ(((theta>=0) && ((theta<_IQ(0.25)-theta_ref1))) || ((theta>=_IQ(0.916666666666667)-theta_ref2) && (theta<_IQ(1)))) );
pwmcntl1.Duty2 = _IQ(1)-_IQ((theta>=_IQ(0.75)-theta_ref1) && (theta<_IQ(0.75)))+_IQmpy( d_pwm,_IQ(((theta>=_IQ(0.416666666666667)-theta_ref2) && ((theta<_IQ(0.75)-theta_ref1)))) );
pwmcntl1.Duty3 = _IQ((theta>=_IQ(0.583333333333333)-theta_ref1) && (theta<_IQ(0.583333333333333)))+_IQmpy( d_pwm,_IQ(((theta>=_IQ(0.25)-theta_ref2) && ((theta<_IQ(0.583333333333333)-theta_ref1)))) );
pwmcntl1.Duty4 = _IQ(1)-_IQ( (theta>=_IQ(0)) && (theta < _IQ(0.083333333333333)) )+_IQ(((theta>=_IQ(0.083333333333333)+_IQ(1)-theta_ref1) && (theta<_IQ(1.0))))+_IQmpy( d_pwm,_IQ(((theta>=_IQ(0.75)-theta_ref2) && ((theta<_IQ(0.083333333333333)+_IQ(1)-theta_ref1)))) );
pwmcntl1.Duty5 = _IQ((theta>=_IQ(0.916666666666667)-theta_ref1) && (theta<_IQ(0.916666666666667)))+_IQmpy( d_pwm,_IQ(((theta>=_IQ(0.583333333333333)-theta_ref2) && ((theta<_IQ(0.916666666666667)-theta_ref1)))) );
pwmcntl1.Duty6 = _IQ(1)-_IQ((theta>=_IQ(0.416666666666667)-theta_ref1) && (theta<_IQ(0.416666666666667)))+_IQmpy( d_pwm,_IQ(((theta>=_IQ(0.083333333333333)-theta_ref2) && ((theta<_IQ(0.416666666666667)-theta_ref1))) || ((theta>=_IQ(0.083333333333333)-theta_ref2+_IQ(1)) && (theta<_IQ(1)))) );
}
PWM_CNTL_MACRO(pwmcntl1) /*generate PWM wave*/
The customer's program controls 6 MOSFETs independently. The settings in the EPWM macro are as follows:
#define PWM_CNTL_AQCTLA_INIT_STATE (CAU_CLEAR + CAD_SET)
#define PWM_CNTL_AQCTLB_INIT_STATE (CBU_SET + CBD_CLEAR)
The action modes of the action limiting submodules of epwmA and epwmB are opposite, which is why the duty ratio of the lower pin in the above code has an extra "1-" in front.
The customer's code can work normally when the duty cycle d_pwm is less than 0.75, but when d_pwm is greater than 0.75, after clicking run, the program will report an error directly, turn on the red light, and display overcurrent.
He observed the waveforms of PWM1A and PWM1B on the oscilloscope and found that at the beginning there would be a complementary waveform with a duty cycle of about 0.5. After that, PWM1A would keep 1 and PWM1B would keep 0. The customer suspected that this might have triggered the short circuit protection.
May I ask why a high duty cycle causes a short circuit and an error message, but there is no problem with a low duty cycle?
Regards,
Annie