资讯动态

STM32数字稳压电源源程序深度解析:从PID控制到PWM输出

发布时间:2026/9/8 10:24:52 来源:尧图企业网站定制
简介一套基于STM32F106CT微控制器实现的稳压电源完整工程源码面向嵌入式开发者、电源设计爱好者以及正在学习STM32与闭环控制的学生。项目已完成调试并自带校准功能通过ADC采集输入输出电压、PWM调节功率器件导通时间配合数字滤波与误差补偿可实现小数点后三位的稳压输出精度。压缩包共57个文件约867KB主要包括C源文件、头文件、编译生成的o/axf/map文件以及Keil工程配置uvproj/uvopt便于直接打开工程阅读或烧录验证也适合对照学习外设初始化、中断服务与校准算法。已有316人浏览学习。学习这份工程既能掌握STM32F106CT的定时器、ADC、PWM等外设的实际配置方法也能理解稳压电源从采样、比较到占空比调整的完整控制链路为后续电源或嵌入式项目提供可复用的代码框架与调试思路。 看到这个标题我第一反应是STM32F106CT这型号挺有意思——ST官方并没有这个型号。能想到最接近的是STM32F103C6T6或C8T6再对照“稳压电源源程序”这个关键词基本可以断定这是一套用STM32F103系列做数字稳压电源的工程。这类工程在资料站上流传很广核心价值不在PCB而在源程序里的控制逻辑采样、PID、PWM输出、保护状态机这一套东西搞明白你就能把一块普通电源板变成可调的精密稳压源。这篇文章不打算只给你贴代码而是把这套源程序背后的设计思路、硬件链路、调参方法掰开揉碎讲清楚。适合手里已经有一块类似板子、想看懂固件逻辑的人也适合准备自己从零写一个数字电源控制程序、但还没理清头绪的嵌入式爱好者。我会把整套系统拆成几个关键模块结合实测中遇到的现象把每个环节“为什么这么做”讲透。1. 从“STM32F106CT”说起先确认你手里的板子是什么1.1 型号辨析与最小系统构成先说结论STM32F106CT这个写法大概率是资料打包者笔误。ST在F1系列里真正存在的型号是STM32F103C6T632KB Flash和STM32F103C8T664KB Flash封装都是LQFP48引脚完全兼容。如果你下载的工程里启动文件、链接脚本标注的是HD高密度或者用到了stm32f10x_flash_extend那就是C8T6起步。判断依据很简单工程里如果包含system_stm32f10x.c、stm32f10x_adc.c、stm32f10x_tim.c这些标准外设库文件基本就是F103系列。这类稳压电源控制程序Flash占用通常在20~40KB之间C6T6有些紧张C8T6比较从容所以绝大多数卖家标注“F106CT”的板子实物拆开看必然是F103C8T6。你拿到工程后先看stm32f10x.h里STM32F10X_HD这个宏有没有被定义如果没有还要检查启动文件选的是startup_stm32f10x_hd.s还是startup_stm32f10x_md.s选错会导致程序跑飞。1.2 这套方案的能力边界这类稳压电源的控制核心硬件上其实很朴素MCU加一个数码管或OLED显示屏加几个按键板上有功率调整管、采样电阻、电位器或编码器。源程序要完成的动作无非是“采集输出电压和电流 - 和目标值比较 - 调整PWM或DAC - 控制调整管导通程度”再加上过流、过温保护。明确能力边界对后续调程序很重要。用STM32F103自带的12位ADC和高级定时器PWM能做到的稳压精度一般在10mV级别调整率做到0.5%以内问题不大但指望它和实验室里几万块的程控电源比拼纹波和动态响应那是难为它。这套系统的定位应该是“教学演示 简单实验供电 小功率可调电源”输出功率一般不超过50W电压最高30V左右。搞清楚这个定位调PID参数时才不会钻牛角尖。2. 数字稳压电源的方案选择为什么用MCU做控制核心2.1 模拟方案、开关方案、数字方案的本质差异很多人会问稳压电源用运放加基准源就能做线性电源电路简单又干净为什么非要塞一颗MCU进去我做了一张三类方案的对比表你一看就明白。方案调压方式精度效率灵活性复杂度纯模拟线性电位器调基准中低调整管压降全损耗差无显示无保护联动低开关电源IC反馈电阻定比高高差固定输出或窄范围可调中MCU数字控制ADC采样 PID PWM/DAC高中取决于功率级强可做恒压恒流切换、数字校准、存储预制参数高MCU方案的核心价值不是“更准”而是“可编程”。纯模拟电源的温度漂移、器件老化误差很难补偿数字方案却可以在软件里做校准表甚至每次上电自校准。更重要的是恒压恒流CV/CC两种模式的切换模拟电路要用一堆比较器和逻辑门来实现而MCU里只需要一个状态机几个if语句就搞定了。2.2 控制环路到底在闭环什么理解这套源程序的关键是弄清楚控制环路的被控对象。典型拓扑是MCU输出PWM - 二阶RC滤波得到平滑的直流电压 - 驱动误差放大器和调整管 - 输出端分压电阻采样 - 回到MCU的ADC引脚。这一整个环路本质上是在控制“输出端的分压值等于DAC给定的目标值”。实际工程里有两种常见做法。第一种MCU的DAC直接作为基准源输出目标电压值外部比较器做误差放大这是“硬件闭环、软件调基准”。第二种ADC实时采样输出电压MCU里跑PID算法计算出的控制量通过PWM或DAC去驱动调整管这是“全数字闭环”。你下载到的这套“STM32F106CT稳压电源源程序”从工程文件配置看属于第二种也就是软件闭环。它代码量更大、调试门槛更高但写好后调压更线性也不容易受运放失调电压影响。3. 硬件设计的关键链路与控制链路3.1 功率级拓扑预稳压加线性调整管软件再厉害也得硬件兜底。数字稳压电源的功率级最常见的是“开关预稳压 线性调整管”结构。前级用一个简单的Buck电路把输入电压降到比目标输出高3~5V后级用线性调整管吃掉这个压差。这样既有开关电源的效率又有线性电源的低纹波。当然很多学习板为了简化省掉前级直接用变压器整流滤波后进调整管效果就是发热量大一点中小功率场景勉强能用。这里要特别注意调整管的驱动方式。源程序里控制量最终要能驱动功率管常见是MCU的PWM经滤波后接运放构成的电压跟随器再驱动达林顿管或MOSFET。很多初学者把PWM直接接到MOSFET栅极以为靠占空比就能调节输出电压结果发现输出波形一团糟就是因为缺少了“滤波成直流 缓冲驱动”这两个环节。PWM频率一般选20kHz以上避开音频范围但RC滤波器的截止频率要设计在几百赫兹否则纹波会非常大。3.2 采样链路与反馈环路采样链路决定控制精度。输出电压采样最常用的方法是电阻分压ADC参考电压是3.3V所以分压电阻要把最大输出电压映射到2.5~3.0V区间留出余量。比如说最大输出30V可以选100k和11k的分压比30V时ADC引脚约2.97V。这类细节源程序里一般会有宏定义对应比如VOLTAGE_DIVIDER_RATIO改硬件电阻后必须同步改程序否则显示电压和实际电压对不上。电流采样稍微讲究一点。低端采样采样电阻在负载和地之间电路简单但会抬高负载地电位高端采样需要用差分运放或专门的电流检测放大器。这套板子大多数用低端采样一个毫欧级采样电阻加运放放大送入ADC。需要注意采样电阻的功率假如最大电流3A0.1欧电阻上压降0.3V功耗0.9W至少选2W电阻才安全。这个问题在源程序里看不出来但改硬件时必须算清楚。4. 源程序核心模块逐段拆解4.1 PWM输出与DAC替代逻辑这套工程里没有用芯片内置DACF103C8T6本来也没有而是用定时器的PWM加外部RC滤波来模拟DAC。核心代码逻辑大概是这样的void DAC_Output(uint16_t vol_ref) { uint32_t period 1000; // PWM周期20kHz uint32_t duty vol_ref; // 占空比直接等于数字量 TIM_SetCompare1(TIM1, duty); }为什么可以把占空比直接当数字量用因为RC滤波后的平均电压等于Vcc * duty / period。源程序里通过PID运算得到一个ctl_out范围是0~999直接填进比较寄存器。这里有个坑如果RC滤波器的截止频率设计得太高比如高于10Hz输出就会有可感知的纹波因为滤波不够彻底如果太低PID响应会变得迟钝调整电压后半天才稳定下来。实测下来R取10k、C取4.7uF是个比较稳妥的组合截止频率约3.4Hz既能滤掉20kHz的PWM分量动态响应也不会太差。4.2 PID控制器的完整实现核心控制算法是位置式PID周期性地执行“采样-计算-输出”。工程里的PID函数大致长这样float PID_Calc(float setpoint, float feedback) { float error setpoint - feedback; integral error; if (integral INTEGRAL_MAX) integral INTEGRAL_MAX; if (integral -INTEGRAL_MAX) integral -INTEGRAL_MAX; derivative error - last_error; last_error error; output Kp * error Ki * integral Kd * derivative; if (output PWM_PERIOD) output PWM_PERIOD; if (output 0) output 0; return output; }这段代码有两点很关键。第一是积分限幅INTEGRAL_MAX必须设置否则电源刚上电的几秒内积分项会一直累积到很大导致输出电压“过冲”甚至击穿负载。第二是输出限幅因为PWM占空比有上限所以PID计算完的输出必须钳位。如果你发现电源在轻载时输出振荡、重载时电压掉得厉害多半就是这两个限幅值没调好。调参经验后面专门讲这里先提醒一个容易忽略的点PID的计算频率要固定。源程序里通常用一个定时器中断比如每200us触发一次PID计算和ADC采样相当于5kHz控制频率。不要在主循环里用while(1)加延时来凑合因为主循环会被显示刷新、按键扫描干扰控制周期抖动会让输出噪声恶化。4.3 恒压恒流状态切换稳压电源的恒压恒流功能说穿了就是一个运行模式选择问题。程序里一般用cv_mode和cc_mode两个标志位逻辑非常简单if (current_feedback current_setpoint) { // 进入恒流模式电流目标作为PID的设定值 pid_setpoint current_setpoint; cc_active 1; } else { // 恒压模式电压目标作为PID的设定值 pid_setpoint voltage_setpoint; cc_active 0; }这个切换逻辑看起来简单但实际调试时有个麻烦如果两种模式切换不加入“滞回”在临界点会来回抖动——负载刚好在临界处时显示会在CV和CC之间跳来跳去输出波动让人头疼。解决方法是软件引入迟滞比如电流到达设定值的98%时先进入CC但回到96%以下才切回CV中间留一个缓冲区。另一个方案是让PID控制器在两种模式间做平滑过渡比如对电压环和电流环的输出取较小值这在控制理论里叫“最小输出选择”很多商用电源就是这么干的。具体用哪种取决于你的源程序作者的选择。5. 台架实测PID调参与动态响应5.1 从P到PID的完整调参顺序拿到这套源程序后PID参数大概率不是为你手头硬件调的。直接上电可能出现两种情况输出电压剧烈震荡或者响应慢得像蜗牛。我的调参方法一直很传统先去掉积分和微分项只留比例项从小到大调整Kp。先把Ki设成0、Kd设成0Kp从0.1起步。给一个目标电压观察输出。如果输出稳定但有静差比如设定5V实际只有4.7V说明Kp不够继续加大。如果输出电压开始以固定周期小幅振荡说明Kp偏大了往回退20%。加上Ki从较小的0.01开始逐渐加大观察静态误差是否消除。如果输出出现低频“呼吸”式的波动通常是积分项太强或者积分限幅太大。最后加Kd从0.05开始试。Kd能抑制超调但也会放大高频噪声ADC采样如果不做滤波Kd会让输出毛刺增多。我用调试上位机观察到的典型参数供参考在5kHz控制频率、输出15V/1A条件下Kp大约在1.2~1.8之间Ki在0.02~0.05之间Kd在0.1~0.3之间。但板子换了、采样电阻换了、电感电容换了参数都要重新整定照抄没有意义。5.2 负载调整率与纹波实测硬件和参数整定好之后要关注两项硬指标负载调整率和输出纹波。我用电子负载做过一次步进测试输出设定15V负载从100mA跳变到1A记录电压变化曲线。结果很能说明问题如果PID响应够快电压跌落只有80~120mV恢复时间在2~3ms内如果PID调得过软电压会跌300mV以上恢复时间拉到10ms。而输出纹波主要取决于RC滤波参数和PCB布局纯靠软件压纹波基本不现实但软件能做的是让PID不要引入额外的数字噪声。ADC采样时用硬件均值是必须的源程序里如果做了“连续采样8次取平均”效果立竿见影。6. 踩坑日志驱动能力不足与地线噪声6.1 第一次上电输出跳变的排查链路这个坑我在帮朋友调板子时踩过。现象是板子一上电输出电压瞬间冲到设定值的1.5倍然后慢慢降回来期间还伴随数码管乱码。当时第一反应是PID参数问题但把Kp调小、Ki清零后依然如此。查到最后发现问题出在MCU引脚驱动调整管的环节。调整管是达林顿管基极需要毫安级电流而STM32的GPIO直接驱动能力只有几毫安勉强能驱动但管子工作在放大区边缘导通不彻底。更致命的是上电瞬间MCU的时钟还没初始化完IO口默认是浮空输入状态调整管基极被外部上拉电阻拉高直接全导通输出就冲到最高。解决办法是在GPIO配置和PWM初始化完成之前先用一个硬件电路确保调整管处于截止状态比如在基极加一个下拉电阻到地程序里也要在main函数最开头就把控制引脚拉低然后再初始化时钟和定时器。这个“先关断再初始化”的顺序比任何软件滤波都重要。6.2 采样异常导致的控制发疯地线布局问题还有一个非常隐蔽的坑。现象是输出电压看起来正常但电流显示几乎全部不准——空载时显示还有几百毫安。一开始怀疑是运放失调换过运放、改过放大倍数都没用。用示波器一测ADC引脚波形发现上面叠加了一堆高频毛刺幅度有几百毫伏。根源在于PCB布局功率地和控制地没有分开大电流回流在采样电阻上产生了额外压降直接串进了ADC参考地。MCU的数字噪声、数码管动态扫描的脉冲电流全部耦合进了采样回路。这种问题只能靠硬件改板解决采样电阻的地端单独走线用星型接地方式汇总到电源输入地运放供电加RC去耦ADC引脚对地并一个0.1uF电容。软件层面能做的是在ADC采样时采用“多次采样取中值”的算法过滤掉个别异常点但说到底数字电源控制程序的稳定运行一半靠代码一半靠PCB。代码写得再好硬件地线一团糟控制照样发疯。另外提醒一句这套源程序下载下来后先不要急着改功能先把“时钟配置”“ADC校准”这些基础代码跑通。F103的ADC有一个上电校准流程要等待校准完成再开始转换否则采样值会整体偏移。很多“输出电压误差大”的反馈其实不是PID或者分压电阻的问题只是ADC没有做校准。我自己把这类板子当教学板用给新人讲数字电源的反馈控制原理效果比空讲理论好太多。你如果也是刚接触建议先跑通默认参数用示波器观察关键节点波形再逐步修改PID参数看现象变化最后再去动硬件结构这样对整个闭环控制的理解会非常扎实。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价