ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

STM32G474实现Buck-Boost+LLC混合拓扑数字电源PWM控制详解

STM32G474实现Buck-Boost+LLC混合拓扑数字电源PWM控制详解 1. 项目梳理为什么选STM32G474和混合拓扑1.1 数字化电源控制的需求到底是什么做数字电源这些年我最大的感受是很多刚入门的朋友把数字电源想得太简单觉得不就是用单片机输出几路PWM配合ADC采样做一个PID闭环吗。实际上真正做起来你会发现数字电源的难点从来不在“出PWM”这一步而在PWM的精度、同步性、故障保护响应速度以及拓扑切换时控制策略的衔接。这个项目选定的目标是Buck-BoostLLC混合拓扑说直白点就是前级用四开关Buck-Boost做宽范围电压变换后级用LLC谐振变换器做隔离和高效稳压。这种方案在储能、充电桩、车载电源、通信电源里非常常见因为这些场景的输入电压范围很宽比如电池电压可能从40V到80V变化但输出要稳定在一个电压上。Buck-Boost负责把宽范围输入压到中间母线电压LLC再负责高效率的隔离变换两者分工明确。STM32G474之所以适合干这个活核心在于它的HRTIM定时器。这不是普通的PWM外设而是一个专门为电源控制设计的高分辨率定时器可以输出最高二百多皮秒分辨率的PWM还能做硬件级别的故障保护、死区补偿、移相控制。配合新一代的ADC和DMA完全能满足中高端数字电源的控制需求。如果你用普通STM32F103那种定时器去做LLC你会发现频率精度和死区控制都不够用尤其是在高频下容易出问题。1.2 Buck-Boost和LLC各自解决什么问题四开关Buck-Boost名字听起来高大上其实原理并不复杂。它由四个MOSFET组成两个高边两个低边中间跨一个电感。当输入电压高于输出时工作在Buck模式只有Q1和Q2做高频开关当输入电压低于输出时工作在Boost模式Q3和Q4做高频开关。当输入输出电压接近时可以让四个管子同时工作实现无缝切换。这种拓扑最大的优势就是输入输出极性相同、电流连续、无死区问题比传统的反极性Buck-Boost好控制得多。但问题也在这里四个管子怎么分配PWM、什么时候切换模式、切换时怎么避免电流过冲这些都是代码里要处理的细节。LLC谐振变换器核心是利用谐振腔谐振电感Lr和谐振电容Cr的谐振特性实现开关管的ZVS零电压开通和整流管的ZCS零电流关断。LLC的工作频率可以高于谐振频率也可以低于谐振频率控制方式就是变频控制PFM偶尔配合移相控制。LLC最大的优势是效率极高软开关特性让开关损耗很小非常适合中大功率场景。但LLC的环路设计比PWM类的拓扑复杂因为它的增益曲线不是线性的而且工作在谐振点附近时增益变化很陡把环路参数调到全负载范围稳定需要下功夫。1.3 STM32G474凭什么能扛下这个活在选择主控芯片时我对比过TI的C2000系列、Microchip的dsPIC还有STM32G474。TI的C2000在电源圈子里名声很大数学运算能力强但价格贵、生态封闭、上手门槛高。dsPIC做电源也不错但外设性能和生态都不如STM32丰富。STM32G474的优势在于性能足够用、外设针对性极强、开发工具链成熟STM32CubeMXHAL库、价格还便宜。具体看外设HRTIM拥有10路独立通道可以组成5个互补对每路都有独立的比较寄存器、死区发生器和故障输入。做Buck-Boost需要4路带死区的互补PWM做LLC需要2路互补PWM半桥或4路互补PWM全桥这些G474都能一趟水搞定。而且HRTIM的PWM输出路径上还带有硬件刹车功能一旦检测到过流信号可以在几十纳秒内把PWM关断这种响应速度是软件中断做不到的。ADC方面G474内置了5个ADC单元支持差分输入、硬件过采样、多通道同时采样配合DMA可以实现无CPU干预的连续转换。对数字电源来说ADC采样的实时性和精度直接影响环路性能G474这块的配置灵活度很高。另外G474内部还带有CORDIC硬件加速器和数学运算单元做PID计算、三角函数、滤波运算都比纯软件快不少。电源环路里用到的滤波、积分、微分计算这些硬件加速器能省不少CPU周期让主循环有更多余量去处理通讯、监控等功能。2. 核心原理Buck-Boost和LLC的控制逻辑拆解2.1 四开关Buck-Boost的PWM需求分析四开关Buck-Boost拓扑的PWM分配我画过不知道多少张时序图这里和大家详细拆解一下。电路结构是Q1、Q2组成Buck桥臂Q3、Q4组成Boost桥臂储能电感L夹在中间。假设输入电压Vin输出电压Vout两者都是正极性。Q1是Buck高边管Q2是Buck低边管Q3是Boost高边管Q4是Boost低边管。工作在Buck模式时Q3常开、Q4常关Q1和Q2互补导通占空比D Vout/Vin。工作在Boost模式时Q1常开、Q2常关Q3和Q4互补导通占空比D 1 - Vin/Vout。工作在Buck-Boost过渡模式时让Q2和Q3的驱动信号做适当处理或者让四个管子都参与开关让输入输出电压比稳定在1附近避免模式切换时的电压跳变和电流冲击。PWM需求方面关键在于几组互补PWM必须严格同频同步且死区时间独立可配。死区时间的大小取决于MOSFET的开关特性和栅极驱动电路一般建议在80ns到200ns之间太短会导致直通短路太长会增加死区损耗。用HRTIM实现时可以在CubeMX里为每个输出通道单独配置死区插入时间上升沿和下降沿的延时可以分别设置非常灵活。2.2 LLC的变频控制原理LLC谐振变换器的核心控制方式是PFM脉冲频率调制通过改变开关频率来控制输出电压。LLC的增益曲线是一条关于频率的钟形曲线谐振频率fr 1/(2π√(Lr·Cr))由谐振电感和谐振电容决定。当开关频率等于谐振频率fr时LLC工作在纯谐振状态增益约为1效率最高。当频率高于fr时工作在上谐振区增益小于1适合降压当频率低于fr时工作在下谐振区增益大于1适合升压应用。这就是为什么LLC特别适合宽范围输出电压的场景。但LLC有一个特点需要注意轻载时如果频率拉得太高增益低于1输出电压可能会失控。所以很多LLC方案会加一个Burst模式间歇工作模式轻载时通过跳周期来控制输出避免频率过度升高。实现LLC的PWM时最核心的寄存器配置是PWM周期寄存器决定频率和比较寄存器决定占空比。半桥LLC只需要两路互补PWM占空比固定为50%只改变频率。全桥LLC需要四路PWM可以是两路带死区的互补对也可以做移相控制。用HRTIM做LLC的PFM控制核心就是根据闭环计算结果动态修改周期寄存器的值。2.3 混合拓扑的控制策略衔接Buck-Boost和LLC组合在一起时控制策略的衔接是整个系统的灵魂。我的做法是Buck-Boost负责粗调把中间母线电压稳压在一个目标值比如400VLLC负责精调把输出电压稳定在最终目标值比如48V。两个级联的变换器各自有独立的反馈环路但需要协调启动时序。启动时先让Buck-Boost软启动中间母线电容充电到目标值后再启动LLC。如果同时启动可能出现中间母线电压还没建立起来LLC就开始工作导致输出过冲或震荡。软件里用一个状态机来管理启动流程每个阶段都检查关键的电压电流值满足条件才进入下一阶段。模式切换方面更复杂。当输入电压从高到低变化时Buck-Boost要从Buck模式切换到Boost模式。如果切换太急电感电流会突变甚至出现电压过冲。我常用的做法是加一个滞环区间当Vout/Vin接近1时让Buck-Boost进入过渡模式在这个区间内两个桥臂的占空比根据输入输出电压比做平滑过渡避免占空比突变。当然也可以用最大占空比钳位和斜率限制来配合让占空比以一定的速率变化而不是一步到位。3. PWM代码实现从CubeMX配置到闭环控制3.1 HRTIM在CubeMX中的关键配置我用STM32CubeMX HAL库这套流程来搭建工程配置HRTIM时有几个关键参数需要特别注意。第一是时钟源。HRTIM的时钟来自PCLK最高可以跑到170MHz。我建议启用HRTIM的内部PLL倍频把定时器时钟提高到最高这样才能获得高分辨率PWM。HRTIM的PWM分辨率计算公式是Ttimer / (fHRTIM)比如fHRTIM 170MHz时PWM周期寄存器值每加1对应的时间步进约为5.88ns。做LLC的PFM控制时频率精度直接由这个时间步进决定。如果要上百kHz的变频控制这个精度完全够用。第二是工作模式。HRTIM的每个定时器单元Timer A到Timer E都可以独立配置我一般把Timer A配置为Buck-Boost的PWM主定时器Timer C配置为LLC的PWM主定时器。每个Timer可以输出两路互补PWM输出1和输出2死区插入可以在输出的前半段和后半段分别配置。第三是PWM频率设置。Buck-Boost的开关频率我设定在100kHzLLC的谐振频率设计在150kHz左右正常工作时开关频率在80kHz到250kHz之间变化。这里要注意HRTIM的周期寄存器是20位的最大值1048575所以在170MHz的时钟下最低频率能做到160Hz左右高频方面完全不是问题。CubeMX里HRTIM的配置界面比较复杂我建议重点检查几个地方波形发生器Waveform Generator的使能、比较值寄存器CMP的初始值、死区时间的单位Deadtime是以定时器时钟周期为单位、以及输出极性。输出极性搞反是新手常犯的错误高边管和低边管的PWM极性在原理图上看起来没问题实际接线上如果驱动芯片是反相输入会导致高边常开低边常关一上电就炸管。3.2 ADC采样与DMA搬运的配合电源环路中ADC采样的实时性非常关键。G474的ADC采样链路我这样搭ADC1负责采样输出电压VoutADC2负责采样电感电流ILADC3负责采样输入电压Vin和中间母线电压Vbus。三个ADC可以并行工作通过DMAMUX把转换结果映射到不同的DMA通道上这样CPU只需要在每次DMA传输完成中断里读取最新的采样值数组。关于ADC采样有几个坑要提醒。第一个是采样保持时间的设置如果ADC的输入阻抗比较高或者前端RC滤波的电容比较大要把采样时间设长一点否则采集到的电压会偏低。我一般设置采样时间为12.5个ADC时钟周期以上配合适当的RC滤波100欧姆10nF效果比较理想。第二个是过采样技术。G474的ADC支持硬件过采样可以把多个连续的采样值累加平均等效提高分辨率。对电源环路来说噪声往往比较大我通常配置8倍过采样这样有效分辨率能提升3位同时还能起到低通滤波的作用。第三个是采样与PWM的同步。数字电源中ADC采样最好在PWM周期的某个固定时间点触发比如在PWM的谷底或峰值时刻采样这样可以避开开关噪声最大的时刻。G474的HRTIM可以产生触发事件直接触发ADC转换这是我最推荐的方式。在HRTIM的寄存器里配置好比较事件让它周期性地触发ADC就能保证每次采样都对齐到PWM周期的同一相位点环路控制的一致性大大提升。3.3 闭环控制代码框架完整的控制代码分为几个层次初始化、ADC采样与DMA中断、环路计算、PWM更新、状态机管理、故障保护。先看初始化部分的核心代码这里展示HRTIM的频率配置。// HRTIM Timer A 配置为100kHz用于Buck-Boost // HRTIM时钟为170MHz周期值 170MHz / 100kHz - 1 1699 hrtim.Instance-TIMxCFG | HRTIM_TIMxCFG_TIMEINSRC; // 使用内部时钟 hrtim.Instance-PER | 1699; // 设置周期 hrtim.Instance-CMP1R | 850; // 50%占空比初始值 hrtim.Instance-DTR | (uint32_t)(15U 16) | (uint32_t)15U; // 死区150ns hrtim.Instance-OUTxR | HRTIM_OUTxR_POL1; // 输出极性配置 hrtim.Instance-CR | HRTIM_CR_EN; // 使能定时器这里要特别注意直接操作寄存器虽然简单但CubeMX生成的代码在某些版本里可能会在初始化后期重写寄存器。所以我的习惯是在HAL_HRTIM_WaveformChannelEnable函数之后再修改寄存器或者干脆用HAL库的接口来设置。如果直接改寄存器然后又在别处调用了HAL接口寄存器值可能被覆盖这个坑我踩过很多次。再看中段的环路计算。Buck-Boost的控制我用电压外环和电流内环双环结构电压环输出电流指令电流环输出占空比。频率不用太高电压环10kHz就够了电流环可以做到50kHz左右。LLC环路的计算方式不同它通过输出电压误差直接调整PWM频率我通常加一个PI控制器输出值直接映射到HRTIM的周期寄存器上。// LLC频率控制输出电压误差 - PI - 频率 - 周期寄存器 float error vref - vout_feedback; float pi_out kp_llc * error integral_llc; // 频率限制在80kHz - 250kHz之间 float freq LR_FREQ_NOMINAL pi_out * FREQ_SCALE; freq CLAMP(freq, 80000.0f, 250000.0f); // 计算HRTIM周期寄存器值 uint32_t period (uint32_t)(HRTIM_FCLK / freq) - 1; LLC_TIMER-PER period;这里PI控制器的参数不是随便拍的。我偷懒的办法是先仿真用Simulink搭一个LLC的小信号模型把PI参数在仿真的伯德图里调好再移植到代码里。虽然仿真参数到实际硬件还要微调但至少有个靠谱的起点不会在现场从零开始摸。DMA中断里做的事很简单把三个ADC的采样结果搬运到全局数组设置标志位告诉主循环可以计算了。CPU在中断里只做数据搬运和标志翻转不做过重的运算数学运算放到主循环或低优先级中断中去做。这种划分方式能让采样频率和控制频率解耦方便调试。4. 调试实录常见问题与排查技巧4.1 PWM故障保护的坑与设计电源产品的安全底线是“永远不能让不该导通的管子同时导通”。HRTIM硬件上有FAULT输入引脚我把它接在硬件过流比较器的输出上。过流比较器的阈值根据功率器件的额定电流和采样电阻的阻值来计算这个值不能太紧也不能太松太紧会导致误触发太松又起不到保护作用。HRTIM的故障保护分两种锁存型和周期型。锁存型一旦触发就永远关闭PWM输出直到软件清除标志位这种适合用在过流、过温这种严重故障上周期型是故障信号消失后自动恢复PWM适合用在软启动等暂态过程中。我的建议是过流和过压故障必须用锁存型这是第一道保险。软件也会配合做保护逻辑但硬件保护才是在纳秒级响应软件处理的是毫秒级的事。另一个容易踩的坑是故障触发后的状态恢复。很多人在调试时发现触发保护后清除标志位重启PWM电路依然异常一查发现是故障源还在一使能PWM又立刻被关断。所以软件要设计合理的重试逻辑首次触发保护后先关闭PWM延时一段时间重新检测故障源是否恢复正常再决定是否重新启动。不能无脑重启也不能永远锁死这里面有一个平衡。4.2 死区时间设置的那些经验死区时间设置的错误轻则发热严重重则炸管。死区太小直通风险大死区太大效率损失明显。以我常用的英飞凌IPB072N15N5G为例它的开启延迟和关断延迟都不到50ns但要考虑到栅极驱动芯片的传播延迟比如UCC21520的传播延迟在30ns左右。串起来算死区下限至少是80ns我通常取120ns到150ns比较稳妥。实际调试中怎么判断死区是否合适看效率。死区太大轻载效率会明显下降死区太小重载时管子温度会异常升高。还有一个方法是用示波器观察上下管Vgs的交叠情况如果发现上下管同时导通了死区必须加大。但是Vgs探头的地要夹在正确的参考点上不要用长地线探棒否则测出来的波形全是被干扰的根本看不出真正的时序。HRTIM配置死区的方法是设置Dead-time Rising和Dead-time Falling寄存器单位是定时器时钟周期。比如170MHz时钟一个周期约5.88ns要设置150ns就填25或26。记得在CubeMX的图形界面里这个单位默认是定时器时钟周期不要和微秒搞混了。4.3 ADC采样噪声问题数字电源的ADC采样噪声是所有调试难题里最让人头疼的。明明输出电压很稳定但ADC采样值的跳动范围能达到几百毫伏导致环路控制抖动、输出纹波变大、甚至啸叫。我总结了几条有效的抗噪声措施。第一ADC采样时刻必须和开关噪声错开。开关管导通和关断的瞬间电路中的dv/dt和di/dt都很大会产生强烈的电磁干扰此时ADC采样会把噪声采进去。我通过HRTIM的触发事件把采样点放在PWM周期的中点远离开关动作时刻效果立竿见影。第二硬件上做好布线。ADC采样回路的地线和功率地要单点连接采样电阻到ADC引脚的走线要尽量短必要时加上RC低通滤波。RC的截止频率要算好既要滤掉高频噪声又不能让信号建立时间太长影响采样精度。第三用软件滤波作为最后一道防线。我通常用滑动平均滤波或者二阶IIR低通滤波把这些滤波代码放在ADC采样完成的DMA中断里。滑动平均的窗口长度根据采样频率和环路带宽的关系来定窗口太大会引入相位延迟让环路不稳定窗口太小又滤不干净一般取8到16个点比较合适。4.4 故障排查速查表我把实际调试中遇到过的问题整理成一张速查表方便大家对照定位。故障现象可能原因排查方法PWM输出无电压HRTIM未正确使能检查时钟使能、Timer使能寄存器、输出通道使能上电炸管死区过小或极性不对查死区寄存器值、用示波器看上下管Vgs输出电压跌落ADC采样偏低查采样时间、RC滤波、参考电压环路啸叫ADC采样相位延迟过大缩短软件滤波窗口、提升环路采样频率模式切换电流尖峰Buckingham-Boost切换无滞环增加滞环区间、控制占空比变化斜率LLC频率无法降低周期寄存器更新失败检查预装载机制确认写入生效时机轻载输出不稳定LLC频率超出范围或Burst逻辑异常限制频率范围、检查Burst模式的阈值这张表不是万能的但它帮我在现场排查时省下了很多时间。大多数情况下问题集中在几个最常见的环节PWM配置、ADC采样、环路参数、电源硬件本身。排查时从最简单的开始先确认PWM波形对不对再确认ADC数值准不准最后才去调环路参数这样是一套很高效的排查流程。4.5 调试工具的使用技巧调数字电源不开玩笑地说示波器是标配而且必须是带宽足够的示波器。LLC工作在150kHz左右Buck-Boost工作在100kHz左右基础示波器看波形没有太大问题。但如果要精确测量开关波形、死区时间、上升沿建议至少200MHz带宽起步否则上升沿测出来都是被示波器“滤波”过的假数据。电流探头也很关键尤其在做环路调试时需要观察电感电流波形来判断是否进入CCM还是DCM模式。电流探头带宽不够测出来的电流波形会有很大的相位延迟误导你对系统稳定性的判断。我觉得如果预算有限可以用一个低感值的采样电阻加差分探头替代但精度和便利性都差一些。软件层面串口和上位机调试是我调试数字电源的重要辅助。我会把ADC采样的原始值、环路计算的中间量、PWM的实际频率和占空比全部通过串口打印出来。这个处理要放到环路的空闲时间段用DMA方式发送不要阻塞控制环路的执行。通过这些实时数据即使不看示波器基本也能判断出系统的工作状态。5. 最终的代码组织与工程结构建议5.1 模块化拆分一个完整的数字电源工程如果所有代码都堆在main.c里后面调试和维护会非常痛苦。我建议按照下面的模块来做拆分每个模块推荐用单独的头文件和源文件组织。/inc bsp_hrtim_pwm.h // HRTIM初始化与外设接口 bsp_adc_dma.h // ADC采样与DMA control_buckboost.h // Buck-Boost双环控制 control_llc.h // LLC变频控制 state_manager.h // 状态机管理 fault_protect.h // 故障保护与恢复 utils_filter.h // 滤波算法 /src bsp_hrtim_pwm.c bsp_adc_dma.c control_buckboost.c control_llc.c state_manager.c fault_protect.c utils_filter.c main.c这样拆分的好处是每个文件职责单一调试时能迅速定位问题。比如PWM波形不正常优先查bsp_hrtim_pwm.c里的配置输出电压纹波大去control_buckboost.c里看环路参数。等代码规模变大以后这种模块化组织方式的优势会更加明显。5.2 状态机的设计思路我把整个系统的运行状态设计为IDLE待机→ PFM_SOFT_STARTBuck-Boost软启动→ LLC_SOFT_STARTLLC软启动→ RUN正常运行→ FAULT故障锁定。状态机的转移条件用宏定义好方便后续修改同时要具备“状态保持”能力防止抖动导致状态反复切换。typedef enum { SYS_IDLE 0, SYS_BB_SOFTSTART, SYS_LLC_SOFTSTART, SYS_RUN, SYS_FAULT_LATCH } SystemState_t; SystemState_t sys_state SYS_IDLE; // 状态机主函数在主循环中调用 void StateMachine_Update(void) { switch (sys_state) { case SYS_IDLE: // 检查启动条件输入电压正常、无故障、使能信号有效 if (input_voltage_ok fault_clear enable_flag) { BuckBoost_SoftStartInit(); sys_state SYS_BB_SOFTSTART; } break; case SYS_BB_SOFTSTART: // Buck-Boost软启动母线电压建立 BuckBoost_SoftStartRun(); if (bus_voltage_ready) { LLC_SoftStartInit(); sys_state SYS_LLC_SOFTSTART; } break; case SYS_LLC_SOFTSTART: // LLC软启动输出电压建立 LLC_SoftStartRun(); if (output_voltage_ready) { sys_state SYS_RUN; } break; case SYS_RUN: // 正常运行执行控制环 BuckBoost_ControlLoop(); LLC_ControlLoop(); break; case SYS_FAULT_LATCH: // 故障锁定等待复位 break; } }我在软启动阶段做了两件事一是让PWM占空比从0开始逐渐增大到目标值避免启动瞬间的浪涌电流二是让中断里的控制环在软启动阶段用开环输出等稳定后再切换到闭环输出切换点要放在母线电压接近目标值的时刻。这样能有效避免启动瞬间的电压过冲。6. 经验总结我走过的弯路和最终建议6.1 反复踩坑后的几点心得做这个项目最大的心得是不要一上来就写代码先花时间把拓扑工作原理彻底搞清楚。很多人一拿到板子就急着调PWM结果波形出不来到处怀疑单片机配置有问题。实际上如果你不理解LLC的增益曲线为什么是这个形状不理解Buck-Boost在模式切换时为什么会有电流尖峰你连排查的方向都没有。调试顺序也很重要。我的建议是先开环后闭环先低压后高压先轻载后重载。开环调试时给一个固定占空比或固定频率的PWM确认各点电压波形符合预期。这一步能发现绝大部分的硬件接线问题和驱动配置问题。闭环调试时先把控制参数调到“保守但还是稳定”的数值确认系统稳定后再一点点增大带宽贪快直接用激进的参数很容易出现发散的震荡到时候很难分清是软件问题还是硬件问题。另外强烈建议在代码里增加一个“参数在线修改”的功能。通过串口命令实时修改PID的增益、目标电压、开关频率上限等参数这样就不用频繁烧写Flash。我用这个功能在现场调试时省下了大量时间不然每次改个参数都要重新编译下载效率太低了。6.2 这个项目还可以怎么扩展目前实现的是Buck-Boost和LLC的基础控制但实际上这套平台还能继续扩展。比如在LLC中加入同步整流控制进一步降低整流损耗加入PFC级联做成一个完整的充电桩功率模块加入状态观测器和前馈控制提升动态响应的速度。硬件层面G474的HRTIM还支持在多个定时器单元之间做同步和交错这意味着可以扩展成多相交错并联的方案做大功率电源时非常有用。最后说一句数字电源的门槛确实存在但没有想象中那么高。关键是掌握正确的方法和思路像搭积木一样一步步把拓扑、硬件、PWM配置、ADC采样、环路控制串起来。希望这篇关于STM32G474的Buck-Boost和LLC混合拓扑PWM代码实现过程能给正在做或准备做数字电源的你一些真正有用的参考。
返回列表