STM32开关电源并联供电系统:均流控制与PID实现全解析
2026/9/6 21:01:25 网站建设 项目流程

简介:这是一份基于STM32单片机的开关电源并联供电系统完整设计方案,面向嵌入式开发者和电子设计竞赛参赛者。文档完整覆盖从方案论证到系统测试:对比三种DC/DC拓扑与均流控制方案,选定同步BUCK结构,以MOS管IRF3205替代续流二极管来降低损耗、提升效率;详述基于TL494的PWM生成、CSM006NPT电流采样、恒流源并联均流以及过流保护等关键电路,并给出了理论推导、关键元器件参数和实测数据,可直接用于同类电源系统的设计搭建或论文写作参考。资源为1个docx文档,压缩包仅294KB,下载后可直接阅读和编辑。目前已有188人学习下载,适合需要快速理解并联开关电源控制思路的读者。 如果说大学四年哪门课让我真正觉得“学的东西能变成产品”,那一定不是单纯的理论课,而是这个把电力电子和嵌入式控制硬生生揉在一起的项目——基于STM32单片机的开关电源并联供电系统。说实话,刚拿到“并联供电”这几个字时,我以为是拿两个电源模块输出端直接并联,加两个二极管完事。后来才知道,事情远没那么简单,这中间牵扯到均流控制、环流抑制、PWM调节、PID闭环,再加上STM32的ADC采样与定时器输出,一套下来,等于把电力电子、自动控制、单片机嵌入式三门课的核心知识点全部串了一遍。

这个项目到底解决了什么问题?简单说,单路开关电源的输出功率有限,但负载可能瞬间就需要更大的电流,与其买一个昂贵的大功率电源,不如用两个甚至多个中小功率电源模块并联扩容。但直接并联会产生“环流”——即两个电源之间互相充放电,轻则效率低下,重则直接烧毁模块。所以需要一个控制器实时监测每一路电源的输出电流,动态调整各自输出电压,让每一路电流按比例分配。STM32在这里扮演的就是“总调度师”的角色,而开关电源是“执行者”。这篇博文我会从整体设计、硬件电路细节、软件控制逻辑、以及联调过程中踩过的坑四个维度来完整复盘,适合课程设计、毕业设计参考,也适合刚接触开关电源与单片机协同工作的朋友作为入门地图。

1. 项目拆解:并联供电到底在解决什么问题

1.1 从功能需求反推设计指标

看标题“基于STM32单片机的开关电源并联供电系统”,关键词有三个半:STM32、开关电源、并联、供电系统。但作为设计者,不能只看名词,得从使用场景倒推性能指标。

假设要给一个最大功率120W的嵌入式设备供电,比如工业控制板卡、机器人驱动电源等,但手头只有两个60W的24V开关电源模块。最经济的方案就是将这两个60W模块并联,组成一个等效120W的电源系统。这时第一个问题就来了:并联后每个模块输出多少电流?理想状态是每个模块各承担50%的负载电流(即“均流”);如果模块参数不一致,某个模块可能承担80%的电流甚至更多,而另一个模块在“摸鱼”,前者很快过热保护甚至损坏。

所以“并联供电系统”的核心设计指标,不是总输出功率,而是均流精度。常见指标是两路电流不平衡度小于5%,对入门设计来说,能做到10%以内也算合格。第二个指标是切换与保护逻辑:当某一路电源故障时,系统能否快速报警并让另一路模块短时承担全部负载?第三个指标是输出电压稳定度——在并联拓扑下,由于负载变化会引起母线电压跌落,环路响应需要足够快,否则系统会振荡。

1.2 为什么选STM32而不是纯硬件方案

在校期间我第一版方案其实是用纯模拟电路实现的——用LM358运放构成差动放大器,检测两路电流,再通过PI调节器去微调两路电源模块的反馈引脚电压(也就是所谓的“外环调节”)。这个方案电路简单、响应快,但也有三个难以接受的痛点:

  • 参数调整全靠换电阻电容,调试效率极低;
  • 温漂严重,早上调好的均流精度,下午可能就偏差10%以上;
  • 无法做复杂的保护逻辑和状态监控,比如需要判断“是负载短路还是某一路模块故障”时,模电方案基本无能为力。

