尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

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

STM32数字电源实战:基于ADC采样与PWM的Buck降压设计

STM32数字电源实战:基于ADC采样与PWM的Buck降压设计 STM32这个系列做数字电源说实话在行业里已经不算新鲜事了但每次看到有人用片内ADC直接采输出电压、再用定时器输出PWM驱动Buck电路我还是会觉得这套组合非常经典。它把模拟电源里最麻烦的环路补偿、保护逻辑、参数整定全部搬到了固件里改一个系数就是一次方案迭代这在传统模拟方案里想都不敢想。这篇笔记我不打算讲大而全的理论而是聚焦STM32数字电源设计中最关键的几个外设ADC采样链路、高级定时器PWM、以及过流保护相关的刹车机制然后用手把手的方式带你把一个最简单的Buck降压电源跑起来。适合刚接触数字电源、或者已经会点STM32但不知道怎么把外设组合成电源系统的朋友当然如果你在调环路时被噪声和振荡折磨过这篇也能帮你少踩几个坑。1. 数字电源设计的外设选型与架构思路1.1 为什么STM32适合做数字电源很多人问电源控制为什么不用专门的数字电源控制器比如TI的UCD系列或者一些DSP非要拿STM32这种通用MCU来做我个人的看法是STM32的优势不在极致性能而在外设的完整度和生态成熟度。一个典型的数字电源闭环需要什么高精度ADC采样输出电压和电流PWM模块输出驱动信号比较器或模拟看门狗做快速故障检测然后是足够快的控制中断响应。这些需求STM32基本都能满足F1系列虽然老但12位ADC加高级定时器已经能跑10kHz到几十kHz的开关频率和控制环路G4系列更是带了内置运放和比较器几乎是为数字电源量身定做的H7系列则适合更高速、更复杂的拓扑。选择什么型号取决于你的开关频率和控制精度需求而不是越贵越好。数字电源相对模拟电源的核心优势就是灵活性和可观测性。环路参数不用换电阻电容直接在代码里改PID系数调试时可以把ADC采样值、占空比、误差信号这些中间量全部通过串口或DAC输出出来用上位机看波形分析环路稳定性模拟电路根本做不到这一点。1.2 关键外设清单与分工在做数字电源之前先把外设的分工理清楚后面写代码才不会乱。我通常把一套数字电源系统里的外设划分为三类感知、执行、保护。感知类外设主要是ADC负责采集输出电压、输入电压、电感电流或负载电流。执行类就是定时器PWM产生固定频率、可调占空比的开关驱动信号。保护类则包括比较器、ADC模拟看门狗、定时器的刹车输入端这些外设的目的是在固件还没来得及反应时用硬件把PWM输出封锁掉。这三类外设必须协同工作任何一环掉链子电源都可能出问题。一个容易忽略的外设是DMA。ADC多通道采样如果靠CPU逐次读取中断开销会非常大而且采样时序不稳定。正确的做法是ADC配DMA循环传输让采样数据自动搬运到内存缓冲区CPU只在需要时去读取数组里的最新值。下面这张表是我做数字电源时常用的外设资源分配参考外设功能定位典型配置要点ADC1输出电压/电流采样多通道扫描DMA循环模式ADC2输入电压/温度采样可与ADC1同步采集TIM1/TIM8高频PWM输出互补输出带死区和刹车TIM6/TIM7控制环定时触发固定频率触发ADC或中断COMP部分型号硬件过流保护直接输出到刹车引脚DMAADC数据搬运环形缓冲半满/全满中断串口调试监控打印采样值和占空比1.3 我为什么推荐电压模式控制起步数字电源的控制方式有电压模式、峰值电流模式、平均电流模式等复杂度差别很大。新手做第一个数字电源我强烈建议从电压模式控制开始。电压模式控制就是只采样输出电压和参考电压做差经过PID调节后直接决定PWM占空比。它只有一根控制环不需要电感电流采样硬件简单控制逻辑也容易调试。缺点是动态响应相对慢环路带宽做不高但对于学习和验证外设功能来说完全够了。等你把电压模式跑通了再往电流模式迁移就会发现只是多了一个电流采样通道和一个内环PI控制结构并没有本质变化。基础打牢固了后面的路自然就顺畅。2. 关键外设详解ADC采样链路与精确测量2.1 ADC多通道扫描和DMA配置的细节数字电源里ADC采样有个特点不是采一次就完了而是需要连续、周期性地采。比如你开关频率20kHz控制环也是20kHz意味着每50微秒就要完成一次全部通道的采样和转换这个频率下用单次查询模式的ADCCPU基本被拖死。所以第一件事就是配置ADC为扫描模式加连续转换或定时器触发配合DMA循环传输。我的习惯是开DMA的循环模式配置一个数组缓冲区DMA每次转换完成自动把结果存进数组。这样CPU根本不用管采样过程只需要在控制中断里直接从数组取最新值。配置时要特别注意两个地方。第一ADC采样时间不要太短STM32的ADC是逐次逼近型采样时间短了输入电容充不满采样结果会偏小。数字电源采样电压一般用电阻分压输出阻抗较高我会把采样时间拉到最大或者加一级运放做跟随器降低输出阻抗。第二多通道扫描时通道顺序要和DMA缓冲区一一对应不然采回来的数据错位排查起来非常痛苦。2.2 采样数据的软件滤波和校准ADC原始数据直接用于PID计算通常会出问题因为电源的开关纹波会耦合到采样值里控制环会把这部分高频噪声当成真实误差去响应轻则输出抖动重则整个环路振荡。我在项目里常用两种滤波手段。第一种简单粗暴直接做滑动平均取最新8次或16次采样值求平均代价是会增加延迟第二种是IIR低通滤波用一个一阶滤波公式就够了。一阶IIR的代码如下系数alpha越小滤波越重但延迟也越大需要根据环路带宽权衡我通常在0.1到0.3之间调。float filtered_value 0.0f; float alpha 0.2f; // 滤波系数 void adc_filter(uint16_t raw_value) { filtered_value alpha * (float)raw_value (1.0f - alpha) * filtered_value; }除了滤波校准也很关键。STM32的ADC有偏移误差和增益误差直接测出来的值可能偏差一两个LSB对电压精度要求高的场合不能让这个误差直接进入控制环。最简单的做法是采集两个已知电压点比如0V和一个精密基准然后算出增益和偏移量做线性修正。正规一点的做法是使用ADC内部校准功能很多STM32型号内置了自校准初始化时记得调用一次。我曾经在一版板子上发现输出电压总是比设定值低0.15V左右排查了很久最后定位到是电阻分压的精度问题加上ADC偏移误差叠加导致。后来换用1%精度的分压电阻并在固件里做了两点校准输出精度立刻好了一个数量级。2.3 模拟看门狗不依赖中断的异常检测ADC采样通常交给控制环处理但控制环是有周期的万一控制环卡死或者PID计算异常输出电压可能会飞起来。这时候单靠软件检测是不够的需要模拟看门狗Analog Watchdog这种硬件机制兜底。STM32的ADC模拟看门狗可以设定上限和下限阈值一旦采样值超出这个范围会立刻置位标志并产生中断甚至可以直接触发一些硬件动作。我在数字电源里就把输出电压的上限保护配置为模拟看门狗正常工作时它几乎不占用资源一旦电压越限中断立刻执行保护措施比单纯依赖主循环的轮询快得多。配置模拟看门狗要注意它作用的是哪几个通道。有些型号的ADC支持对扫描序列中的所有通道进行监控有些只支持单个通道需要查参考手册确认。在电源应用里最需要监控的是输出电压和电感电流这两个通道如果你用的型号只支持一个通道监控优先监控电感电流因为电流过冲比电压过冲更危险。3. 关键外设详解高级定时器PWM与硬件保护3.1 高级定时器为什么适合驱动电源开关管STM32系列里有普通定时器和高级定时器做数字电源一定要用高级定时器也就是TIM1和TIM8部分型号还有TIM20等。高级定时器的核心优势在于三点互补PWM输出、死区插入、刹车功能。互补输出是驱动半桥或全桥拓扑的刚需。一个PWM通道输出高边驱动信号互补通道输出低边驱动信号两者中间必须插入死区时间否则上下管会同时导通造成直通短路。STM32高级定时器的死区发生器是硬件实现的精度可以达到几十纳秒级别这对电源安全至关重要。刹车功能更是一个保命的外设。你可以把比较器输出或者外部故障信号直接连接到定时器的刹车输入引脚一旦触发PWM输出立即被硬件拉低不需要软件介入。这个响应时间在纳秒级比固件中断快几个数量级。我设计的每块电源板都会把过流保护信号引到刹车脚上。3.2 死区时间怎么算死区时间设置的依据是开关管的关断延迟和开通延迟。以常见的MOSFET为例关断延迟通常比开通延迟长一些死区时间至少要大于关断延迟减去开通延迟的差值同时还要留出一定裕量。具体计算方式是通过高级定时器的死区寄存器DTG配置。STM32的文档里有一套死区时间的计算公式根据DTG[7:5]的不同范围时基分为三档。举例来说如果你需要200ns的死区使用72MHz的定时器时钟那么每格约13.9ns配置值大约是14到15。手算容易出错我一般直接参考ST官方的参考例程里面有现成的计算宏。提示死区时间设置过大输出波形会出现平顶有效占空比被吃掉输出电压带载能力下降死区时间设置过小则可能出现上下管直通管子瞬间发热烧毁。调试时先用示波器观察栅极驱动波形确认死区合适再上主电。3.3 刹车机制和过流保护的实际接线数字电源的过流保护理想状态下是分级处理的。第一级是硬件比较器直接触发刹车瞬间封锁输出第二级是ADC采样电流后在固件里做慢速过流判断如果电流持续超过阈值但还没到硬件保护的触发点就执行降额或者软关机。硬件比较器可以用STM32G4系列内置的COMP外设也可以用外部比较器芯片。不管是哪种输出端要连接到定时器的刹车输入。STM32高级定时器的刹车输入有多路可以分别配置为高电平有效或低电平有效还能配置自动重装载刹车和可控刹车。我踩过的一个坑是刹车信号的电气连接。早期设计时比较器输出直接接MCU的刹车引脚但电源板功率部分的大电流切换会产生很强的地弹噪声比较器输出被干扰导致PWM偶尔误关断。后来把比较器输出做了RC滤波并用施密特触发器整形才彻底解决。4. 动手实验基于STM32的Buck降压电源4.1 硬件电路搭建和主要参数计算实验目标我设定为输入12V输出5V最大输出电流2A开关频率50kHz。选择Buck拓扑是因为它结构最简单又能完整展现数字电源的各个环节。Buck电路的核心元件是电感、续流二极管或同步整流MOSFET、输出电容。电感值的选择公式是L (Vin - Vout) × D / (ΔI × f)。其中D Vout/Vin 5/12 ≈ 0.417ΔI取输出电流的20%到40%按0.6A纹波计算L (12-5) × 0.417 / (0.6 × 50000) ≈ 97μH取标称100μH。输出电容的选取主要看输出电压纹波要求以及环路稳定性容值大一些对纹波有好处但太大会让环路响应变慢需要配合PID参数调整。这里可以选一个470μF的电解电容并联几个10μF的MLCC兼顾低频储能和高频滤波。采样电路上输出电压用两个电阻分压后进ADC。分压电阻选值时要考虑ADC输入阻抗和功耗的平衡我通常用10kΩ和3.3kΩ的1%精度电阻分压比约3.03。ADC参考电压如果用的是内部VREF精度有限最好外接一个精密基准源比如REF3030这样输出电压精度才有保证。4.2 工程初始化ADCDMAPWM的代码骨架初始化代码我基于STM32CubeMX生成然后手动调整这里把核心配置说清楚。首先配置ADC1为多通道扫描模式通道0接输出电压分压采样通道1接输入电压采样。DMA配置为循环模式数据宽度半字缓冲区两个uint16_t的数组。ADC触发源选择TIM1的更新事件这样PWM每个周期自动触发一次采样保证采样点和开关周期严格同步这是降低采样噪声的重要技巧。接着配置TIM1为PWM模式1输出通道1和通道1N作为互补输出插入500ns死区。PWM频率设置为50kHz对应ARR值为72MHz / 50000 - 1 1439初始占空比设为30%左右等电压环跑起来后由固件自动调节。刹车功能配置为输入有效时输出强制低电平这样硬件保护就能立即断开开关管。最后配置TIM6为500μs周期中断作为控制环的节拍。在主中断里做PID计算更新TIM1的CCR值。这样整个系统的工作流程是PWM周期触发ADC采样DMA搬运数据TIM6定时控制环读取最新采样值并调节占空比。初始化流程中最容易出错的是外设时钟和引脚复用漏配一个GPIO的AF模式整个外设就等于没配置。所以先从CubeMX生成基础工程避免手写寄存器时漏掉某个RCC使能位。4.3 核心控制环PID实现与调试电压模式控制的核心是PID控制器。数字PID的离散公式是输出 Kp × 误差 Ki × 误差积分 Kd × 误差微分。在嵌入式里实现时要注意抗积分饱和、微分滤波、输出限幅这几个工程细节否则理论上再完美的PID到了实际硬件上都可能失控。我常用的PID结构是增量式PID输出的是占空比增量而不是绝对值这样天然带限幅保护也方便做软启动。一个简单的实现如下float pid_update(float target, float current) { float error target - current; float p_out Kp * error; integral error; // 积分限幅防止饱和 if (integral INTEGRAL_LIMIT) integral INTEGRAL_LIMIT; if (integral -INTEGRAL_LIMIT) integral -INTEGRAL_LIMIT; float i_out Ki * integral; float derivative error - last_error; // 微分低通滤掉高频噪声 derivative_filtered alpha * derivative (1 - alpha) * derivative_filtered; float d_out Kd * derivative_filtered; last_error error; float output p_out i_out d_out; // 输出限幅防止占空比突变 if (output PWM_MAX) output PWM_MAX; if (output PWM_MIN) output PWM_MIN; return output; }调参的时候我习惯先让积分和微分归零只调比例项找到临界稳定点。临界比例增益记作Kcr临界振荡周期记作Tcr然后按齐格勒-尼科尔斯经验公式算出Kp、Ki、Kd。这个经验公式给的是一个起点实际调试时还是得靠示波器观察负载阶跃响应来修正。在数字电源里PID参数还会受到采样延迟和控制频率的影响。控制频率越高可以获得的环路带宽越高但延迟也会影响相位裕度。我实测下来50kHz开关频率下控制环跑10kHz是个比较稳妥的起点太高的控制频率反而会因为延迟导致环路不稳定。4.4 软启动和负载阶跃测试直接上电是数字电源调试的大忌。刚上电时输出电容相当于短路如果PID一开始就全力输出瞬间电流可能会烧掉MOSFET。所以软启动是必须的。实现软启动最简单的方式是让参考电压从0缓慢爬升到目标值。比如设定目标5V以每10ms增加0.1V的速度逐步提高参考电压这样输出会平滑地达到目标不会产生过冲。这个功能在代码里只需要用一个软启动计数器在控制环里对目标值做斜率限制即可。负载阶跃测试是用来验证环路动态响应的重要方法。我在输出端接一个电子负载从0.5A突跳到1.5A用示波器观察输出电压的变化。理想的响应是电压有一小幅度跌落几十毫伏然后迅速恢复没有明显振荡。如果看到电压反复震荡说明相位裕度不足需要降低Kp或者增加阻尼如果恢复太慢则说明带宽不够可以尝试提高Kp和Ki。我遇到过最头疼的问题是输出电压在阶跃后出现等幅振荡频率大概是几kHz。排查了很久最后发现是采样滤波太深引入了过大的控制延迟导致环路相位裕度被吃掉。把滤波系数从0.1改到0.3后振荡立即消失。这个案例也说明数字电源的环路调试是一个整体的平衡过程采样延迟、滤波、PID参数必须一起考虑。5. 常见问题与排查技巧实录5.1 快速排查参照表做数字电源调试踩过的坑我整理了一份速查表方便大家上手时对照排查现象可能原因解决思路输出电压偏低分压电阻误差、ADC校准偏差用万用表测量分压点电压做两点校准输出电压纹波大LC滤波器参数不合适、采样噪声耦合加大输出电容优化采样时序和滤波带载后电压跌落严重占空比受限、环路带宽不足检查PWM最大占空比设置提高控制环增益输出振荡相位裕度不足、采样延迟过大降低KP、调整滤波系数用示波器观察环路响应PWM输出突然消失刹车被触发、过流保护误动作检查刹车输入信号排查比较器阈值和噪声干扰开关管异常发热死区时间不足、驱动波形异常用示波器查看栅极波形确认死区设置ADC数据跳动大采样时间不足、参考电压不稳增加采样时间检查VREF引脚滤波电容5.2 深入分析采样噪声导致环路不稳定的实际案例这里展开讲一个我调试中花了两天才解决的问题。现象是输出电压在轻载时正常一加负载就有明显的抖动声示波器看输出波形有大约1kHz的低频振荡叠加在正常的PWM纹波上。一开始我怀疑是PID参数问题把Kp调低积分系数减小振荡幅度有所下降但依然存在。后来用ADC的原始数据去分析发现采样值在加负载后噪声明显增大峰峰值从原来的3个LSB变成了30个LSB。这些噪声进入控制环后被放大器放大最终调制到占空比上形成振荡。问题的根源是PCB布局电流采样回路和功率开关回路没有做单点接地噪声通过地平面耦合进了ADC采样通道。后来重新改板把采样回路的地单独走线距离功率地拉开噪声水平大幅下降环路也稳定了。这个案例让我明白一个道理数字电源的很多疑难杂症根源往往不在固件而在硬件布局。5.3 关于调试工具的几点建议调试数字电源示波器是刚需至少要能同时观察PWM驱动波形和输出电压波形。如果预算有限一个便宜的入门级示波器也够用关键是触发功能要好方便捕捉瞬态过程。逻辑分析仪对于查看PWM和刹车信号的时序关系很有帮助比如确认刹车信号比PWM更新快了多少。如果调试PID参数可以在固件里把PID中间变量通过DAC输出用示波器观察相当于一个简易的数字信号分析仪。最后是串口监控。我会在固件里定期打印ADC采样值、当前占空比、PID输出这些数据配合一个简单的上位机工具画成曲线能直观看到环路的状态。这个做法虽然简陋但很多时候比高级调试器更高效。我用的STM32型号都自带USART接线也简单一根USB转串口线就能搞定。6. 从实验到产品的几个进阶方向如果顺利跑通了上面这套Buck电源说明STM32数字电源的基础链路已经掌握。但在实际产品里还需要处理更多工程化的问题。比如多路输出间的交叉调整率、不同负载状态下的频率切换、以及更复杂的拓扑如LLC、全桥移相等这些都是数字电源工程师日常要面对的内容。我自己在实验板上验证完电压模式控制后紧接着把电路改成了峰值电流模式增加了一路电感电流采样和一个内部比较器。改动最大的不是硬件而是对电流环路的理解——电流内环一旦跑起来输出电压的动态响应会有质的提升。这个进阶过程强烈建议有条件的朋友试一试数字电源的核心竞争力就在多环控制上。另外G4系列的内置运放和比较器真正用起来之后会发现省掉了很多外围器件整个板的面积可以做得很小。我后面做便携式设备的电源方案时已经开始全面转向G4了片内集成度带来的可靠性提升是分立方案比不了的。
返回列表