简介基于STM32G474的四开关Buck-Boost数字电源是一份完整开源设计面向电源设计学习者、嵌入式开发工程师及毕业设计人群。项目支持TypeC PD诱骗输入与DC5.5接口输入输入输出最高48V/10A采用同步整流技术兼顾效率与稳定性。资源包共1655个文件约12.36MB以C/H源程序为主含汇编、链接脚本、工程配置及说明文档覆盖固件开发与调试所需。已有377人下载学习。除原理图、PCB、源码和外壳3D模型外还提供典型应用场景与设计思路可直接基于STM32G474进行二次开发或参考其Buck-Boost控制算法、同步整流驱动及功率级设计适合从理论到样机制作时对照研究。1. 把数字电源拆开看四开关同步整流Buck-Boost到底难在哪第一次拆开这个开源项目时我心里想的是Buck-Boost不就是四个功率管加一个电感吗真正把代码烧进去、示波器挂上去之后才发现四开关同步整流拓扑做成数字电源难点根本不在功率级而在死区时序、ADC采样时刻和环路参数这三件事上。这个基于STM32的同步整流Buck-Boost数字电源开源工程把原理图、PCB和数控代码完整打包在一起主控是STM32拓扑是四开关非反相Buck-BoostFSBB同步整流带来的效率收益和那些要命的坑都摆在同一套文件里。想做数控电源的硬件工程师、想从模拟控制切到数字控制的嵌入式工程师以及准备拿真实项目练手的学生都能从里面直接抄作业——完整的Buck-Boost电路、配套的STM32工程和数控代码不是演示用的阉割版。2. 方案与原理为什么选四开关Buck-Boost加STM322.1 四开关Buck-Boost三种工作模式怎么切换先把这个拓扑的骨架说一下。Q1是Buck桥臂的高端管Q2是低端管Q3是Boost桥臂的低端管Q4是高端管中间一个电感L。输入电压经Q1/Q2半桥斩波后再经Q3/Q4半桥和输出电容形成输出。相比二极管整流的Buck-BoostQ2和Q3这两个位置用的是MOS管做同步整流导通压降从零点几伏降到毫欧级的导通电阻乘积低压大电流场景下效率差距相当明显。工作模式按输入输出电压关系来切。输入明显高于输出时走Buck模式Q3常开、Q4常关Q1/Q2做互补PWM输入明显低于输出时走Boost模式Q1常开、Q2常关Q3/Q4做互补PWM输入输出接近时进入Buck-Boost模式两组半桥都参与开关以一个特定的相位关系衔接。模式切换不是按照某一次比较就立刻跳而是带滞环——常见做法是Vout/Vin大于1.1时进Boost、小于0.9时回Buck中间区域待在Buck-Boost模式避免在两个模式之间来回抖。模式切换的平滑度是这个拓扑的玄学所在。Buck到Buck-Boost再到Boost占空比和电感两端电压的极性都在变如果控制代码里没有处理好过渡负载切换的一瞬间输出电压会出现一个不小的台阶甚至反向过冲。实际工程里会在模式切换点做输出软过渡比如逐步改变占空比而不是直接跳变。2.2 同步整流的收益与死区风险很多初次接触数字电源的人会觉得同步整流就是把续流二极管换成MOS管而已。这个理解没错但少算了两个风险死区和反向电流。先说收益。非同步的Buck-Boost电流流经Q2/Q3的体二极管或外加二极管一个0.4V~0.6V的压降在大电流下损耗很大换成MOS管后压降变成Id*Rds(on)例如3A电流在30mΩ的管子只在压降90mV效率能拉高好几个点。这也是这个开源项目把同步整流作为卖点的原因。再说风险。互补PWM之间必须有死区dead time不然上下管同时导通就是直通短路。死区太短不行太长也不行——太长时电流在死区时间段只能走体二极管效率损失且体二极管反向恢复带来额外损耗。常见的起步值是50ns到200ns具体要看驱动IC的传播延迟和MOS管的栅极电荷特性用示波器量栅极驱动波形确认交叠为零。还有反向电流的问题。轻载下电感电流进入断续DCM后同步整流管一直开着的话电感电流会反向流动能量从输出往输入灌。数字控制器里可以检测过零并提前关断同步管来规避但如果没有做这个判断轻载效率会难看甚至在某些状态下电感啸叫。这个在后面的避坑章节会专门展开。2.3 STM32做数字电源为什么不是DSP这个项目的控制核心选STM32而不是DSP我是支持的。数字电源对MCU的要求集中在三块高分辨率PWM、定时器与ADC的同步能力、以及足够快的环路计算。PWM分辨率方面STM32G4的高分辨率定时器HRTIM可以把PWM边沿分辨率做到亚纳秒级F334也是经典的数字电源MCU选型。普通的高级定时器TIM1/TIM8做Buck-Boost也够用只是在窄占空比输出时分辨率会吃紧。ADC方面G4的5Msps高速ADC配注入组可以做到与PWM事件硬件同步触发环路延迟可控。CORDIC和数学加速器还可以用来算角度运算不过在纯Buck-Boost控制里用不太上。相比之下DSP在性能上有优势但STM32的优势是生态。CubeMX生成初始化工程HAL库写好驱动SDK和参考资料满地都是做电源的控制环完全够用。对于这个开源项目来说选择STM32意味着大多数嵌入式工程师拿到代码就能编译、烧录、开干门槛低了一大截。这也是我认为它值得下载复现的原因之一。3. 硬件设计落地电感、MOS管、采样链路怎么定参数3.1 电感与开关管选型哪些参数不能拍脑袋以12V输入、5V/3A输出、200kHz开关频率来算一遍这是这个项目里最典型的工况。Buck模式占空比DVout/Vin算出来0.417。电感电流纹波一般取满载电流的20%到30%按30%算就是0.9A的峰峰值。纹波公式ΔI_L Vin × D × Ts / L反推L Vin × D / (fsw × ΔI_L)代入数字L 12 × 0.417 / (200000 × 0.9) ≈ 27.8μH。实际取22μH到33μH都能工作取小了纹波大但动态快取大了纹波小但电感体积大、成本高。开关管耐压按输入电压的1.5倍以上留裕量12V输入用30V~40V的MOS管就很稳电流按峰值来选Ipeak Iout ΔI_L/2 ≈ 3.45A考虑到瞬态冲击再乘1.2倍裕量选5A以上的管子合适。同步整流管的Rds(on)直接影响效率低压大电流场景尽量选低导通电阻但这往往意味着更贵的封装和更大的栅极电荷需要权衡。电感还有一个容易被忽略的参数是饱和电流。电感峰值电流加上输出短路时的瞬态Isat必须留足裕量否则电感一旦饱和感值骤降电流会失控。选型时至少保证Isat大于最大输出电流的1.5倍同时关注电感温度系数别只看常温下的饱和电流。3.2 采样链路电压分压与电流检测的布局输出电压采样用电阻分压分压比要考虑到ADC参考电压。比如ADC参考3.3V输出电压5V分压比选2:1采样点电压落在2.5V左右给瞬态留了空间。分压电阻上并联一个小电容做滤波但这个电容不能太大否则采样保持环节的建立时间会变长影响ADC读数准确。电流采样是这个项目里最容易马虎的地方。常见做法是低端采样在输出回路串一个采样电阻用差分运放放大后送ADC成本低但容易受地弹影响。高端采样用INA240这类电流检测放大器共模抑制好但成本高一些。开源工程里通常用低端采样这时采样电阻的布局很关键必须用开尔文连接也就是把采样电压的走线直接从电阻两端引出来不要共用电流路径否则在大电流下走线压降会污染采样信号。接地处理上功率地PGND和模拟地AGND建议单点连接采样芯片的地和ADC的地在AGND域功率回路在PGND域汇接点选在输入电容的负端。别把功率地分割得太碎反而会引入额外的地回路。3.3 读这个项目的PCB值得抄的三个布局习惯第一驱动IC和MOS管栅极的走线短而粗最好加一个小阻值的栅极电阻来抑制振铃。第二功率环路的面积被压得很小——输入电容、高边管、低边管、电感、输出电容要形成一个紧凑的回路开关高频电流只在这个最小面积里流动EMI会明显好。第三采样电阻和采样放大的走线是差分对平行且贴近避免大面积铺地兜圈。还有一个值得抄的细节电感底下不铺铜或者只在单面铺小面积铜避免电感磁场在铜层感应出涡流发热。PCB上高压和低压区域之间开槽也是电源板常见的做法能提高爬电距离和维护时的安全感。4. 数字控制环路ADC采样、PID与PWM死区的配合4.1 ADC采样与开关周期同步触发为什么关键数字电源和模拟电源的本质区别是采样时刻和计算延迟。模拟环路是连续的数字环路是离散的离散点在时间上的抖动会直接变成输出噪声。如果ADC采样由软件随意触发采样点落在开关管的开通关断边沿附近采到的电压里混着开关尖峰PID一算输出抖动随之放大。正确做法是把ADC触发和PWM事件硬件绑定。中心对齐模式下定时器在计数值达到周期值或零值的时候产生更新事件把这个事件配置为ADC触发源让ADC在一个开关周期的中心点开始转换此时电感电流在中心值附近、开关瞬态已经结束采样值最有代表性。G4的ADC注入组能在PWM触发后立即可靠采样。采样数量也有讲究。单个点的ADC结果瞬时噪声太大数字滤波又引入延迟常见做法是连续采4到8个点取平均或者用FIR滤波器做轻量滤波。注意滤波器的截止频率不要靠近环路带宽否则会把相位裕量吃掉。采样保持时间也别忽略。如果前端分压电阻并联的滤波电容太大ADC内部采样电容在采样窗口内建立不完全读到的值会有固定偏差。这个偏差在小信号下不明显但会让环路静态误差变大看起来像PID没调好其实是硬件建立问题。4.2 PID离散化位置式、积分限幅与抗饱和数字控制的PID和模拟的PID在公式上差了一个离散化过程。这个项目用的最常见的位置式PID每个控制周期计算一次公式如下// pid.h typedef struct { float Kp, Ki, Kd; float integral; // 积分累计值 float last_error; // 上一次误差用于微分项 float integral_max; // 积分限幅抗饱和关键 float out_max; // 输出限幅 float out_min; } pid_ctrl_t; // pid.c 位置式PID每个控制周期调用一次 float pid_update(pid_ctrl_t *pid, float ref, float fb) { float error ref - fb; // 误差目标值减反馈值 pid-integral error; // 积分累加 // 先对积分项限幅避免过冲这是抗饱和的核心 if (pid-integral pid-integral_max) pid-integral pid-integral_max; if (pid-integral -pid-integral_max) pid-integral -pid-integral_max; float output pid-Kp * error // 比例项 pid-Ki * pid-integral // 积分项 pid-Kd * (error - pid-last_error); // 微分项 pid-last_error error; // 输出限幅防止占空比被推到极端值 if (output pid-out_max) output pid-out_max; if (output pid-out_min) output pid-out_min; return output; }这段代码里的积分限幅是最容易被人省掉的环节。电源控制环路里PID的输出就是占空比或目标电流如果积分项无限累积负载阶跃时输出会长时间饱和恢复慢且过冲大。先对积分项限幅再把输出限幅两者配合才能构成完整的抗饱和结构。参数整定从Kp开始Kd在Buck-Boost里我一般先设0因为微分项对采样噪声很敏感开关频率纹波会让Kd项变成噪声放大器。等Kp和Ki调出基本稳定后再根据需要加很小量的Kd。注意Ki的单位这里的积分项是误差的累加Ki实际上是每个控制周期误差贡献的系数控制周期变了Ki要重新折算。4.3 PWM输出与死区配置高级定时器的使用方法PWM生成和死区插入是数字电源里最不能偷懒的部分。以STM32高级定时器TIM1为例CH1和CH1N输出互补PWM驱动Q1/Q2CH2/CH2N驱动Q3/Q4具体映射以工程为准配置片段如下// TIM1初始化中心对齐模式输出互补PWM TIM_HandleTypeDef htim1; htim1.Instance TIM1; htim1.Init.Prescaler 0; // 不分频直接用定时器时钟 htim1.Init.CounterMode TIM_COUNTERMODE_CENTERALIGNED1; // 中心对齐 htim1.Init.Period 2100; // 84MHz时钟下约20kHz开关频率 htim1.Init.ClockDivision TIM_CLOCKDIVISION_DIV1; HAL_TIM_PWM_Init(htim1); // 配置死区时间具体数值按驱动电路的延迟来定 TIM_BreakDeadTimeConfigTypeDef sDeadTimeConfig {0}; sDeadTimeConfig.DeadTime 50; // 实际死区时间按参考手册公式换算 sDeadTimeConfig.OffStateRunMode TIM_OSSR_DISABLE; sDeadTimeConfig.OffStateIDLEMode TIM_OSSI_DISABLE; HAL_TIMEx_ConfigBreakDeadTime(htim1, sDeadTimeConfig); // 设置占空比PID输出映射到比较寄存器 __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_1, pid_output);这里的周期值、死区值都要根据实际主频做换算。中心对齐模式下定时器先向上再向下计数更新事件发生在周期的底部正好用来触发ADC这也是我把CounterMode选成CENTERALIGNED1的原因之一。占空比寄存器与PID输出之间的映射是线性的PID输出out_min对应比较值0out_max对应周期值写个映射函数接上即可。死区配置完后一定要用示波器实测不要只看寄存器。示波器双通道同时量CH1和CH1N的栅极波形确认两路之间没有交叠且死区时间符合预期。这一步我在写代码和画PCB时都提醒过自己但每次拿到新板子还是会先做这个测量因为死区配置错了上电的一瞬间就可能是冒烟现场。5. 常见问题与排查五个最容易翻车的点5.1 空载啸叫与输出纹波异常现象空载或极轻载时电感发出持续的吱吱声输出电压纹波明显比满载时大示波器上能看到一个低频的振荡包络叠加在正常纹波上这个频率一般在几百赫兹到几千赫兹之间。原因负载很轻时电感电流进入断续模式控制对象从CCM的二阶模型变成DCM的一阶模型相位裕量发生变化如果PID参数是按照CCM工况整定的DCM下容易产生低频振荡振荡频率落在音频范围就成了啸叫。另一个常见原因是数字PWM突然发多个脉冲凑占空比形成了burst模式间歇性的能量注入也会引起电感机械振动。解决先确认工作模式。如果允许加一个最小负载让电源始终工作在CCM这是最直接的后悔药。更实用的做法是让代码在轻载时切到DCM检测模式用比较器检测电感电流过零过零后立即关断同步整流管阻止反向电流同时把环路带宽调低一些用一组适用于DCM的PID参数去跑轻载段。5.2 启动过冲软启动没做好现象每次上电输出电压冲到设定值以上甚至有几次直接触发了过压保护负载越大过冲越明显反复上电都会复现。原因启动瞬间反馈为零PID积分项从零开始往正向快速累积等输出电压接近设定值时积分项已经积累了一个很大的量输出自然过冲如果还有输出电容充电电流的叠加过冲会更明显。软启动时间设得太短、步进太粗同样会出现。解决软件里做一个软启动斜坡把目标电压按时间步进比如每10ms增加5%让积分项有时间跟随同时启动阶段把积分项清零等参考电压接近设定值后再放开积分受限。还要检查启动瞬间占空比是否被输出限幅直接推到最大这种极限占空比对启动过冲是雪上加霜。5.3 同步整流管炸管死区极性配置错误现象上电瞬间电流飙升MOS管烧毁拆开后发现高边管和低边管都有击穿痕迹驱动芯片也可能连带损坏有时候伴随PCB铜箔烧焦。原因最常见的是死区配置没生效、PWM极性配反、或者使能了不该使能的输出导致Q1/Q2或Q3/Q4同时导通形成直通短路。死区时间设得太短也会在器件延迟差异下出现短暂交叠。解决装机前先把功率部分断开只给控制板供电用示波器分别量每对互补PWM的波形确认死区时间非零、极性正确。我自己的习惯是先在固件里把输出固定到某一占空比再逐路观察波形确认无误之后再接电感负载。别省这一步它救的是板子。5.4 ADC噪声导致环路抖动采样时刻不对现象PID输出在稳态时仍有明显高频波动输出电压纹波变大示波器上看有与开关频率相关的毛刺轻载时特别明显重载时稍微好一点。原因采样触发没有和PWM同步采样点落在开关边沿或死区时间内采到的是开关尖峰也可能是采样保持时间不足输入端的RC滤波器还没有建立完成就开始转换。解决把ADC触发改为定时器更新事件触发采样点放到PWM周期中心区域连续采样4到8次取平均如果输入RC滤波电容偏大调小分压电阻阻值以降低时间常数保证建立时间在采样窗口内完成。5.5 电流采样在轻载时偏移反向电流与地弹现象电压环正常电流环在轻载下控制异常读回来的电流出现负值或明显偏大负载稍大才恢复查看采样电阻两端的波形能发现负向压降。原因同步整流的Buck-Boost在轻载进入DCM后如果同步管没有做过零关断电感电流会反向低端采样电阻上的电压极性翻转采到的电流自然变负。另一个原因是采样电阻附近的地弹开关瞬态大电流在接地路径上产生压降叠加到采样信号上。解决先判断是反向电流还是地弹。把示波器探头接到采样电阻两端对比电感电流波形和采样运放输出如果是反向电流做谷底检测电流过零即关断同步管如果是地弹检查采样电阻的开尔文连接和铺地路径采样走线不要跨越功率回路。6. 让它稳下来负载阶跃、环路带宽与效率测量的习惯项目能跑起来只是第一步真正让它在不同工况下都稳定需要一套固定的验证顺序。我的习惯从上电前开始。第一件事示波器双通道量每一对互补PWM的死区波形确认无交叠。第二件事空载上电观察输出电压是否过冲、是否啸叫。第三件事接电子负载做10%~90%的负载阶跃用示波器看输出电压过冲量和恢复时间。负载阶跃过冲建议控制在设定值的5%以内恢复时间在几百微秒量级具体指标看应用场景。环路带宽测量不是每个人都有频率响应分析仪可以用一个土办法在反馈分压点注入一个低频正弦扰动信号示波器同时记录参考点和输出点比较两者的幅度和相位逐步提高扰动频率找到增益降到0dB的频点那就是近似的环路带宽。Buck-Boost的环路带宽我一般压在开关频率的1/10到1/20之间也就是20kHz开关频率下带宽做到1kHz到2kHz再高就容易在采样延迟和数字滤波那里栽跟头。下表是我每次调完电都会过一遍的验收项也是这个开源项目最有价值的部分——它有完整的硬件和代码支撑你去做这些测量。验收项工具通过标准死区波形示波器互补PWM无交叠空载启动过冲示波器小于设定值的5%负载阶跃10%~90%电子负载示波器恢复时间在数百微秒效率功率计满载效率与数据手册或官方参数对比温度热像仪或测温枪满载30分钟电感与MOS管温度在规格内最后说一项我自己翻过车的习惯。早期我调数字电源总是急着把PID的Ki加高觉得稳态误差小了就是成功结果在负载阶跃测试中输出振荡了好几次后来才意识到问题出在我跳过了死区测量就直接上电某个模式下的PWM极性不对环路再怎么调都白搭。从那以后我每次画完板子、写完固件都强制按这个顺序走一遍先量死区、再测空载、然后做负载阶跃、最后才动PID参数。这套流程帮我省下了不少冒烟的代价也让我对这个开源工程的信任度远高于那些只能看文档、不能真正跑起来的项目。希望帮到你。本文还有配套的精品资源点击获取