引入STM32后,均流策略从“模拟PI硬调”变成“数字PID软调”。通过高精度ADC实时采样电流,通过定时器输出两路带死区控制的PWM,调节预加重和反馈基准,动态修正每路电源模块的输出电压。这样不仅调试方便——改算法就行,而且可以根据不同负载工况切换控制策略。STM32系列里我最终选用了STM32F103C8T6,72MHz主频、2路12位ADC、4个16位定时器、内置温度传感器,对于这个项目的算力需求完全够用,而且价格友好、资料丰富,非常适合在学校实验室环境做开发调试。

2. 系统整体设计与核心器件选型

2.1 系统架构与信号流向

整个系统可以划分为四个功能块:功率模块、采样调理电路、STM32主控、以及驱动与执行机构。信号流向是这样的:

  • 功率模块输出端串联精密采样电阻(毫欧级),产生毫伏级电压信号;
  • 电流采样信号经INA282或AD8217等差分放大器放大20~50倍后,送入STM32的ADC引脚;
  • 电压采样通过电阻分压网络,将输出母线电压(比如24V)降到3.3V以下,同样进入ADC;
  • STM32内部运行数字PID算法,算出一个微调量,再通过另一个DAC(或PWM+滤波生成模拟电平)去控制每个电源模块的反馈引脚或TRIM引脚;
  • 当检测到严重过流或短路时,STM32直接控制继电器或电子开关,切断故障路模块的输出,保护整个系统。

这里要特别说明为什么需要“微调反馈引脚”而不是直接串联一个功率管来调整电流。开关电源模块通常都有反馈环路,通过修改反馈引脚的电压参考值,可以将输出电压在一定范围内微调(例如标称24V,可调范围大约21.6V~26.4V,对应±10%)。我们正是利用这个特性,通过STM32控制的“微调电压”来改变某一路模块的输出电压,进而改变它承担的电流。这个思路是整个系统的控制基础,也是最容易被新手忽略的地方。

2.2 主控选型与开发环境搭建

STM32F103C8T6作为主控,具体到本项目需要的资源如下:

资源用途具体说明
ADC1/ADC2采集电流与电压12位分辨率,采样时间可调,建议用DMA循环采样
定时器TIM1/TIM3输出PWM调节微调电压16位,频率20kHz~100kHz
定时器TIM2控制采样节拍触发ADC采样,形成1kHz控制环
UART1调试与上位机通信打印关键参数,方便调参
GPIO控制继电器/报警过流保护、故障指示

开发环境方面,我日常用的是STM32CubeMX + Keil MDK的组合。CubeMX负责引脚初始化和时钟树配置,Keil负责写逻辑代码。很多同学卡在“软件环境搭建”上,其实STM32CubeMX生成工程后,重点只需要关心两件事:ADC采样是否启用了扫描模式和连续转换,TIM输出PWM有没有配置好占空比极性。这两块通了,后续算法反而是最简单的部分。

还有一种小众但值得尝试的配置方式是使用VS Code + PlatformIO + STM32Cube框架开发,插件体系轻量,代码提示比Keil舒服不少,适合习惯了现代IDE的同学。但因为STM32标准外设库的代码范例在Keil下更丰富,第一次做项目的话还是建议老老实实从Keil入手。

3. 电路细节设计:采样、驱动与保护

3.1 电流采样电路:毫欧电阻与INA282放大方案

电流采样是整个系统的“眼睛”,精度直接决定了均流效果。我的选择是使用5毫欧(mΩ)的精密合金电阻作为采样电阻,额定电流10A时,最大压降为50mV。这个压降不能直接送进ADC,需要经过仪表放大器放大。经过比较,我选了INA282,它是一款固定50倍增益的差分放大器,供电电压2.7V~18V,共模输入范围比较宽,非常适合高边电流采样。

电路连接方式:采样电阻放在电源模块输出正端与负载母线正端之间(高边采样),INA282的IN+和IN-分别接到电阻两端,输出经过一个100Ω电阻和一个1nF电容组成的低通滤波器,再接到STM32的ADC引脚。INA282输出计算公式:V_out = (I_load × R_sense) × 50。以5mΩ、10A为例,满量程输出为 10×0.005×50 = 2.5V,在STM32的3.3V ADC量程内,且留了大约25%的裕量,这个设计是比较合理的。

