仿真波形一片完美,样机一上电就给你脸色看——这是我做第一台数字控制图腾柱PFC时最深刻的记忆。上篇我们把拓扑演变、工作模态和仿真验证讲完了,这篇直接从样机切入,说说从原理图到稳定运行之间那些文档不会写的细节。数字控制图腾柱PFC的难点从来不在"能不能用",而在"换流细节、采样时机、模式切换、环路折中"这些实际工程问题。文章按硬件选型、软件架构、过零点处理、环路整定、保护实测、PCB与EMC的顺序展开,适合正在做PFC、想上手数字电源控制、或者被过零毛刺折磨得想摔示波器的同行参考。
1. 样机硬件从图纸到PCB:那些拍板时刻的取舍逻辑
1.1 功率级选型:GaN与Si MOSFET的性价比分界线
图腾柱PFC对高频桥臂的要求只有一个词:没有反向恢复。低频桥臂Q1/Q2工作在工频换流,用普通CoolMOS甚至IGBT都没问题;高频桥臂Q3/Q4如果有体二极管反向恢复电荷,在AC过零点附近换流时就会产生很大的电流尖峰,轻则THD恶化,重则直接炸机。所以第一版样机我把高频桥臂定为GaN HEMT,低频桥臂用传统Si MOSFET,这是最稳妥的混合方案。
具体功率等级怎么选?我的判断标准是这样的:
| 功率范围 | 高频桥臂推荐 | 理由 |
|---|---|---|
| 100W以下 | Si MOSFET + CrM临界模式 | 峰值电流小,反向恢复影响有限,成本敏感 |
| 100W~300W | Si MOSFET(低Qg)+ 准临界/谷值开通 | 性价比最高,难点在过零处理 |
| 300W~1kW | GaN HEMT + CCM连续模式 | 高频开关优势明显,散热压力小 |
| 1kW以上 | GaN或SiC + 交错并联 | 单管电流应力太大,必须分摊损耗 |
我做的600W样机,高频桥臂选了650V GaN,低频桥臂选了一颗很普通的600V CoolMOS。GaN栅极耐压窗口窄(通常±20V以内,推荐工作区更窄),驱动电路必须单独设计,不能直接套Si管的驱动。
1.2 驱动电路设计:共源电感是这个拓扑的第一杀手
图腾柱PFC高频桥臂的换流速度非常快,di/dt轻松超过1A/ns。这种速率下,功率回路和驱动回路如果共用了一小段源极寄生电感,那这个电感上就会感应出压降,直接叠加在Vgs上。开关节点电流在几纳秒内反向,共源电感上的压降可能是负的几伏——GaN管在这种负压尖峰下很容易触发误导通,上下管直通,然后你听见的就是一声闷响。
处理办法有三条,缺一不可:
第一,驱动芯片必须用开尔文连接,驱动回路单独走线,功率电流绝对不允许流过驱动芯片的GND引脚这个回路。我给驱动IC专门开了一条从源极焊盘直接回到驱动芯片GND的走线,宽度不用太大,但路径要短。
第二,驱动电阻分开通和关断两路。开通电阻取2.2Ω~4.7Ω,关断电阻取0Ω~1Ω,中间用一个小二极管隔离。实测下来,关断回路阻抗低对防止误导通的作用比"调大负压"更明显。
第三,GaN建议用负压关断。很多GaN驱动芯片自带负压,也可以用简单的电平转换电路把关断电平拉到-2V到-3V。别小看这负压,换流过程中SW节点振铃能在米勒电容上耦合出几伏的尖峰,负压关断是最后一道防线。
驱动隔离方面,我用了数字隔离驱动,内置死区时间,死区设置可以软件调,也可以外部电阻定。对于600W这个量级,隔离驱动的传输延迟和共模瞬态抑制(CMTI)指标要比普通光耦好得多。尤其是AC过零点换流那一下,整个桥臂中点会以很高的dv/dt跳变,CMTI不够的隔离器会在输出端产生毛刺,这是很多"莫名炸机"的隐藏元凶。
1.3 电流采样通道:差分放大加ADC过采样的实现细节
图腾柱PFC的电流采样位置很有讲究。电感电流就是输入电流,控制目标明确;但电感一端接着开关节点,另一端接着AC输入,共模电压不是零。如果把采样电阻放在AC输入侧,共模电平就是电网电压本身,正负半周在±311V之间摆动。
我对比过两种工程方案:
方案一是隔离放大器加分流电阻。母线侧采样,用AMC1300这类隔离运放把模拟信号传到数字侧。好处是高低压完全隔离,不怕共模;坏处是成本高、延迟大(隔离运放带宽通常几百kHz,相位延迟在电流环里要仔细算)、还需要隔离电源。
方案二是高压共模差分放大器直接采样AC侧的采样电阻。INA149或者AD629这类器件共模输入范围能做到几百伏,而且带宽到几百kHz没问题。电路简单,成本低,信号延迟小。缺点是共模抑制比在高频段会掉,AC电压变化率dv/dt大的时候会叠加共模误差。
我最终选了方案二,因为电流环带宽要求高,延迟越小越好。采样电阻5mΩ,600W满载时峰值电流约25A,采样电阻上的峰值压降125mV,功耗约3W。差分放大增益设在20倍左右,输出到ADC的量程能覆盖整个电流波形,又不会在浪涌时削顶。
采样点从PCB走线到ADC还有一段距离,这段走线我做了包地处理。电源域的地和数字地单点连接,避免功率地噪声串进采样信号。在软件里,我开了ADC过采样,每4个开关周期取8次样本求和平均,等效位数能多出1~2位,对过零附近的小电流测量很有帮助。
2. 数字控制软件架构:状态机、定标与时序设计
2.1 控制周期和ADC触发时点:采样时机比采样次数重要
数字控制的第一个决定:控制计算频率是多少。图腾柱PFC的开关频率我设在200kHz,这是GaN很舒服的频率。电流环必须每个开关周期执行一次,所以控制任务频率也是200kHz;电压环和PLL不需要这么快,放在10kHz的子任务里。
ADC采样时刻比采样频率更重要。开关管开通关断的瞬间,采样电阻上会有巨大的尖峰,正好撞上ADC采样窗口就会读到假数据。我把ADC触发信号设置为PWM计数器比较值——采样点放在PWM周期中间,也就是开关管导通稳定后的中点,避开所有换流沿。这个做法每个做数字电源的人都会强调,但依然有人图省事直接用固定周期的ADC采样,波形一塌糊涂再来查噪声。
PWM更新策略也有讲究。如果用"计算完成后立即更新"的模式,采样、计算、PWM更新都在同一个时刻,会导致采样点落在刚更新的PWM沿附近。我采用的是"下一周期生效"模式:第N个周期采样并计算出占空比,第N+1个周期才应用。这样多了一拍延迟,但控制稳定性好很多,环路设计时把这一拍算进去就行。
2.2 状态机与保护分级:开机流程比运行逻辑更容易翻车
数字控制的好处之一就是开机时序可以做得非常可控。我设计了一个五状态状态机:IDLE、PRECHARGE、SOFT_START、RUN、FAULT。状态机平时没事干,但每个控制中断都会过一遍,该迁移迁移,该封锁封锁。
typedef enum { ST_IDLE = 0, ST_PRECHARGE, ST_SOFT_START, ST_RUN, ST_FAULT } PfcState_t; void pfc_state_machine(void) { switch (state) { case ST_IDLE: pwm_disable(); relay_open(); if (ac_ok() && vbus < V_BUS_SAFE) { state = ST_PRECHARGE; } break; case ST_PRECHARGE: // 母线通过预充电阻充电,继电器两端电压差应该减小 if (vbus > 0.92f * V_BUS_NOM) { relay_close(); ac_zero_current_flag = 1; // 在过零点附近闭合更安全 state = ST_SOFT_START; } break; case ST_SOFT_START: // 占空比从最小开始线性爬坡,参考电流也限幅爬坡 soft_start_timer++; duty_ramp = MIN(1.0f, soft_start_timer * DUTY_STEP); if (soft_start_timer > SOFT_START_MAX) { state = ST_RUN; } break; case ST_RUN: // 正常双环控制 break; case ST_FAULT: pwm_disable(); // 记录故障码,等待复位 break; } }开机最容易翻车的点有两个:一是继电器闭合时机太早。母线还没充满电就闭合继电器,浪涌电流大到能把继电器触点焊死。二是软启动斜坡太陡。占空比爬升快,输出电容充电电流猛增,过流保护误动作甚至磁性饱和。我实测下来600W样机软启动500ms左右比较合适,既能保证电容充满,又不会让电流环一开始就饱和。
保护逻辑按优先级分级处理:
- 逐周过流限制(每个开关周期检查,触发立即封锁PWM)
- 母线过压保护(允许几个小周期的反应时间,同时关驱动)
- 母线欠压、AC异常、过温保护(进入FAULT前做消抖确认)
逐周过流是最硬的一条限制。电流采样值在中断里跟OCP阈值比较,超过就直接把PWM输出锁死,这个动作不能靠软件判断再关——要放到比较器硬件层做,或者放在控制任务的最高优先级最前面执行。软件慢半拍的后果就是看着IGBT炸成两半。
2.3 定点数Q格式与抗积分饱和:数字控制不给小数点
DSP和单片机做控制,浮点运算不是不能用,但定点数定标做得好,代码跑得又快又稳。我常用的定标是Q15格式:把-1到+1范围的标幺值映射到-32768到32767的整数。电流采样、电压采样、PI系数全用Q15标幺,占空比也是Q15。
控制算法里最容易出问题的不是比例项,是积分项。积分项输出限幅要跟计算逻辑分开做,先限积分值,再限总输出,这叫条件积分或抗饱和积分。不然的话,输出已经限幅了,积分还在累加,恢复的时候就会过冲,母线电压冒出一个大尖峰。
typedef struct { int32_t kp_s16q15; int32_t ki_s16q15; int32_t integ_s16q15; int32_t out_max; int32_t out_min; } PiController_t; int32_t pi_run(PiController_t *pi, int32_t err_s16q15) { int32_t out; // 积分项更新并限幅 pi->integ_s16q15 += (int32_t)(((int64_t)pi->ki_s16q15 * err_s16q15) >> 15); if (pi->integ_s16q15 > pi->out_max) { pi->integ_s16q15 = pi->out_max; } else if (pi->integ_s16q15 < pi->out_min) { pi->integ_s16q15 = pi->out_min; } // 比例项 + 积分项 out = (int32_t)(((int64_t)pi->kp_s16q15 * err_s16q15) >> 15) + pi->integ_s16q15; // 输出总限幅 if (out > pi->out_max) out = pi->out_max; if (out < pi->out_min) out = pi->out_min; return out; }Q15定点有几个细节要注意:乘法是(int64_t)中间量再右移15位,但右移是整除不是四舍五入,误差在小数。系数标定时要留余量,积分增益别定到极限范围,否则动态响应时很容易提前饱和。
3. CCM/DCM交界处与AC过零点的工程处理
3.1 过零毛刺的根因:一次完整的故障排查链路
图腾柱PFC最让人头疼的就是AC电压过零点。我第一版样机在满载时THD能到8%,波形在过零点附近有明显的凸起和凹陷,电流波形有一段奇怪的台阶。那段时间我压着性子排查,过程值得完整记录一下。
先怀疑死区时间。图腾柱拓扑在过零附近要从"正半周模式"切换到"负半周模式",低频桥臂和高频桥臂的角色互换,死区如果设置不当,换流瞬间会出现直通。我把死区从100ns调到300ns,波形没变化,排除。
再用示波器抓SW节点电压波形。正常情况下开关动作应该在每个PWM周期内清晰可见,但我发现过零附近出现了一些不该有的窄脉冲——宽度只有几十纳秒,频率却和开关频率不一致。这说明有误导通或者振铃被误识别为开关动作。
接着查驱动波形。高频桥臂下管正好在受到干扰的位置,驱动电压上有负向毛刺,幅度达到-3V多——已经超过了GaN管关断时的安全负压范围。这个毛刺的来源就是中间章节说的共源电感振铃。但问题是,为什么只在过零附近出现?
到这里我才反应过来问题出在采样和控制配合上。过零附近,电感电流本来就小,电流采样信噪比很差。ADC采样窗口如果正好落在换流尖峰上,采到的"电流"可能是负几十毫伏的噪声,控制环路把它当成真实的负电流,就会给出错误的占空比修正,反过来又加剧了换流振动。这是一个闭环的恶性循环:采样噪声导致占空比抖动,占空比抖动又产生更多噪声。
排查结论:问题不在死区,不在驱动电路硬件,而在信号采样时机和滤波策略。解决方法是三管齐下:
第一,ADC采样点移到PWM周期后1/4处,彻底避开换流沿和振铃区域。第二,软件里对电流反馈做过零区域的滑动平均,我采了最近4个周期的值取中值滤波,能有效丢到单个尖峰。第三,过零前后各50个采样点内的电流环输出增加限幅,不允许占空比剧烈变化。
整改后THD从8%降到3.7%,满载PF从0.98升到0.995以上。这次排查最大的教训是:数字控制里,不当的采样时机可以被环路放大成明显的波形畸变,问题不一定出在功率级。
3.2 谷值开通的工程实现:比较器比ADC更省心
轻载时图腾柱PFC会进入临界导通模式(CrM)或断续导通模式(DCM)。这两种模式下,电感电流降到零后,开关节点电压会通过功率管结电容和电感发生谐振,产生一个"谷底"。如果在电压谷底处开通上管,就能实现准零电压开通——开关损耗大幅下降,这也是CrM模式轻载效率高的原因。
但谷值要精确捕捉,不是一两个周期就能搞定的。高频桥臂的上下管在DCM下每次关断后,SW节点会振出几个完整的谐振周期,只有第一个谷底电压最低,后续谷底电压逐渐升高。要在第一个谷底开通,误差不能超过几十纳秒。
比较器方案才是我实际采用的。用一颗高速比较器监测SW节点电压和母线电压的比例关系,当SW点电压跨过电感下端参考电压的瞬间,比较器输出一个边沿,DSP或者MCU的捕获单元捕捉这个边沿,在下一次PWM周期精确对齐开通。这个方案完全避开了ADC采样频率的限制,响应时间是纯硬件级别的。
数字预测方案也可以:DCM下电感电流到零的时刻可以用公式估算,然后加上LC谐振周期的四分之一就是谷底时刻。公式估算简单,但对电感感值、母线电压的精度敏感,温度一变化就容易偏。我做过对比,比较器方案在温度变化20°C时谷底跟踪误差仍然在30ns以内,数字预测方案已经偏出去100ns了。
3.3 模式切换的滞环:轻载效率和安全裕量的平衡
图腾柱PFC在CCM、CrM、DCM三种模式之间切换,切换点如果处理不好,电流波形会像锯齿一样跳动,控制系统也不知道自己处于哪个模式。我用的是滞环切换策略:电流峰值大于某个阈值就进入CCM,低于某个阈值就切到CrM/DCM,切回来的阈值比切过去的阈值高一点。这样在切换点附近不会来回振荡。
轻载策略上,我加了Burst模式:负载低于10%时,每几个AC周期才工作一次,中途让PWM完全停止,输出电压由母线电容维持。Burst的触发和退出都加了滞环,避免频繁启停。实测10%负载效率从88%提升到91%左右,对于有能效认证要求的电源这个提升挺可观。
模式切换还有一个细节:切换瞬间电流环的参数要平滑过渡。我的做法是电流环KP、KI系数做成随模式变化的变量,在切换边界处插值过渡,而不是跳变。直接跳变的后果是轻载到重载切换时电流环超调,母线电压瞬间跌落十几伏,足够触发欠压保护。
4. 双环控制参数整定:从仿真到实测的差距
4.1 电流内环:数字延时是穿越频率的天花板
图腾柱PFC电流内环的被控对象是电感,模型接近一阶积分,一个PI控制器足以压住。关键是穿越频率怎么选。传统做法取开关频率的1/10,200kHz开关频率取20kHz穿越频率。但数字控制的延时把这个上限往下拉了不少。
电流环的信号链路里有两个固定延时源:采样和计算需要时间,PWM更新在下一周期生效。加起来等效约1.5个开关周期。穿越频率越高,这个延时贡献的相位滞后越大:
相位滞后 = 360° × 穿越频率 × 1.5 × 开关周期
代入20kHz穿越频率、200kHz开关频率:360° × 20000 × 1.5 × 5μs = 54°。加上被控对象本身的90°相位滞后,就算PI补偿器在穿越频率处提供了足够的超前角,总相位裕量也所剩无几。所以我把电流环穿越频率定在15kHz左右,相位裕量做到55°以上。这个选择牺牲了一点动态响应速度,换来了实质上的稳定性——仿真里把穿越频率推到20kHz看似带宽更高,实测开机时电流波形就开始抖了,这就是相位裕量不足的表现。
电流环整定的另一个细节是阻尼比。仿真里我用了0.707的标准配置,实测发现阻尼比略低(0.8左右)会让开机电流更柔和。不要盲目追求"最优"阻尼,数字电源里稳定压倒一切。
4.2 电压外环:母线上有个100Hz的坑
电压外环控制母线输出电压,但负载实际上是"功率源"而非常规的"电流源"——负载功率恒定,输入功率按正弦变化,母线电容就必须承受电网周期内两倍频的能量脉动。
母线电容选择要先算能量脉动。600W负载在50Hz电网下,一个电网周期的能量脉动约:
ΔE = P / ω = 600 / (2π × 50) ≈ 1.91J
母线电压390V,电容470μF:
ΔU ≈ ΔE / (C × U) = 1.91 / (470μF × 390V) ≈ 10.4V
这直接决定了电压环的带宽上限。为了让电压环在100Hz处有足够的衰减,不能让它对两倍频的纹波做出响应。我把电压环穿越频率设在10Hz左右。在这个频率下,100Hz处的环路增益已经衰减了接近一个数量级,母线电压纹波能被控制在1V以内。
电压环比例系数太低,负载阶跃时母线跌落太多;太高,会把100Hz纹波引入占空比指令,电流波形恶化。我的经验是:电压环的采样可以做平均处理,用最近一个AC半周期的均值作为反馈值,既滤掉了纹波,又不慢到影响负载响应。
4.3 软件锁相环:用SOGI扛过零畸变
数字控制PFC需要准确的电网相位和频率信息,用来同步PWM、安排换流时刻、计算功率。普通过零检测电路在电网畸变时容易误判,软件锁相环才是可靠的做法。
单相系统没有天然正交信号,我用SOGI(二阶广义积分器)构造正交。SOGI输出两路信号:一路和输入同相(α),一路滞后90°(β)。然后拿这两路做Park变换进锁相环。
SOGI的参数选择有一个坑:中心频率要跟着电网频率走。如果SOGI中心频率固定50Hz,电网频率偏到49.8Hz时,β分量相位误差就会增大,PLL跟踪精度下降。我在SOGI里加了一个简单的频率反馈,让中心频率始终跟随PLL输出的估计频率。
PLL带宽我设在30Hz左右。带宽太高等效于对输入信号里的每个畸变都做响应,过零畸变会被放大成相位扰动;带宽太低则跟不上电网频率的缓慢变化。实测30Hz这个值在电网波动±0.5Hz范围内都能稳定跟踪,相位误差控制在1°以内。
5. 保护逻辑、上电时序与实测数据
5.1 上电时序:让样机"软着陆"
样机第一次上电,我坚持用调压器加限流电阻的方式,AC电压从50V开始慢慢往上调。调试数字电源不只是为了安全,更是为了观察每个阶段的波形是否正常。这里有一个非常实用的中间状态:不闭环,只开驱动,看开环下电流波形是否对称。如果开环波形都不对称,那多半是采样偏置不对,跟环路无关。
正式上电流程:
- AC输入经调压器缓慢加到220V,状态机停在IDLE
- 预充电阻给母线电容充电,等母线电压达到目标值的92%
- 继电器闭合,进入软启动,占空比从最小开始线性爬坡
- 软启动结束后切换到双环闭环运行
- 逐步加载,从10%负载到110%负载,每步停留几秒观察波形
我的样机在满载600W,220V AC输入下效率实测96.2%,PF满载0.996,THD满载3.2%。10%负载时效率90.5%左右(开了Burst模式),THD在轻载偏高,达到15%,但轻载THD要求通常比较宽松。
5.2 保护误触发:浪涌、开机瞬间和继电器动作的"小动作"
保护逻辑写起来容易,调起来难。最难的不是保护动作太慢,而是误触发。
我遇到过三次典型的误触发: 第一次是开机瞬间母线欠压保护动作。原因是电压环还没建立,母线电容充电速度略慢,欠压阈值设置得太紧。解决方法是欠压保护的判断加了一个消抖时间窗口,允许母线在软启动期间有正常的较低值。
第二次是浪涌电流引起的逐周过流保护。在雷击浪涌测试和AC电压跌落恢复测试时,输入瞬时电流很大,逐周过流阈值被触发。这个不能说是"误"触发,因为它确实在过流;但如果你在正常操作时频繁触发,问题就是阈值设置没有给瞬态留余量。我把逐周过流阈值设置在满载峰值电流的1.5倍,同时软件里加了blanking窗口——只在PWM开通后的前2μs内使能硬件过流比较器,这个窗口能有效避开开通瞬间的电流尖峰。
第三次是继电器动作瞬间的干扰。继电器是机械触点,闭合瞬间可能弹跳几次,高频桥臂的电流采样会被这种瞬态干扰误判。解决方法是:继电器动作前和动作后的50ms内,暂停过流保护判断,只保留过压保护(因为过压比过流更需要快速响应)。
实测老化测试方面,我在40°C环境温度下烧了4小时,带满载连续运行,样机外壳温度最高点在电感,约84°C;GaN管壳温约76°C,在器件允许范围内。母线电压纹波在满载时实测约8V,和理论计算的10V对得上,余量还算健康。
6. 从PCB布局到EMC摸底:两轮整改里的经验与教训
6.1 高频功率环路面积:决定辐射和振铃的第一步
样机效率、THD都达标的第二天,我把它送去摸底传导EMC,结果150kHz附近超标差不多10dB。这个结果不意外,图腾柱拓扑工作在高频开关状态下,开关节点对参考地的dv/dt非常大,共模噪声本来就比普通boost PFC难搞定。
PCB布局是预先就能做好的功夫。高频功率环路的定义是:输入电容→高频上管→高频下管→输入电容回流。这个环路面积要尽可能小。我用两层板做功率级,输入电容和两个高频管放在同一面,中间用一小块铜皮搭桥,环路面积控制在10cm²以内。这个面积做得好,开关振铃幅度能下降一半。
驱动电路走线也要精心布置。驱动芯片到GaN管栅极的驱动回路不要和功率回路叠加,栅极返回铜皮单独走一条,宽度大于驱动电阻焊盘直径。我见过不少人把驱动GND和功率GND混在一起,最后开通速度一提上去就误触发。
6.2 输入EMI滤波器与Y电容的两个教训
第一轮摸底超标后,我加了整改措施。先是输入端加了一级共模电感,感值5mH,再配合2.2μF的X电容和1nF再加1nF的Y电容。理论上共模扼流圈应该把主要干扰都卡住了,但复测还是有残余超标。
检查后发现两个问题。第一个是Y电容的接地方式不对。Y电容应该接到母线电容的地,然后单点连到参考地;我一开始接到了输出地,结果共模电流绕了个大圈,等效阻抗反而增大了。第二个是驱动电阻太小,dv/dt太快,辐射能量集中在高频段。我把开通驱动电阻从2.2Ω调到4.7Ω,关断电阻保持0Ω,开关速度慢了一些,开关损耗多了约0.3%,但150k到1MHz频段的噪声下降了接近7dB。
第二轮复测,传导测试余量做到6dB以上,辐射测试在30MHz以下的超标也消除了。驱动电阻和EMI滤波器之间永远有个折中:dv/dt太快,EMC难过;dv/dt太慢,开关损耗上去。我这里的经验值是GaN管开通dv/dt控制在5V/ns以内,关断可以略快,约8V/ns,这个组合在效率和EMC之间比较均衡。
这些PCB布局和滤波参数的经验并不新奇,但如果不去实际跑一轮传导测试,很难意识到Y电容接地位置这种"小细节"能影响那么多。图腾柱PFC作为一项成熟度高、但调试坑多的拓扑,每一步改动都需要靠实测数据说话,而不是靠感觉。