做LLC电源这几年,最让人头大的一个场景就是上电瞬间:软启动还没走完,谐振电流先冲出一个比满载还高的尖峰,然后OCP保护动作,电源直接打嗝。要压住这个谐振电流峰值,以前靠调软启动曲线、试参数,后来我把PSOC里的CLB-MACO用起来,把软启动从“软件逐点设置”变成了“硬件实时轨迹”,效果完全不一样。这篇blog就聊聊这个思路怎么落地:LLC启动电流尖峰到底怎么来的、传统方案为什么压不住、CLB和MACO各自干什么活,以及参数怎么定、代码怎么写、调试时要注意什么。适合正在折腾数字电源、服务器电源或者充电模块的工程师,也适合对LLC软启动过流头疼但还没来得及深究的朋友。
1. 先把敌人看清:LLC启动电流尖峰从哪来
1.1 半桥中点那个阶跃,才是尖峰的真源头
很多朋友以为LLC启动尖峰是因为“频率还没扫下来”,只要启动频率足够高、增益足够低,电流就不会大。这个说法只对了一半。启动频率高确实能压低稳态增益,让输出电压慢慢爬,但启动瞬间谐振电流的第一波冲击,本质上跟频率关系不大,而是跟半桥中点电压的阶跃有关。
拿半桥LLC举例,上电前半桥中点S点是0V,谐振电容Cr上也是0V。第一个驱动脉冲到来时,上管导通,S点从0V跳到Vin/2(母线400V就是200V)。这个200V的阶跃直接加到Lr和Cr串联组成的谐振网络上,产生一个典型的LC阶跃响应——电流瞬间冲上去,第一个峰值的大小最理想的情况下大约是:
I_peak ≈ (Vin/2) / Zn
其中Zn是谐振网络的特征阻抗:
Zn = sqrt(Lr / Cr)
这个公式很关键,它说明峰值电流由母线电压和特征阻抗决定,跟开关频率没有直接关系。我手头一台半桥样机,Lr=22uH,Cr=66nF,Zn = sqrt(22e-6 / 66e-9) ≈ 18.3Ω,母线400V,理论峰值就有 200/18.3 ≈ 10.9A。再加励磁电流、寄生参数和阻尼偏差,实测冲到13~15A很常见。如果这台电源满载设计只有10A,启动瞬间就是150%过流,OCP不跳才怪。
所以第一个要建立的观念是:启动尖峰在第一个开关周期就已经决定了,后面所有扫频动作都是在补救,不是在预防。真正能管住这个尖峰的,只有两条路——降低第一个脉宽注入的能量,或者给谐振网络一个更平缓的激励建立过程。
1.2 尖峰不管的连锁反应:从OCP误触发到炸管
启动电流尖峰看着只是波形上“duang”一下,实际危害比示波器画面上严重得多。
首先是过流保护误动作。数字电源的OCP比较器一般盯着谐振电流或者原边电流,阈值按稳态满载的1.2~1.5倍设置。启动尖峰一不小心就超过这个值,电源进入打嗝保护,软启动永远走不完,表现出来就是“上电后输出电压起不来,或者反复重启”。
其次是功率器件的应力。IGBT或者CoolMOS的峰值电流能力虽然有余量,但尖峰叠加高压时,关断瞬间的应力会明显上升。我见过一次炸管事故,事后分析就是启动尖峰太大、关断电流超SOA(安全工作区),管子直接击穿。这不是危言耸听,LLC启动炸管在行业内不算罕见。
还有磁芯饱和问题。谐振电流尖峰大,意味着励磁电流和原边电流都短时间冲高,如果此时变压器磁通还没建立好,或者磁芯磁通摆幅因为瞬态偏置而超出设计,轻则异响、重则饱和,电感量瞬间掉下来,电流更失控。
你可以把这个过程理解成家里的水管突然打开阀门:水流先是“咚”地一下冲出来,然后才慢慢稳定。启动尖峰就是电源里的“水锤效应”,软启动的目的就是让这个阀门开得慢一点、稳一点,而不是让水龙头一开始就全开。
2. 传统软启动为什么压不住这个尖峰
2.1 固定曲线方案:好用,但不跟手
传统模拟软启动芯片,或者很多PWM控制器自带的软启动引脚,本质上是给一个电容充电,用电容电压去微调频率或者占空比。好处是电路简单、不用写代码、上电就能跑。坏处也很明显:曲线是固定的,没办法随输入电压、负载状态、温度自适应。
同一个LLC,220V输入和90V输入时母线电压差一倍,启动尖峰也差一倍。固定曲线只能按最恶劣工况来调,留很大裕量,结果就是正常工况下软启动拖得很慢,启动时间长得让人着急。还有些场合需要在启动过程中动态切换频率步进,或者跟后级负载通信联动,模拟方案完全做不到。
更麻烦的是,模拟软启动没法处理“启动过程中谐振电容预充电”这类精细问题。LLC上电前谐振电容电压是零,半桥中点一跳变就是阶跃冲击。数字方案可以在第一个脉冲之前先给Cr预充电,或者用脉宽限幅器把第一个脉宽压到极小,模拟方案只能靠外接电容的RC常数瞎蒙。
2.2 纯软件查表方案:三个绕不开的天花板
后来大家转向数字控制,用MCU/DSP做软启动,最常见的办法是查表:把一条频率随时间变化的曲线存在Flash里,启动时每隔一个固定间隔刷新一次PWM周期寄存器。
这个方案能做,但实际用起来有三个天花板。
第一是粒度问题。查表本质上是离散逼近,表越密越接近理想曲线,但Flash空间和刷新间隔有限。步进大了,每次跳频都是一次扰动,电流波形能看到明显的阶梯;步进小了,启动时间拉长,CPU还得频繁进中断。
第二是时序实时性。MCU主循环和中断被环路控制、通信、保护逻辑挤占,软启动刷新能不能严格按1ms或者100us间隔执行,完全取决于系统实时性。我见过有工程师把软启动放到定时中断里,结果中断里还有其他任务,实际刷新间隔抖动个30%,谐振电流峰值也跟着抖——这种问题最难查,波形上看就是“时好时坏”。
第三是第一周期的无力。就算查表频率曲线再完美,第一个脉冲到来时,MCU还在初始化、ADC还没稳定,根本来不及对第一个脉宽做限制。只要第一个驱动脉冲宽度是全脉宽,尖峰就压不住。
那FPGA呢?FPGA做这种活当然没问题,时序精度极高,但成本、PCB面积、开发难度都不是普通电源项目愿意承受的。PSOC这种带可编程逻辑的MCU恰好卡在中间——有硬件逻辑的实时性,又不牺牲MCU的灵活性和开发效率。
3. PSOC CLB-MACO怎么把软启动变成“硬件实时轨迹”
3.1 CLB:贴着PWM模块做时序操作的硬件逻辑
PSOC里有个外设叫CLB(Configurable Logic Block,可配置逻辑块),本质是一小撮可编程硬件逻辑,可以把它理解成“嵌在MCU里的迷你FPGA”。它能跟芯片里的TCPWM(定时/计数/PWM模块)直接互联,输入接PWM信号,输出又能反过来控制PWM。
LLC软启动正好需要这种能力。第一个脉宽怎么限制?正常半桥LLC的PWM占空比是接近50%的,如果能让CLB在启动初期对PWM输出做一次“裁剪”,把脉宽从极小值逐步展开,就能从物理上掐断第一个脉冲的能量注入。这种裁剪动作必须在纳秒级别完成,而且不能依赖CPU中断——刚好CLB的硬件逻辑就是干这个的。
再比如周期寄存器的载入。PWM频率要动态调整时,如果CPU随手写周期寄存器,可能在一个周期中间写入,导致这个周期长度异常,波形出现毛刺。CLB可以设计成在PWM周期边界处同步载入新值,相当于给寄存器更新加了一个“对齐门闩”。这个细节对于软启动轨迹的平滑性非常重要。
不同系列PSOC对CLB的命名和资源略有差别,有的叫CLB,有的叫UDB,但思路一致:把需要逐周期处理的时序逻辑从CPU手里拿走,交给硬件。
3.2 MACO:为软启动曲线计算准备的数学引擎
MACO(Math Coprocessor,数学协处理器)是PSOC里面的硬件数学加速单元,专门干CPU不擅长的事——除法、开方、三角函数、指数这些计算。LLC软启动里的指数扫频曲线,靠CPU的软件库算,一次除法加一次exp可能要几微秒甚至几十微秒;用MACO硬件算,是纳秒到微秒级别的。功耗还低很多。
别小看这点性能差距。软启动频率更新频率如果是每100us一次,一次计算差几十微秒,直接吃掉一半时间预算;如果CPU还在跑电压环路、通信协议,根本忙不过来。把数学运算卸载给MACO,CPU只负责状态机流转和结果搬运,整个系统就从容了。
MACO计算的另一个价值是“实时自适应”,而不是查表。查表只能选择预先画好的曲线,MACO可以根据实时输入电压、温度、负载状态,在线算出一条新的软启动轨迹参数。这就把固定曲线方案的死板和纯软件方案的延迟问题一起解决掉了。
3.3 频率、占空比、OCP阈值三条轨迹怎么联动
我这几年做软启动的经验是:只压频率轨迹,效果有限;三条轨迹联动,效果才是质变。
- 频率轨迹:从1.5~2倍谐振频率往工作频率方向扫,决定增益爬升速度。
- 占空比限制轨迹:从极窄脉宽逐步展开到50%带死区,决定单位周期注入的能量上限。
- OCP阈值轨迹:启动初期放宽、接近稳态时收紧,防止保护误动作,同时保留真正的过流保护能力。
这三条轨迹是同步变化的。MACO输出的是同一套“曲线参数”,CLB拿这些参数分别作用到PWM频率寄存器、PWM比较值、OCP比较器阈值。CPU只在启动开始时给一个“go”信号,然后定期读一下状态,其余时间基本放手。
用生活类比来说:CPU是船长,决定航线和目的地;MACO是领航员,负责实时计算和修正航向;CLB是舵机,以最快速度执行每一次微调。船长不需要自己亲手打舵,才能真正腾出手来处理风浪。
4. 软启动参数设计:起始频率、扫频曲线和脉宽限制怎么定
4.1 起始频率和目标频率:先定边界再谈曲线
设计软启动,第一步不是写代码,而是定参数边界。LLC工作频率范围一般由谐振频率fr和最低工作频率决定,软启动则要在这个范围之外再往上拉一截。
我的经验是:起始频率取1.5~2倍的fr。太高了,虽然增益更低,但死区时间内谐振电流过零困难,可能丢ZVS;太低了,靠近容性区边界,启动过程一旦有扰动就可能进入ZCS(零电流开关)失效区,电流波形会很难看。以fr=100kHz为例,起始频率大概取150kHz~200kHz。
工作频率也就是软启动要扫到的目标,一般取额定工作点频率,比如轻载或额定负载对应的110kHz。注意这里有一个常见坑:如果把目标定在fr上,启动完成后负载一重,频率还要往下降,等于软启动结束之后还有一次“二次爬坡”,电流可能再起一个浪头。所以我的习惯是软启动目标频率定在额定满载工作频率附近,让闭环从那里接着走,而不是停在fr。
扫频时长方面,典型值在10ms~50ms之间。太短,输出电压冲击大,负载侧可能过压;太长,满载启动时用户等得不耐烦,也有可能出现励磁电流异常。具体怎么取,要配合脉宽限制一起看,下面的公式会给一个判断依据。
4.2 指数扫频曲线与脉宽限幅的配合关系
扫频曲线我强烈建议用指数曲线,而不是直线。原因是LLC的增益-频率曲线本来就是非线性的:启动高频段增益变化慢,接近谐振点时增益变化陡。如果频率线性下降,接近工作点时增益会猛增,电流自然跟着猛冲;指数下降可以让频率在低增益区走得快一点,在高增益区走得慢一点,让输出电压爬升速率更均匀。
指数扫频的形式是:
f(t) = f_start + (f_end - f_start) × (1 - e^(-t/τ))
这里的τ是时间常数,决定了曲线“拐弯”的快慢。实际操作中,MACO硬件算指数很轻松,实时改τ也很方便。我一般取τ = T_ss / 4,让曲线在前1/4段时间内完成大部分频率变化,后3/4段时间慢慢逼近目标。
脉宽限制轨迹跟频率轨迹必须联动,不能各走各的。启动最开始,第一个脉宽我建议从5%~10%开始。注意这里说的是占空比,不是死区——半桥的正常占空比接近50%,启动初期只有这个值的五分之一甚至更小。这直接决定了第一个周期注入谐振网络的能量上限,是压尖峰的第一道闸。
脉宽展开曲线用线性或者S型都可以,我习惯跟频率同步走:频率在高速段时脉宽也小,频率进入慢速逼近段后脉宽逐步放开到正常值。因为高频段本身增益低,脉宽小一点不影响输出建立;等频率接近工作点了,再把脉宽交还给正常控制,这样整个启动过程电压、电流都平滑。
4.3 频率步进、扫频时间与电流变化率的换算
另一个很多人忽略的参数是频率步进。不是曲线画出来就行,步进太大依然会在谐振电流上留下台阶。工程经验是:每个扫频周期(比如100us更新一次)的频率变化量不超过当前频率的0.5%~1%。
以100kHz起始、每100us更新一次、50ms扫完为例,平均步进大约是:
(200k - 110k) / 500 = 180Hz/步
相对200kHz启动点的变化率是0.09%,这个量级很安全。如果扫频时间压缩到10ms,同样500步,步进就是1800Hz/步,相对变化率接近1%了,实测中电流波形就会出现可见的折线。
估算电流变化率还有一个实用公式:
ΔI_Cr ≈ C_r × dV_Cr/dt
如果谐振电容Cr=66nF,频率步进太大导致Cr电压每步跳变20V,那么电流跳变量就是66e-9 × 20 / 100e-6 = 13.2A——这就很夸张。所以频率步进必须跟Cr电压变化率一起审视,光盯着频率数字没意义。
下面把参数调整方向整理成一张表,方便做调试参考:
| 参数 | 调大影响 | 调小影响 | 我的建议 |
|---|---|---|---|
| 起始频率 | 增益更低,但可能失去ZVS | 靠近容性区,启动易振荡 | 1.5~2倍fr |
| 扫频时间 | 启动慢,输出冲击小 | 启动快,电流台阶大 | 10~50ms |
| τ时间常数 | 曲线变缓,前期走得快 | 曲线变陡,前期慢后期快 | τ=扫频时间/4 |
| 频率步进 | 电流台阶明显 | 占用时间长,CPU负担大 | 每步≤0.5%当前频率 |
| 起始脉宽 | 第一周期能量大,尖峰高 | 电压建立过慢,可能启动失败 | 5%~10%占空比 |
| OCP阈值轨迹 | 保护太松,风险大 | 启动未结束就误触发 | 随脉宽展开同步收紧 |
5. 实操落地:在PSoC上一步步搭出来
5.1 外设规划:把每项工作分给最适合的模块
纸上谈兵讲完,说说怎么在PSOC里落地。我这里以带CLB和MACO的PSoC系列为参考,不同型号引脚和寄存器名有差异,但外设分工思路通用。
- TCPWM:输出互补PWM,带死区,驱动半桥上下管。启动期间频率和比较值会被CLB持续刷新。
- CLB:接TCPWM的PWM输出和周期信号,实现脉宽限幅、周期边界同步载入、启动标志逻辑。
- MACO:算指数扫频曲线、算OCP阈值曲线、算脉宽限制曲线,把结果写到CLB的寄存器或者影子寄存器。
- ADC:采样母线电压、输出电压、谐振电流,提供给MACO做自适应修正。
- CPU:跑软启动状态机,负责初始化外设、启动时给go信号、结束后切换闭环。
建议先把外设中断分配好。软启动期间不要让CPU做高优先级之外的活,ADC转换结果可以直接通过DMA搬运到内存,MACO算完通过事件触发一遍CPU读取,不要用CPU主动polling等MACO结果,否则实时性又回到软件方案的水平了。
5.2 CLB内部逻辑要点与关键代码示意
CLB的设计方式通常是在芯片配置工具里用原理图或者逻辑描述完成,具体语法随平台走,但核心逻辑可以用一段概念代码表示。这一段不是能直接编译烧录的完整例程,重点看思路:
// 概念性描述:CLB对PWM周期寄存器做同步载入 + 脉宽限幅 // 具体实现需按平台CLB资源调整 module softstart_clb ( input wire pwm_cycle_done, // TCPWM的周期结束信号 input wire clk, input wire [15:0] maco_target_period, input wire [15:0] maco_limit_duty, input wire start_en, output reg pwm_period_write_en, output reg pwm_duty_force_en ); // 只在PWM周期边界执行寄存器载入,避免周期中间写导致的毛刺 always @(posedge clk) begin if (start_en && pwm_cycle_done) begin pwm_period_write_en <= 1'b1; // 脉冲:向TCPWM周期寄存器发出载入请求 pwm_duty_force_en <= 1'b1; // 脉冲:使能脉宽限幅比较逻辑 end else begin pwm_period_write_en <= 1'b0; pwm_duty_force_en <= 1'b0; end end endmoduleCLB里还有一块逻辑专门做脉宽限幅:比较PWM输出高电平时间和maco_limit_duty对应的数值,一旦达到限制值就强制拉低PWM输出。这个动作在每个开关周期都执行,完全硬件实时,CPU不参与。实测下来这个逻辑只要写对了,第一个脉冲的宽度就能被精确限制在设定值,不会出现“软件还没跑起来、PWM已经全宽输出”的尴尬。
有一点要特别提醒:CLB内部逻辑的时序收敛一定要在配置阶段跑一遍静态时序分析。不同PSOC型号的CLB资源有限,逻辑级数稍深就可能出现毛刺或时序违例。我有一次把限幅比较逻辑写得复杂了,CLB输出在高速PWM下出现偶发毛刺,导致一个周期突然全宽导通,尖峰又回来了。后来简化逻辑、用两级触发器打拍才解决。
5.3 软启动状态机:CPU、MACO、CLB怎么协作
软件侧的状态机我习惯分成四个阶段,每个阶段对应一组不同的MACO计算输入和CLB使能信号:
/* 软启动状态机,代码为思路示例 */ typedef enum { SS_PRECHARGE, // 谐振电容预充电等待 SS_SCAN_FREQ, // 频率扫掠 + 脉宽限幅 SS_TRANSFER, // 闭环切入过渡 SS_RUN // 正常运行 } ss_state_t; void softstart_tick(ss_state_t state, uint32_t t_ms) { switch (state) { case SS_PRECHARGE: // 等待CLB把谐振电容预充到目标电位,期间PWM保持关闭 CLB_start_prc(); if (ADC_vout() > TH_VOUT_PRE) state = SS_SCAN_FREQ; break; case SS_SCAN_FREQ: // 调用MACO计算指数扫频频率和脉宽限制值 maco_start(MACO_EXP_SCAN, t_ms); maco_wait_done(); CLB_write_period(maco_get_period()); CLB_write_duty_limit(maco_get_duty()); OCP_set_threshold(maco_get_ocp_thd()); // 同步调整OCP阈值 if (t_ms >= SS_TOTAL_MS) state = SS_TRANSFER; break; case SS_TRANSFER: // 打开闭环,软启动频率轨迹交给环路 voltage_loop_enable(1); CLB_bypass(); state = SS_RUN; break; default: break; } }这段代码的要点是:CPU只发起运算和搬运结果,每条轨迹的生效由CLB在周期边界硬件执行。MACO_wait_done()在工程上我一般做成超时保护,万一MACO异常卡住,不能堵死状态机。
另外,状态机的阶段判断不能只看时间,最好加上电压和电流条件。比如SS_SCAN_FREQ阶段,如果输出电压已经达到目标值的90%,就可以提前切到SS_TRANSFER;反过来,如果到时间了但输出电压还低,说明启动可能被负载拖住,需要报错而不是硬切闭环。这种“时间+状态”双条件的判断在数字电源里非常实用。
6. 实测与排查:那些波形图不会告诉你的细节
6.1 实测下来的典型差异:有轨迹限制和没轨迹限制
我拿那台半桥LLC样机对比过三组设置:纯频率扫掠、频率+脉宽限制、频率+脉宽限制+OCP阈值轨迹联动。
第一组纯频率扫掠,启动瞬间谐振电流照样冲到14A,跟没做软启动基本一样,因为第一个全宽脉冲无法避免。第二组加了脉宽限制,第一个脉冲宽度限制到10%,谐振电流峰值立刻降到7A以下,但OCP阈值如果还是按1.2倍满载设置,启动中后段电流爬升时依然会误触发。第三组把OCP阈值也做成随时间收紧的轨迹,整段启动电流波形平缓,峰值控制在8A以内,启动时间大约28ms,输出电压单调上升无过冲。
这组对比让我彻底认同一个观点:软启动不是一条曲线的事,是三条曲线互相配合的事。只调频率,永远在跟尖峰“捉迷藏”。
6.2 启动过程常见问题排查速查表
调试中踩过的坑比设计时想到的问题多得多,这里整理一份速查表:
| 现象 | 可能的根因 | 排查方向 |
|---|---|---|
| 第一个脉冲就有大尖峰 | 脉宽限幅逻辑未生效,或CLB未同步对齐 | 抓第一个周期Vgs,确认PWM宽度是否等于设定值 |
| 启动中段电流台阶明显 | 频率步进过大 | 减小每周期频率变化量,或增大扫频时间 |
| 高频段丢ZVS,波形振荡 | 起始频率太高,死区时间与谐振周期不匹配 | 适当降低起始频率,或调整死区时间 |
| 接近工作频率时电流又冲高 | 指数曲线τ太小,频率逼近过快 | 增大τ,让曲线“软着陆”到目标频率 |
| PWM输出偶发毛刺 | CLB逻辑时序违例或未打拍同步 | 简化CLB逻辑,在输入输出加两级触发器 |
| 软启动正常但OCP误触发 | OCP阈值轨迹落后于电流轨迹 | 让OCP阈值曲线与脉宽展开曲线同步,仿真验证 |
| 启动时间到但电压没起来 | 起始脉宽限制太低,输出建立过慢 | 适当提高起始脉宽到10%~15%,观察电流 |
| 启动完成后闭环切入波形塌陷 | SS_TRANSFER切换时频率跳变,闭环尚未接管 | 切换前让软启动频率接近闭环目标,或增加过渡段 |
排查软启动问题,我的经验是先抓波形,不要上来就改代码。示波器至少抓三路:谐振电流、半桥中点电压、PWM驱动波形。谐振电流看尖峰形态,半桥中点看是否丢ZVS,PWM驱动看实际脉宽——很多问题一眼就能定位,根本不用猜。
6.3 两个我一直在用的调试习惯
最后分享两个我自己长期保留的调试习惯,都是在现场踩坑踩出来的。
第一个习惯是:上电调试时把示波器触发设到第二个开关周期,第一个周期单独抓一次。原因很简单,启动第一个周期的行为往往决定了整个启动过程的成败,但默认触发方式很容易把这一帧漏掉。先确认第一个脉宽被正确限制住,再谈后面的曲线优化。如果第一个周期就是全宽脉冲,后面所有努力都白搭。
第二个习惯是:给软启动状态机加“慢动作模式”。调试阶段把时间轴拉长10倍——原来20ms的扫频变成200ms,原来1ms的步进间隔变成10ms。这样每条轨迹的变化都能在示波器上看得清清楚楚,频率步进、脉宽展开、OCP阈值收紧的配合关系一目了然。调好了再把时间参数恢复到正常值。这个习惯帮我省掉了大量“玄学”排查时间,很多问题在慢动作模式下会自己现出原形。
个人体会是,PSOC这套CLB-MACO方案真正解决的不是算得快,而是把软启动从“软件尽力而为”变成了“硬件说到做到”。频率刷新、脉宽限制、阈值收紧这些动作都发生在硬件层面,CPU反而解脱出来干它该干的活——判断状态、处理异常、跟外部通信。这种分工方式,比单纯堆算力要健康得多。等回头看波形上那个曾经让你失眠的尖峰,安安静静地平躺在一个可控的高度上,你会觉得这一个下午没有白费。