CCM PFC应用中,平均电流模式控制方法早已成为工业标准,有着非常广泛的应用,该种控制方法的简要原理图可见下图。在这种控制方法中,需要采集交流电的电压和电流波形,并将交流电压波形和电压环误差放大器(数字控制系统中是电压环PID)的输出值Vea送到乘法器。乘法器将Vea与输入交流电压的平均值相乘后,除以交流电压的有效值的平方。引入交流电压的平均值和有效值的目的是维持电压环的增益为一个定值。如果没有引入这个电路或算法,电压环的增益将会是输入电压平方倍。
电流控制信号必须尽可能的接近交流电整流后的电压波形来提升PF值,但是如果电压环的带宽太高。电压环将会调整输入电流的大小来实现PFC的输出电压稳定,这种工作模式会使输入电流的波形严重失真。因此,电压环的带宽必须远小于输入交流电压的频率。但是电压环的动态响应又必须很快,以便于快到跟得上后级负载的用电需求。所以,电压控制回路的带宽又应该稍微的高一些。
交流电压有效值平方除法器所构成的电路,可使电压环增益维持某固定值,所以控制器的带宽就可以尽可能的接近交流电的频率,来降低输出输入交流电压瞬态变化时对直流输出电压的影响。特别是当交流电压输入变化范围很大时,这个问题更显得重要。在乘法器中引入多个变量这个办法,可使电压环增益维持在恒定值。让电压环误差放大器的输出变成直接的功率控制,电压环误差放大器的输出就可直接的控制传递到负载的功率大小,下文这个例子就可以轻易到看到的这个问题。
如果电压环的输出是一个定值,而此时输入的交流电压变化两倍,则电流环控制命令会直接增大两倍(乘法器的原因)。但是在送出到电流环之前,还将会除以前馈电压信号的平方(因为乘法器中的分母项),也就是除以四倍的输入电压信号,其结果将会使送到电流环的给定值降低到原先的一半,输入电流将被迫变成之前的一半。所以可以实现:输入电压变化两倍时,输入电流变为之前的一半,就可以维持输出功率不变。(TI的设计,真脑洞大开!)
得到电流环的参考信号后iref,电流环则根据实际电感电流,输出控制值到PWM部分调整占空比。这个控制值将和三角波切割来产生可以调整的占空比。对于PWM输出级来讲,只要得到了电流环的输出值,通过配置根据不相位的三角波就能实现多路交错的功能。
******************************我是分割线******************************
下面将介绍在PSIM 9.1仿真环境里搭建用离散PID控制的2相交错CCM PFC控制模型,其中PID控制器使用C语言代码实现,可以直接转移到DSP或单片机控制中使用。在仿真环境里使用代码中的参数仿真,也具有一定的现实指导意义。
功率级部分,采样地线电流做差分放大,常规套路。取样两个MOS的开关电流波形,用作过流保护,过流保护用简单的and门实现,当电流达到设置峰值时直接关闭当前脉宽。
功率级:
控制部分:
控制器需要四个信号输入:PFC输出电压,电压环基准,交流电压波形,电感电流,其中采样频率100KHZ(可以修改),控制器也是按Ts=10us来计算。
仿真波形:
说明:图片上半部分是两路电感电流,下面则是直流母线电压。
亲爱的朋友们,是不是觉得这个仿真出来的波形很烂,我猜应该是电压环PI参数的问题?
想请各位大神们来帮忙,一起参与进来,帮我调试PI参数,帮我把波形搞好吧。(^ ^)
参考文档:
1,UCC28070A 数据手册,TI
2,UCC3854A 数据手册,TI
3,Help on the Embedded Software Block,Powersim Inc
4,PSIM User’s Guide,Powersim Inc
附录:
/**
代码如下,有兴趣的朋友可以自己增加有效值计算的代码,然后仿真电网电压快速变化的工况。
电压环:
double V_out_sen;
double V_ref = 0;
double pid_out;
double lastout = 0;
/*
*PID 控制中间变量
*/
double error_0 = 0;
double error_1 = 0;
double error_2 = 0;
double a0 = 0;
double a1 = 0;
double a2 = 0;
double Ts = 0.00001;
double kp = 0.75;
double Ti = 0.01;
double Td = 0;
/*
*PID 输出限制
*/
double out_max = 10;
double out_min = 0.1;
/*
*乘法器
*/
double V_multiplier = 0;
{
/*
*V_loop
*/
V_out_sen= in[0];
V_ref= in[1];
error_0= V_ref - V_out_sen;
a0= kp*( 1 + Ts/Ti +Td/Ts );
a1= kp*( 1 + 2*Td/Ts);
a2= kp*(Td/Ts);
pid_out= (lastout + a0 * error_0 - a1 * error_1 +a2*error_2);
if(pid_out<= out_min)
{
pid_out= out_min;
}
if(pid_out>= out_max)
{
pid_out= out_max;
}
lastout= pid_out;
error_1= error_0;
error_2= error_1;
// out[0] = pid_out;
V_multiplier= ( in[2] * pid_out);
out[0]= V_multiplier;
}
电流环:
double V_out_sen;
double pid_out;
double lastout = 0;
double V_ref = 0;
double Ts = 0.0001;
double error_0 = 0;
double error_1 = 0;
double error_2 = 0;
double a0 = 0;
double a1 = 0;
double a2 = 0;
double kp = 5;
double Ti = 0.01;
double Td = 0;
double out_max = 9.5;
double out_min = 0.1;
{
V_out_sen= in[0];
V_ref= in[1];
error_0= V_ref - V_out_sen;
a0= kp*( 1 + Ts/Ti +Td/Ts );
a1= kp*( 1 + 2*Td/Ts);
a2= kp*(Td/Ts);
pid_out=(lastout + a0 * error_0 - a1 * error_1 +a2*error_2);
if(pid_out<=out_min)
{
pid_out= out_min;
}
if(pid_out>= out_max)
{
pid_out= out_max;
}
lastout= pid_out;
error_1= error_0;
error_2= error_1;
out[0]= pid_out;
}