这里有一个非常容易被忽视的坑:采样电阻的布局和走线。既然是毫欧级电阻,PCB走线上哪怕多出10mΩ的寄生电阻,都会造成几十毫伏的误差,直接影响均流精度。所以采样电阻的引脚要采用开尔文接法——即采样信号线直接从电阻两端引出,而不是从电阻的焊盘连线末端引出。同时采样信号线要走差分线,平行贴近,减小噪声拾取。

3.2 微调控制电路:单片机如何“遥控”电源模块

要让STM32能够调节开关电源模块的输出电压,有几种常见工程做法:

  • 方法一:使用STM32的DAC输出模拟电压,接一个运算放大器构成的跟随器,输出连接到电源模块的TRIM引脚(如果有);
  • 方法二:使用定时器的PWM输出,经过两阶RC低通滤波器变成一个直流电平,再经过运放缓冲后接反馈引脚;
  • 方法三:直接使用数字电位器(如MCP4131),串联在反馈电阻分压网络中。

我选用的是方法二,原因有三个:F103C8T6没有内置DAC,外挂DAC芯片(比如MCP4725)会增加成本和布线复杂度;而PWM+RC滤波只要两个电阻两个电容就能实现,非常省事;PWM波形通过RC滤波后虽然有一些纹波,但经过运放缓冲和反馈环路的自身滤波,对电源模块的电压调节影响不大。

具体参数:PWM频率选50kHz,RC低通滤波器截止频率设计为1kHz左右,这样PWM基波被滤除得比较干净,而PID调节信号本身是近直流,可以无损通过。RC参数我用了 R=6.8kΩ、C=22nF,截止频率 = 1 / (2πRC) ≈ 1.06kHz,实测纹波在10mV以内,远小于电源模块输出电压的采样精度需求。

需要特别说明的是,微调电压并不是直接叠加到输出端,而是通过影响电源模块的反馈比较器来实现。大部分开关电源模块的反激或正激拓扑都有一个TL431或精密运放构成的电压环,将输出电压分压后与参考电压(通常2.5V)比较。我们的微调电压如果接入这个分压网络的下端电阻位置,通过改变下端电阻流过的电流,就能等效改变参考电压,从而改变输出电压。理解这一点,你会对“闭环控制”有更深的掌握。

3.3 保护电路:不可省略的一环

很多菜鸟做开关电源项目,有一个坏习惯:只做控制,不做保护。直到某次调试时因为MOS管短路导致负载烧毁,我才痛下决心把保护做到位。实践中,我这套系统至少要有三重保护:

  • 硬件过流保护:在每路输出端串联自恢复保险丝,额定电流的1.2倍,作为最后一道防线;
  • 软件过流保护:STM32通过ADC实时采样电流,如果超过设定阈值(比如9A)持续5ms,立即将对应PWM占空比降为0,同时置位报警GPIO;
  • 输出过压保护:用TL431+可控硅搭一个简单的SCR crowbar电路,当母线电压超过26.5V时,可控硅导通短路输出,熔断保险丝,保护后级负载。

第一重保护是“物理底线”,第二重保护是“常规防线”,第三重保护是“应急逃生通道”。三者的响应速度依次加快,成本依次升高,配合起来才能做到万无一失。这个思路同样适用于其他大功率调试场合。

4. 软件逻辑与核心算法实现

4.1 控制框架:1kHz定频中断 + 主循环任务

软件方面,我并不建议在裸机上跑复杂的实时操作系统。对于这种中等复杂度的控制项目,一个定时器中断 + 一个主循环的简单结构已经足够可靠。

控制节拍用TIM2,配置为1kHz更新中断。在中断服务函数中,依次执行以下动作:

  • 读取并滤波两路ADC电流值;
  • 计算总电流与平均电流;
  • 根据均流误差,运行数字PID(增量式PID,输出PWM占空比微调量);
  • 更新两路PWM的占空比;
  • 清除中断标志位。

主循环则负责不紧急的事务,比如通过UART发送调试信息、扫描按键、刷新OLED显示状态等。

4.2 数字PID实现:从公式到C代码

均流控制的核心是一个增量式数字PID。这里我用的是最常见的位置离散化公式的一种变形:增量式PID,它输出的是“控制量的增量”,而不是“控制量的绝对值”,这样天然有积分饱和抑制效果,且在前一次控制量基础上叠加,不会造成大幅跳变。

