Part Number:TMS320F28335Other Parts Discussed in Thread: CONTROLSUITE, INSTASPIN-BLDC
目前在调试无感BLDC控制
例程参考:HVBLDC_Sensorless及InstaSPIN_BLDC
我是在TMS320F28335上调试的,由于InstaSPIN_BLDC中使用的C28x_InstaSPIN_BLDC_Lib.lib只支持定点控制器,所以编写代码的时候参考了两个例程,过零点检测使用了HVBLDC_Sensorless中的“com_trig.h”。
目前调试的情况是,仅速度闭环,从一定占空比的开环强拉到速度闭环,都是正常的。
在正转基础上,增加了反转,运行异常,表位为强拉结束后进入速度闭环,母线电流迅速增加,硬件电路过流报警。
硬件平台是自己设计的,目前已经完成了:
1.PMSM无位置传感器控制,使用增强型滑膜观测器eSMO;
2.BLDC电机带霍尔传感器的转速电流双闭环控制、正反向控制
3.BLDC电机无位置传感器速度环控制、正向运行
鉴于此,我想硬件平台应该没有问题,目前BLDC无位置传感器速度环控制反向运行异常可能不是硬件电路的原因,伪代码如下,请大家帮我看看是哪里的问题
__interrupt void
BLDC_MainISR(void)
{
static Uint32 IsrTicker = 0;
// Verifying the ISR
IsrTicker++;
// Initial Rotor Alignment Process
if( g_AlignFlag != 0 )
{
转子位置对其处理;
}
else
{
母线电流采集;
母线电压采集;
// Connect inputs of the RMP module and call the Ramp control macro.
g_rc1.TargetValue = g_SpeedRef;
RC_MACRO(g_rc1)
// ——————————————————————————
// Connect inputs of the MOD6 module and call the Modulo 6 counter macro.
// ——————————————————————————
// Switch from open-loop to closed-loop operation by Ramp3DoneFlag variable
if(g_SpeedRef > _IQ(0.0))
{
g_mod_dir1.CntDirection = _IQ(1.0);
}
else
{
g_mod_dir1.CntDirection = _IQ(-1.0);
}
g_PreviousState = g_mod_dir1.Counter;
MOD6CNTDIR_MACRO(g_mod_dir1) // 使用instaSPIN_BLDC中的moddir宏函数
// ——————————————————————————
// Set the speed closed loop flag once the speed is built up to a desired value.
// ——————————————————————————
//while counting up we want positive speed
if( ( g_mod_dir1.Counter == 5 ) && ( g_PreviousState == 4 ) && g_mod_dir1.TrigInput)
{
g_speed1.TimeStamp = g_VirtualTimer;
SPEED_PR_MACRO(g_speed1);
g_SpeedLoopFlag = TRUE;
}
//while counting down we want negative speed
else if( ( g_mod_dir1.Counter == 0 ) && ( g_PreviousState == 1 ) && g_mod_dir1.TrigInput )
{
g_speed1.TimeStamp = g_VirtualTimer;
SPEED_PR_MACRO(g_speed1);
g_speed1.Speed = _IQmpy(g_speed1.Speed,_IQ(-1.0));
g_SpeedLoopFlag = TRUE;
} // 该部分代码参照instaSPIN_BLDC例程
// ——————————————————————————
// Connect inputs of the COM_TRIG module and call the Commutation trigger macro.
// ——————————————————————————
g_cmtn1.Va = AdcMirror.ADCRESULT2 * IQ12TOFLOAT – g_offset_Va;
g_cmtn1.Vb = AdcMirror.ADCRESULT3 * IQ12TOFLOAT – g_offset_Vb;
g_cmtn1.Vc = AdcMirror.ADCRESULT4 * IQ12TOFLOAT – g_offset_Vc;
g_cmtn1.CmtnPointer = g_mod_dir1.Counter;
g_cmtn1.VirtualTimer = g_VirtualTimer;
CMTN_TRIG_MACRO(g_cmtn1) // 该部分代码参照HVBLDC_Sensorless
g_mod_dir1.TrigInput = g_cmtn1.CmtnTrig; // 参照instaSPIN_BLDC例程增加了这条语句
if( ( g_rmp3.Ramp3DoneFlag == 0) || ( g_SpeedLoopFlag == FALSE ) )
{
// Connect inputs of the RMP3 module and call the Ramp control 3 macro.
g_rmp3.DesiredInput = g_CmtnPeriodTarget;
g_rmp3.Ramp3Delay = g_RampDelay;
RC3_MACRO(g_rmp3)
// Connect inputs of the IMPULSE module and call the Impulse macro.
g_impl1.Period = g_rmp3.Out;
IMPULSE_MACRO(g_impl1)
// ——————————————————————————
// Connect inputs of the MOD6 module and call the Modulo 6 counter macro.
// ——————————————————————————
g_mod_dir1.TrigInput = g_impl1.Out;
} // 该部分代码参照instaSPIN_BLDC例程
// ——————————————————————————
// Connect inputs of the RMP2 module and call the Ramp control 2 macro.
// ——————————————————————————
g_rmp2.DesiredInput = g_DfuncTesting * FLOATTOIQ15;
RC2_MACRO(g_rmp2)
// ——————————————————————————
// Connect inputs of the PID_REG3 module and call the PID speed controller macro.
// ——————————————————————————
g_pid1_spd.Ref = g_rc1.SetpointValue;
g_pid1_spd.Fbk = g_speed1.Speed;
PI_MACRO(g_pid1_spd)
if( g_SpeedRef >= 0 )
{
if( g_pid1_spd.Out < 0 )
{
g_pid1_spd.ui = 0;
g_pid1_spd.i1 = 0;
}
}
else if( g_SpeedRef < 0 )
{
if( g_pid1_spd.Out > 0 )
{
g_pid1_spd.ui = 0;
g_pid1_spd.i1 = 0;
}
}
// ——————————————————————————
// Connect inputs of the PWM_DRV module and call the PWM signal generation
// update macro.
// ——————————————————————————
// Switch from fixed duty-cycle or controlled Speed duty-cycle by SpeedLoopFlag variable
if( g_SpeedLoopFlag == FALSE )
{
g_pwm1.DutyFunc = (int16)g_rmp2.Out; //速度开环时,由斜坡函数给定占空比
g_pid1_spd.ui = _IQ(0.0);
g_pid1_spd.i1 = _IQ(0.0); //速度开环时,控制器清0
}
else
{
g_pwm1.CmtnPointer = g_mod_dir1.Counter;
g_pwm1.DutyFunc = _IQmpy(g_pid1_spd.Out * FLOATTOIQ15,g_mod_dir1.CntDirection);
BLDCPWM_MACRO(1,2,3,g_pwm1)
}
…….
}
// Reinitialize for next ADC sequence
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
}
Annie Liu:
在正转基础上,增加了反转,运行异常
目前尚不清楚改变轴旋转方向的目的是什么,或者为什么这是正常的或不符合预期的。 SW 设定的力角是否使 <1Hz 轴速度成为可能?
,
user78960159:
您好 改变专向的目的是使电机能够在无感方式下正反转运行
目前电机反转时,母线电流迅速增加并超过外置电源设置的最大电流上限导致电源报警保护,从现象看应该是反转时监测的换相点不准确导致的
1.HVBLDC_Sensorless例程,我看了下,应该只能使电机正转,不知道我说的对不对
位于\ti\controlSUITE\development_kits\DRV830x-HC-C2-KIT_v105目录下的InstaSPIN-BLDC从代码看是可以使电机正反转运行的,反向时速度环及电流环相关控制量做了取反处理,但是该工程下的C28x_InstaSPIN_BLDC_Lib.lib只支持定点控制器,所以我目前的工程参考了HVBLDC_Sensorless及InstaSPIN-BLDC两个工程,我使用的控制器是TMS320F28335,并使用了开启了FPU支持。
2.希望TI提供C28x_InstaSPIN_BLDC_Lib.lib的浮点库,并提供该库的相关说明文档,目前在controlSUITE下,该库没有任何说明文档。相比较而言,PMSM的无感控制应该会复杂些,eSMO是有其浮点库eSMO_float的。
我目前的换相处理如下,
如上图所示,这是电机正转时换相点分析。电机正转时,A相超前B相,B相超前C相。换相使用com.trig.h中的CMTN_TRIG_MACRO宏函数
无感BLDC的三段式启动:转子定位、开环强拉、速度闭环运行都没有问题。
下图为反转时换相点分析,反转时,C相超前B相,B相超前A相:
修改的CMTN_TRIG_MACRO宏函数代码如下:
#define nCMTN_TRIG_MACRO(v) \ \/* Always clear flags on entry */ \ v.CmtnTrig = 0; \ v.ZcTrig = 0; \ \/* Neutral voltage calculation (3*motor Neutral voltage) */ \ v.Neutral = v.Va + v.Vb + v.Vc; \ \/* Commutation State table Tasks*/ \/* State s1: current flows to motor windings from phase B->A, de-energized phase = C */ \ if( v.CmtnPointer == 0 ) \ { \ v.DebugBemf = _IQmpy(_IQ(3),v.Va) – v.Neutral; \ if( v.DebugBemf > 0 ) \ v.NoiseWindowCounter = 0; \ else /* Zero crossing Noise window processing */ \ NOISE_WINDOW_CNT_MACRO(v); \ DELAY_30DEG_MACRO(v) \ } /* else if-end: State s1 */ \ \/* State s2: current flows to motor windings from phase B->C, de-energized phase = A */ \ else if( v.CmtnPointer == 1 ) \ { \ v.Delay30DoneFlag = 0; \ v.DebugBemf = _IQmpy(_IQ(3),v.Vb) – v.Neutral; \ if( v.DebugBemf < 0 ) \ v.NoiseWindowCounter = 0; \ else /* Zero crossing Noise window processing */ \ NOISE_WINDOW_CNT_MACRO(v); \ } /* else if-end: State s2 */ \ \/* State s3: current flows to motor windings from phase A->C, de-energized phase = B */ \ else if( v.CmtnPointer == 2 ) \ { \ v.DebugBemf = _IQmpy(_IQ(3),v.Vc) – v.Neutral; \ if( v.DebugBemf > 0 ) \ v.NoiseWindowCounter = 0; \ else /* Zero crossing Noise window processing */ \ NOISE_WINDOW_CNT_MACRO(v); \ } /* else if-end: State s3 */ \ \/* State s4: current flows to motor windings from phase A->B, de-energized phase = C */ \ else if( v.CmtnPointer == 3 ) \ { \ v.DebugBemf = _IQmpy(_IQ(3),v.Va) – v.Neutral; \ if( v.DebugBemf < 0 ) \ v.NoiseWindowCounter = 0; \ else /* Zero crossing Noise window processing */ \ NOISE_WINDOW_CNT_MACRO(v); \ } /* else if-end: State s4 */ \ \/* State s5: current flows to motor windings from phase C->B, de-energized phase = A */ \ else if( v.CmtnPointer == 4 ) \ { \ /*v.Delay30DoneFlag = 0;*/ /* clear flag for delay calc in State 5 */ \ \ v.DebugBemf = _IQmpy(_IQ(3),v.Vb) – v.Neutral; \ if( v.DebugBemf > 0 ) \ v.NoiseWindowCounter = 0; \ else /* Zero crossing Noise window processing */ \ NOISE_WINDOW_CNT_MACRO(v); \ /*DELAY_30DEG_MACRO(v)*/ \ } /* else if-end: State s5 */ \ \/* State s6: current flows to motor windings from phase C->A, de-energized phase = B */ \ else if( v.CmtnPointer == 5 ) \ { \ /*v.Delay30DoneFlag = 0;*/ \ v.DebugBemf = _IQmpy(_IQ(3),v.Vc) – v.Neutral; \ if( v.DebugBemf < 0 ) \ v.NoiseWindowCounter = 0; \ else /* Zero crossing Noise window processing */ \ NOISE_WINDOW_CNT_MACRO(v); \ /*DELAY_30DEG_MACRO(v)*/ \ } /* else if-end: State s6 */ \ \/* Zero crossing to Commutation trigger delay */ \ v.CmtnTrig = 0; /* Always clear flag on entry */ \ \ if( v.DelayTaskPointer > 0 ) /* v.DelayTaskPointer = 1 for #CHK_TRIGGER */ \ { \ if( v.ZcTrig != 0 ) \ { \ /* Substract NoiseWindowMax to compensate the advanced zero-crossing validation point */\ v.CmtnDelayCounter = v.CmtnDelay – v.NoiseWindowMax; \ v.DelayTaskPointer = 0; /* v.DelayTaskPointer = 0 for #COUNT_DWN */ \ } \ } \ else /* v.DelayTaskPointer = 0 for #COUNT_DWN */ \ { \ v.CmtnDelayCounter -= 1; \ if( v.CmtnDelayCounter == 0 ) \ { \ v.CmtnTrig = 0x00007FFF; /* Yes!- Set trigger. This is used */ \ /* as an input to "MOD6_CNTR" module that changes the commutation sequence. */ \ \ v.DelayTaskPointer = 1; /* v.DelayTaskPointer = 1 for #CHK_TRIGGER */ \ } \}
3.不清楚为什么反转异常,我今天会重新建工程,关闭FPU支持,使用C28x_InstaSPIN_BLDC_Lib.lib调试看看情况
,
user78960159:
问题已经解决 目前无感BLDC的初始转子定位、开环强拉、无感监测换相点运行 正反转都没有问题了
上图为基于InstaSPIN-BLDC例程修改的无感BLDC正向运行
下图为无感BLDC反向运行
我将浮点28335工程修改为定点28335工程,以便能使用C28x_InstaSPIN_BLDC_Lib.lib
但是发现和com.trig.h的问题一样,反转时还是会过流。
最后使用了InstaSPIN-BLDC例程中的PWM控制宏函数,正反转就没有问题了。但是对f2803xpwm_cntl_8301.h文件中的PWM控制方式还不太理解,需要时间消化一下。
,
Annie Liu:
很高兴您的问题已经解决,谢谢您的分享!