之前尝试过用SiC器件研发了一款图腾柱PFC整流器,别的不说,这SiC是真的耐造。从头到尾,竟然没有炸过任何一片SiC MOSFET。
然后最近在做一款高功密的2kW Boost样机,换了配方,用了GaNsystem公司的氮化镓器件,于是,有了我的“处女炸”。
炸机的主要原因是软起动的逻辑没有处理好。
正文刚开始的启动逻辑正常的启动顺序:(状态机state)- 刚启动dsp:state = ColdMachine,此时,PWM信号被封锁,开关管关断。DSP根据采样判断输入电压的范围,如果在允许的范围内,则进入软起动阶段,state = SoftStart。
- 软起动state = SoftStart:此时利用rmp程序,逐步增加电压环的参考电压,PID程序开始运行。直到软起动完成(根据软起动标志位判断),进入正常工作状态,state = NORM;
- 正常工作state = NORM:电压外环的参考电压为目标值,固定不变;PID正常工作。注意,此时积分量占据了PID输出的绝大部分。如果在此状态下判断输入电压超出正常范围,则进入冷机状态,封锁PWM,state = ColdMachine。
但是,我们忽略了一个点,用状态机是没有错的,这样可以避免输入电压在正常范围边界时候产生的控制震荡,但是,我们忘了在从NORM进入ColdMachine状态时清零PID控制器。
正如上文提到,在NORM时,PID的积分量输出是主导的。也就是说,在从NORM进入ColdMachine之后,如果再进入SoftStart状态,此时PID的输出依然是和在进入ColdMachine之前的NORM状态保持一致的,而软起动阶段,电压外环的参考值和采样值都比较小,对PID控制器的积分量贡献不大,积分量依旧保持了一个较大值。
举个栗子
在正常时候,Boost的输入电压为140V,输出为400V。则稳定时的占空比大概在0.7左右。如果这个时候140V忽然降为零,机器进入Cold状态,当140V又忽然回来的时候,进入软起动的时候,占空比依然是0.7,而且会在0.7附近待好久。而我们正常的软起动,其占空比应当是从最小占空比开始慢慢增加的(不管软起动的原理是什么,其表现在占空比上面的效果应该是这样的。)。跑一下仿真,占空比在0.7左右和0.2(下限)左右,运行40ms,看一下电路表现有什么区别。
LT-spice仿真电路如下。
如果占空比在0.2左右,则电流如下:
如果占空比在0.7左右,电流如下:
二者的电流峰值是差不多的,但是,电流的积分(能量)完全不一样,虽然只跑了40ms,但是这两种电流在开关管中产生的热量不在一个数量级,因此,在我们刚开始的启动逻辑下,片子是很容易过热炸机的。
当然,我们用了一个半桥两片管子,这两篇肯定不是一起炸的,先炸掉的应该是流过电流更大(或者说电流占空比更大的一个,也就是电感充电路径上的开关管,在上面的电路图中对应M)来了,热乎的。
正常工作state = NORM:电压外环的参考电压为目标值,固定不变;PID正常工作。注意,此时积分量占据了PID输出的绝大部分。如果在此状态下判断输入电压超出正常范围,则进入冷机状态,封锁PWM,state = ColdMachine,初始化PID控制器。
调整后的中断程序如下,相比源程序,在进入ColdMachine状态时,初始化了PID控制器,清空了软起动标志,如下:
完整的中断服务子程序如下:
/* ISR definition */interrupt void ISR1(void){ samplecounter_a++; v_out = ((signed int)(AdcResult.ADCRESULT0 - V_OUT_BIAS)) / GAIN_VOUT; v_in = ((signed int)(AdcResult.ADCRESULT1 - V_IN_BIAS)) / GAIN_VIN; //state = NORM; switch(state) { case COLD_MACHINE: /* Shut down */ // Set GPIO4 high as the dirver enable bit EALLOW; GpioDataRegs.GPACLEAR.bit.GPIO4 = 1; // DISENABLE GaN devices EDIS; rc1.SetpointValue = (float)(0.0/VOUT_REF); rc1.TargetValue = 1.0; if((v_in > VIN_LOW)&(v_in < VIN_HIGH)) { state = SOFT_START; } break; case SOFT_START: /* Operating */ RC_MACRO(rc1); V_Controller.term.Ref = VOUT_REF * rc1.SetpointValue; V_Controller.term.Fbk = v_out; PID_GRANDO_F_FUNC(&V_Controller); dutycycle = V_Controller.term.Out; EALLOW; EPwm4Regs.CMPA.half.CMPA = floor((1.0-dutycycle) * PRD); EDIS; EALLOW; GpioDataRegs.GPASET.bit.GPIO4 = 1; // ENABLE GaN devices EDIS; if (rc1.EqualFlag == 0x7FFFFFFF) state = NORM; break; case NORM: V_Controller.term.Ref = VOUT_REF; V_Controller.term.Fbk = v_out; PID_GRANDO_F_FUNC(&V_Controller); dutycycle = V_Controller.term.Out; EALLOW; GpioDataRegs.GPASET.bit.GPIO4 = 1; // DISENABLE GaN devices EDIS; EALLOW; EPwm4Regs.CMPA.half.CMPA = floor((1.0-dutycycle) * PRD); EDIS; if((v_in < VIN_LOW)||(v_in > VIN_HIGH)) { state = COLD_MACHINE; rc1.EqualFlag = 0; // Reset PID PID_GRANDO_F_init(&V_Controller); V_Controller.param.Kp = KP_V; V_Controller.param.Ki = KI_V; V_Controller.param.Kd = KD_V; V_Controller.param.Umax = UMAX_V; V_Controller.param.Umin = UMIN_V; } break; } AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; //DELAY_US(2);}关键点2另外,输出电容的大小对于启动电流的影响也是比较大的。在上面的仿真中,我们把输出电容设置为300uF,电流波形是这样的
而如果把输出稳压电容换成30uF,电流波形如下:
而3uF对应的电流波形是这样的
而在此处的应用中,我们根本就不需要这么大的输出电容。
图中纹波从大到小分别对应着输出电容1uF, 3uF, 30uF, 300uF。
输出电容的大小应当根据电压纹波率进行选取,而不是越大越好。
电容的计算公式:
C > I o , m a x D m a x f s w Δ V C>\frac{I_{o,max}D_{max}}{f_{sw}\Delta V}C>fswΔVIo,maxDmax