PFC双环控制实战:从理论到代码的完整实现

张开发
2026/4/15 2:21:22 15 分钟阅读

分享文章

PFC双环控制实战:从理论到代码的完整实现
1. PFC双环控制的核心原理PFC双环控制是数字电源设计中的关键技术它的核心目标有两个一是让电源的输入电流波形与输入电压波形保持同相位二是确保输出电压稳定在设定值。这种控制策略在Boost PFC拓扑中尤为常见比如我们常见的电脑电源、LED驱动电源都在使用这种技术。我第一次接触PFC双环控制是在设计一款300W的AC-DC电源模块时。当时遇到的最大问题是电源的功率因数只有0.7左右远远达不到0.9的设计要求。通过引入双环控制后功率因数成功提升到了0.98效果非常明显。双环控制之所以有效是因为它将复杂的控制问题分解为两个相对独立但又相互配合的环路外环电压环像个稳重的老管家它关注的是输出电压是否稳定。这个环路的工作频率通常在10-20Hz响应速度较慢但非常稳定。内环电流环则像个敏捷的运动员它的任务是让输入电流紧紧跟随输入电压的变化。这个环路的工作频率通常在几千Hz响应速度非常快。在实际工程中这两个环路通过PI控制器协同工作。外环PI控制器输出的不是直接的PWM信号而是一个电流幅值参考信号。这个信号会与整流后的输入电压波形相乘生成内环的电流参考信号。这种设计巧妙地实现了电流波形对电压波形的跟踪。2. 硬件平台搭建与配置要实现PFC双环控制首先需要搭建合适的硬件平台。根据我的经验TI的C2000系列DSP是最常用的选择特别是TMS320F28035这款芯片它内置了高精度的PWM模块和快速的ADC非常适合做数字电源控制。硬件连接有几个关键点需要注意电压采样电路通常使用电阻分压网络将高压输出电压降到DSP可接受的0-3V范围。这里要特别注意分压电阻的精度和温度系数我推荐使用0.1%精度的金属膜电阻。电流采样电路可以使用霍尔传感器或者分流电阻。在小功率应用中我更喜欢使用分流电阻方案成本更低而且响应更快。关键是要选择低感抗的分流电阻比如Vishay的WSBS系列。PWM输出电路需要特别注意死区时间的设置。太短会导致上下管直通太长又会影响效率。根据MOSFET的开关特性我一般设置在200-500ns之间。ADC的配置也有讲究。由于我们需要同时采样输入电压和电流最好使用同步采样模式。以C2000为例可以这样配置ADCvoid InitADC(void) { AdcRegs.ADCTRL1.bit.ACQ_PS 0xF; // 采样窗口16个SYSCLK周期 AdcRegs.ADCTRL3.bit.ADCCLKPS 0x3; // 内核时钟分频 AdcRegs.ADCTRL1.bit.SEQ_CASC 1; // 级联模式 AdcRegs.ADCMAXCONV.bit.MAX_CONV 0x1; // 2个转换 AdcRegs.ADCCHSELSEQ1.bit.CONV00 0x0; // ADCINA0 AdcRegs.ADCCHSELSEQ1.bit.CONV01 0x1; // ADCINA1 }3. 外环电压控制实现细节外环电压控制是双环控制的基础它决定了整个系统的稳定性。在实际编程时有几个关键点需要特别注意首先是采样时刻的选择。由于输出电压纹波较大我建议在PWM周期的中点进行采样这样可以获得更准确的平均值。在代码中可以这样实现#pragma INTERRUPT(adc_isr, ADC_ISR) void adc_isr(void) { static Uint16 sample_count 0; if(sample_count PWM_PERIOD/2) { Vout_actual AdcRegs.ADCRESULT04; // 读取ADC结果 sample_count 0; } AdcRegs.ADCST.bit.INT_SEQ1_CLR 1; // 清除中断标志 PieCtrlRegs.PIEACK.all PIEACK_GROUP1; }PI控制器的实现是外环的核心。这里我分享一个经过实际验证的PI控制器代码typedef struct { float Kp; float Ki; float Umax; float Umin; float Ui; } PI_Controller; float PI_Update(PI_Controller *pi, float error) { pi-Ui pi-Ki * error; // 抗饱和处理 if(pi-Ui pi-Umax) pi-Ui pi-Umax; else if(pi-Ui pi-Umin) pi-Ui pi-Umin; return pi-Kp * error pi-Ui; }参数整定是另一个难点。我推荐使用工程上常用的Ziegler-Nichols方法先将Ki设为0逐渐增大Kp直到系统开始振荡记下此时的Kp值为Ku和振荡周期Tu。根据下表设置参数控制器类型KpKiPI控制器0.45*Ku0.54*Ku/Tu在实际调试中我发现这个参数往往还需要微调。一个好的经验是观察输出电压的恢复过程理想的响应应该有约10%的超调量并在3-5个周期内稳定下来。4. 内环电流控制实现技巧内环电流控制是PFC性能的关键。与电压环不同电流环需要更快的响应速度。在我的项目中电流环的控制周期通常设置为电压环的1/10左右。电流采样的准确性至关重要。这里有个实用技巧在MOSFET导通期间采样电流会引入开关噪声我建议在PWM周期的70%位置采样这时电流纹波较小。代码实现如下void InitEPwm(void) { EPwm1Regs.TBPRD PWM_PERIOD; // 设置PWM周期 EPwm1Regs.CMPA.half.CMPA PWM_PERIOD/2; // 初始占空比50% EPwm1Regs.ETSEL.bit.SOCAEN 1; // 启用SOC EPwm1Regs.ETSEL.bit.SOCASEL 1; // 计数器等于CMPB时触发 EPwm1Regs.ETPS.bit.SOCAPRD 1; // 每周期触发一次 EPwm1Regs.CMPB (int)(PWM_PERIOD * 0.7); // 在70%位置采样 }电流环PI控制器的实现与电压环类似但参数差异很大。我常用的调试方法是先设置Ki0逐步增大Kp直到电流波形开始出现轻微振荡。然后逐步增加Ki值观察电流跟踪效果。最后进行动态负载测试检查在不同负载条件下电流波形的THD总谐波失真。参考电流的生成需要特别注意。它应该是外环输出的幅值乘以整流后的输入电压波形float GetCurrentReference(float Vout_error, float Vin_rectified) { static PI_Controller voltage_pi {0.1, 5.0, 1.0, 0, 0}; static float max_current 5.0; // 最大电流限制 float Iref_amp PI_Update(voltage_pi, Vout_error); if(Iref_amp max_current) Iref_amp max_current; return Iref_amp * Vin_rectified; }5. 实际调试中的经验分享在实际调试PFC双环控制系统时我遇到过不少坑这里分享几个最有价值的经验第一个是关于ADC采样的。刚开始我直接使用DSP内置的12位ADC发现噪声很大导致控制不稳定。后来我做了三点改进1在ADC输入前加RC低通滤波截止频率设为开关频率的1/102采用过采样技术每个控制周期采样4次取平均3在软件中加入滑动平均滤波。改进后的采样稳定性大幅提升。第二个常见问题是电流环振荡。有次调试时电流波形总是出现周期性振荡检查了很久才发现是PCB布局问题电流采样走线太长引入了开关噪声。重新设计PCB后问题解决。这个经历让我明白硬件设计不好再好的控制算法也没用。第三个经验是关于保护机制的。有次测试时MOSFET突然烧毁后来分析是因为过流保护响应太慢。现在我都会在硬件和软件上做双重保护硬件比较器做ns级快速保护软件做ms级精确保护。具体实现可以参考这段代码void InitComparator(void) { Comp1Regs.DACVAL.bit.DACVAL 1023; // 设置比较阈值 Comp1Regs.CTRL.bit.COMPDACEN 1; // 启用比较器 Comp1Regs.CTRL.bit.SYNCSEL 1; // 与PWM同步 } #pragma INTERRUPT(protection_isr, PROTECTION_ISR) void protection_isr(void) { EPwm1Regs.TZFRC.bit.OST 1; // 强制PWM输出关闭 while(1); // 进入保护状态 }最后分享一个调试小技巧在调试初期可以先用函数发生器模拟ADC输入信号这样可以单独测试控制算法避免功率电路的风险。等算法调通后再接入真实信号。这个方法帮我节省了大量调试时间。

更多文章