我的实现代码如下:

int16_t incPID_Calc(PID_TypeDef *pid, float current, float target) { float error = target - current; float inc; pid->integral += error; if (pid->integral > pid->integral_limit) pid->integral = pid->integral_limit; if (pid->integral < -pid->integral_limit) pid->integral = -pid->integral_limit; inc = pid->Kp * (error - pid->prev_error) + pid->Ki * error + pid->Kd * (error - 2.0f * pid->prev_error + pid->prev_prev_error); pid->prev_prev_error = pid->prev_error; pid->prev_error = error; return (int16_t)inc; }

这段代码里有几个细节值得展开。

第一,我加了积分限幅,即integral_limit。如果不限制积分项,当系统上电瞬间电流偏差很大时,积分项会疯狂累积,导致严重的超调,甚至使PWM快速打到极限,输出过冲。这是数字PID调试中最常见的问题之一。

第二,增量式PID输出的单位是PWM占空比的变化量,不是绝对占空比。所以主函数中需要这样处理:

pwm1 += incPID_Calc(&pid1, current1, average_target); pwm2 -= incPID_Calc(&pid2, current2, average_target);

这里用了“增量互补”的思路:一路增加输出,一路减小输出,形成压差,迫使电流均衡。但需要注意PWM占空比的上下限,通常我将调节上限设置为电源模块微调电压对应的占空比范围(比如20%~80%),超出范围则钳位在边界,防止失控。

第三,关于采样滤波,ADC直采的数据毛刺很大,尤其是开关电源这种强干扰环境。我先做了一次滑动平均滤波(窗口16点),再送入PID。有一点经验是:不要过度滤波,否则会引入相位滞后,导致PID环路振荡。16点窗口在1kHz控制频率下,滞后大约是16ms,能够接受,再大就危险了。

4.3 均流策略实现的完整步骤

最终的核心控制逻辑,整理成清晰的步骤就是:

  1. 系统上电后先执行软启动流程:将两路PWM占空比置为初始值(对应电源模块标称电压),等待输出电压稳定;
  2. 延时500ms后,启动ADC采样,开始软启动到正常运行的平滑过渡;
  3. 进入1kHz控制中断:分别读取两路电流值并滤波,计算总电流和平均目标电流;
  4. 计算两路电流与平均电流的误差,通过增量式PID分别输出调节量,互不影响;
  5. 每次调节后,检查输出占空比是否在允许范围内;如果连续50次控制周期内误差都小于50mA,则判定系统达到均流稳态;
  6. 若某路电流超过保护阈值,立即关闭该路PWM输出,同时打开蜂鸣器报警;
  7. 通过UART实时上传两路电流和占空比数据,方便电脑端画波形调试。

这套逻辑看起来不复杂,但从流程图到代码,再到实际跑通,我整整花了一周半的时间,其中大部分消耗在调PID参数和跟电源噪声做斗争上。

5. 入坑实录:并联供电调试中的典型问题与对策

5.1 STM32连接失败:Error: No STM32 Target Found

用ST-Link下载程序时,遇到了几乎每个STM32新手都会撞见的报错:Error: No STM32 Target Found! If your product embeds Debug Authentication, please...。当时第一反应是芯片烧了,查了一圈后发现根本不是——是BOOT0引脚悬空,导致芯片偶尔进入不了烧录模式。解决办法很简单:BOOT0引脚通过10kΩ电阻下拉到GND,确保默认从Flash启动。

另一个常见原因是目标板没有外部供电,或者SWDIO/SWCLK接线松动。实践中最稳妥的办法是:ST-Link除了接SWDIO、SWCLK、GND之外,也把3.3V引脚接上(前提是目标板I/O电平是3.3V)。这样可以保证烧录时不会因为供电不稳导致连接失败。

5.2 ADC采样值跳变:采样地与功率地混用

第一次联调时,发现两路ADC采样的电流值在空载情况下就有±几十毫安的跳动,而且频率跟开关电源的开关频率(约65kHz)强相关。用示波器一量,发现INA282输出端叠加了几十毫伏的高频噪声,而ADC参考电压VREF+上也有相同频率的毛刺。

这个问题是典型的“地弹”现象。开关电源模块的功率地(承载大电流开关跳变)与控制地(模拟采样参考地)如果直接连在一起,高频噪声就会通过地平面耦合进信号链。解决方案是采用单点接地:将功率地回流的路径单独走一条粗短导线,在电源输入端汇合到一点,控制电路的所有地(包括STM32、INA282、ADC参考地)在这一点连接。同时ADC的参考电压端加一颗100nF + 10μF的去耦电容,放置在芯片附近。

经过这一改,ADC采样值终于稳定下来,空载跳动降到了±3mA以内。

5.3 均流失效:PID参数调节的试错过程

刚开始跑均流算法时,现象很典型:两路电流呈“呼吸效应”——一路电流从3A慢慢爬到8A,另一路从8A慢慢跌到3A,来回震荡,始终稳定不下来。这明显是PID振荡,而且几乎可以肯定是比例项增益过高加上积分项不合适导致的。

我的调试方法是经典的“先P,再I,最后D”:

  • 将Ki和Kd设为0,Kp从小到大递增,观察两路电流响应。当Kp调到某个值(我这里是0.8左右),系统开始出现等幅振荡,记下这个临界值,然后取Kp为临界值的一半;
  • 加入Ki,从很小的值(0.01)开始递增,观察稳态误差是否逐步减小。过程中如果出现低频慢振荡,说明Ki过大,需要回调;
  • 最后加入少量Kd(0.05左右),它主要作用是抑制超调和快速变化的噪声。

最终我采用的PID参数为:Kp = 0.45,Ki = 0.02,Kd = 0.02,控制周期1ms,均流精度实测在3%~5%之间,负载在10%~100%范围内切换时,系统都能在约200ms内重新恢复均流。

如果想加速调参过程,建议在上位机把两路电流和PWM占空比画出实时曲线,用“曲线观察法”代替“数值观察法”,能直观看到振荡周期和阻尼特性,调整参数的效率会成倍提高。

5.4 半桥与反激拓扑的选择困惑

设计硬件时,很多同学纠结到底用哪种开关电源拓扑。这里给一个清晰的选择参考:本项目是“两路现有电源模块并联”的系统架构,主要工作是做模块外部的均流控制,所以直接选用市面上现成的反激式开关电源模块(比如明纬的常用型号)作为功率级;如果是自己从零设计开关电源,反激式适合100W以下的小功率多路输出场景,半桥式则适合300W以上的中大功率单路输出场景,两者在变压器设计和控制芯片选型上差异很大。

反激式开关电源是AC-DC还是DC-DC?严格说,反激拓扑本身既可以是AC-DC(输入经整流桥后加反激变换器),也可以是DC-DC(输入为直流母线电压),拓扑属性并不限定输入源类型。本项目中使用的是DC-DC类型的电源模块。

6. 总结与扩展思考

写到这里,整个基于STM32单片机的开关电源并联供电系统就完整复盘了一遍。从需求分析、器件选型、硬件设计、软件算法到联调排查,这条技术链路几乎覆盖了嵌入式系统开发的全部关键环节。如果只让我留一条最核心的经验,那就是:并联供电系统的难点不是供电,而是“均流”;均流的难点不是电路,而是“采样精度”;采样精度的难点不是芯片,而是“布局与地线”。很多看起来高大上的问题,最后都被一个毫欧电阻的开尔文接法和一个单点接地给解决了。

这个项目之后,我又沿着这个方向做了两个扩展:一是尝试了三路电源模块并联,只需要增加一路采样控制和对应PID即可,均流策略可以无缝扩展,这让我意识到STM32+数字控制的方案在系统扩展性上的巨大优势;二是把均流控制器改造成了基于MODBUS协议的远程可调电源系统,通过RS485总线就能远程设定每路模块的最大输出电流和报警阈值。这些扩展都不需要改动底层电路,只增加了通信接口和相应的软件协议处理。

最后分享一个调试小技巧:给电源模块并联大电解电容时,上电瞬间的冲击电流会非常大,我因为没注意这个细节炸过一次电路板的保险丝。现在的习惯是,在电源输入端串一颗NTC热敏电阻作为软启动限流元件,等电容充满电后再用继电器短接NTC。这个习惯延续到了我后来所有的电源类项目里,从未再失手过。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询