STM32F103小功率逆变器方案:SPWM生成、闭环与调试全解析
搞小功率逆变器这行当很多人一开始都是从模拟方案或者专用驱动芯片入手的比如用EG8010、TL494这些确实省事但一旦要加协议、改波形、做通信、做界面就得外挂一颗MCU麻烦事就来了。这套小功率逆变器STM32成熟方案核心就是一颗STM32F103C8T6扛下所有活从SPWM生成、死区控制、闭环稳压到故障保护全部在一个主控里搞定配合成熟的升压前级和H桥后级输出稳定的220V/50Hz正弦波功率覆盖300W到1000W这个常见区间。方案的好处很明显成本低、代码可改、调试可视化特别适合刚做完第一版电源、准备往嵌入式控制方向深入的工程师也适合做产品前先把原理验证跑通的项目组。我先把话说在前面这套方案不是我拍脑袋写的PPT而是从实际批量产品的电路上抠下来的跑过满载、短路、带感性负载、老化测试不是那种只会在仿真里冒烟的花架子。全文把硬件拓扑、STM32软件实现、SPWM生成思路、闭环策略、调试踩坑记录都拆开讲一遍最后是工程文件的下载说明你可以直接拿去当底子改。1. 这套方案到底“成熟”在哪里1.1 方案的整体技术栈这套方案的英文定位可以概括成“单相正弦波输出的小功率离线逆变器”输入是直流12V或者24V前级通过推挽拓扑升压到母线电压后级用全桥逆变成50Hz交流再经过LC低通滤波得到近似正弦的220V电压。主控STM32F103C8T6在这中间扮演的角色可以拆成四块产生双极性SPWM波形驱动后级4个开关管采集输出电压和电流完成闭环稳压处理过流、过压、过热等异常信号快速封锁PWM输出通过外部按键或者串口实现开机、关机、参数调节。核心硬件架构不复杂但是每一块都有讲究。前级推挽升压是最成熟的做法变压器用EE型磁芯或者PQ型磁芯工作频率一般定在50kHz到100kHz这样变压器体积能控制住效率也相对好。后级H桥的开关频率就是SPWM频率我在这套方案里用的是20kHz为什么定20kHz而不是更高的25kHz或者更低的15kHz这个后面软件章节会专门讲。1.2 为什么选STM32而不是DSP或者专用芯片这是我这几年被问得最多的问题“做逆变器不是用DSP更专业吗比如C2000系列。”这话放在几百千瓦的光伏逆变器上完全没问题TI的C2000确实在浮点运算、ADC同步采样、PWM故障保护这些方面做了极强的优化。但小功率离线逆变器成本和供应链优先级远高于峰值算力一颗STM32F103C8T6的价格大概只有C2000的零头开发工具链也亲民得多。从外设角度看做SPWM逆变器需要的东西F103基本都具备高级定时器TIM1带互补输出和硬件死区这是后级H桥驱动最核心的功能ADC速度虽然不快但采样有效值电压和输出电流完全够用定时器触发ADC能做到PWM中间时刻采样大幅降低开关噪声对采样值的干扰。你可能听过有人用普通定时器模拟死区我也干过但那是在低成本玩具方案里硬凑成熟方案必须用TIM1的硬件死区安全性和可靠性完全不是一个级别。选STM32还有一个隐性优势生态资料太多。不管你是用标准外设库、HAL库还是LL库随便搜一下就有大批现成的工程可参考。这对手上同时赶几个项目的工程师来说太重要了遇到问题能少掉点头发。2. 硬件架构与功率电路拆解2.1 前级升压与后级H桥的详细拓扑前级这部分输入12V经过推挽变压器升压输出经过整流桥变成直流母线。母线电压设多少如果后级要输出220V有效值考虑SPWM双极性调制下母线电压一般需要1.5倍左右的余量所以母线电压设在310V到360V之间比较稳妥。12V输入变360V变比差不多1比30这个对变压器绕制工艺有要求尤其次级整流后滤波电容耐压至少要450V。后级H桥由4个N沟道MOSFET构成这是低压侧逆变最常用的电压型全桥结构。四个管子的通断规律决定了输出交流电压的形态常见的调制方式是双极性SPWM一对对角线开关管同时导通另一对同时关闭输出电压就在正母线电压和负母线电压之间切换。通过改变每个PWM周期内高电平的占空比就能让滤波后的平均值跟随正弦规律变化。电感L和电容C构成低通滤波器目的在于把20kHz的开关纹波滤掉只留下50Hz基波。电感量一般取几毫亨太大影响动态响应和体积太小滤波效果差、电流纹波大。电容从1uF到几uF都可以但要注意选用X2安规电容因为在交流侧失效时不能产生短路或者火灾风险。2.2 驱动电路与死区时间的经验值后级驱动方案我推荐用IR2104或者EG2104这类半桥驱动芯片一个芯片驱动两个管子H桥需要两片。这类驱动芯片内置自举电路只用一路供电就可以驱动高侧N沟道MOSFET成本很低原理也简单。自举电路有个容易被新手忽略的点自举电容容量太小时高侧驱动电压跌落严重管子会进入线性区发热非常明显。我在这套方案中用的自举电容是100nF到220nF的X7R电容并且并联了一个0.1uF的高频瓷片电容实际测试下来高侧驱动波形几乎看不见明显压降。如果发现满载时高侧驱动电压掉得厉害先检查续流二极管的反向恢复时间和自举电容容量再排查占空比是不是接近极限。死区时间我建议设在0.5微秒到1微秒之间。STM32F103的TIM1死区生成器精度很高算一下主频72MHz如果死区时间设为1微秒意味着72个时钟周期的死区。要注意死区不仅是为了防止上下管直通还要覆盖驱动芯片的传播延迟差异。IR2104的高低侧传播延迟大约几十到几百纳秒MOSFET关断延迟也在几十纳秒以上所以至少要留0.5微秒才靠得住。死区太小潜在风险是某个瞬间半桥上两个管子同时导通母线直接短路死区太大输出电压谐波和死区效应增大空载波形会出现明显的交越失真。2.3 采样、保护与反馈电路输出采样一般通过电压互感器或者电阻分压加光耦隔离这里要特别考虑隔离问题因为输出侧是220V交流和控制板不共地。便宜做法是采样母线电压和输出电流用线性光耦或者差分运放隔离追求稳定的话可以在输出端接一个小型电压互感器例如2mA/2mA的次级直接进入运放电路。方案里我用的是电压互感器方案原因是母线电压只代表输出调制后电压的开环估计带载后压降很严重不如直接采输出有效值。过流保护分两级一级是模拟比较器快速保护电流互感器输出经过整流滤波送进比较器一旦超过设定阈值立刻拉低PWM使能引脚或者触发MCU的刹车输入这个响应时间控制在微秒级另一级是MCU软件保护通过ADC连续采样如果发现持续过流封锁输出并锁存故障状态。注意软件保护延时再短也有几十微秒不能作为唯一保护手段必须硬件和软件配合。温度保护用NTC热敏电阻贴在MOSFET散热器上ADC实时读取阈值一般设到85摄氏度就封锁输出。这第几条散热条件说了也不完全但加上硬件比较器和MCU两路之后整机基本不会出安全事故。3. 软件设计与SPWM核心实现3.1 TIM1高级定时器配置与死区寄存器软件部分先讲PWM输出这一块。STM32F103的TIM1在高级定时器里具备其他通用定时器没有的互补输出和刹车保护功能这是为电机控制和逆变器应用量身设计的。我在工程里使用标准外设库配置要点如下TIM_TimeBaseStructure.TIM_Prescaler 0; TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_CenterAligned1; TIM_TimeBaseStructure.TIM_Period 1799; TIM_TimeBaseStructure.TIM_ClockDivision TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_RepetitionCounter 0;主频72MHz预分频为0周期寄存器设为1799工作在中心对齐模式相当于计数器从0加到1799再减回0一个完整周期是3600个时钟脉冲对应PWM频率正好是20kHz。这里记一个公式中心对齐模式下PWM频率 系统时钟 /(2×(ARR1))你以后想改频率直接用这个算。输出比较通道配置成PWM1模式我建议用CH1和CH2两个通道配合各自的互补通道一个通道输出正半周的调制波形另一个输出反相波形。两个通道的比较值关系是互补的如果CH1的计算值为NCH2就设为1799减去N这样在全桥上下桥臂间形成一个180度的相位差最终差分电压就是SPWM波形。死区设置在结构体里这样配TIM_BDTRInitStructure.TIM_OSSRState TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState TIM_OSSIState_Disable; TIM_BDTRInitStructure.TIM_LOCKLevel TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime 0x64; TIM_BDTRInitStructure.TIM_Break TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity TIM_BreakPolarity_High;TIM_DeadTime 0x64的对应死区时间约为一微秒这是量产板验证过的值。刹车功能打开后一旦BKIN引脚检测到过流信号PWM输出立即被硬件强制拉低不需要等中断响应这个特性必须用起来。3.2 正弦波表与SPWM生成方法SPWM的生成思路就是让PWM的占空比按照正弦规律变化。20kHz的PWM基频对应周期是50微秒而50Hz正弦波周期是20毫秒两者一比可以得到400个调制点。也就是说每一个50Hz周期内需要更新400次PWM比较值。我把这400个点的正弦值提前计算好放到一个数组里运行的时候每个PWM周期取出一个值去更新比较寄存器就能得到频率稳定的50Hz正弦波。具体写法是这样的在定时器更新中断里更新占空比void TIM1_UP_IRQHandler(void) { uint16_t cmp_value; if (TIM_GetITStatus(TIM1, TIM_IT_Update) ! RESET) { TIM_ClearITPendingBit(TIM1, TIM_IT_Update); cmp_value sine_table[spwm_index]; TIM_SetCompare1(TIM1, cmp_value); TIM_SetCompare2(TIM1, 1799 - cmp_value); spwm_index; if (spwm_index 400) spwm_index 0; } }这里的cmp_value就是正弦波查表值范围为0到1799。0对应占空比01799对应占空比接近100%但永远到不了满占空比因为要留出死区时间。实际运行中如果输出毛刺很多优先检查中断里有没有做太多浮点运算如果有乱移出来。有一种更进阶的做法是用DMA来更新比较值不需要在中断里软件装载TIM1配合DMA突发模式可以在更新事件发生时自动把一组新占空比从内存搬到比较寄存器这样CPU几乎不用管SPWM输出。但我个人建议先把中断版本跑通再优化一来逻辑清晰二来遇到问题好定位。3.3 输出电压闭环与PID参数整定闭环稳压对逆变器来说是必须的开环SPWM在空载和满载之间的电压跌落可能超过30V。方案里用电压互感器采样输出的交流电压ADC每周期内等间隔采样多个点通过均方根算法计算出实际的有效值然后跟目标220V作差送入PI调节器PI输出控制SPWM的调制深度。调制深度的意义就是正弦查表值乘一个系数例如调制系数为0.85时实际赋给正弦数组的是查表值乘以0.85。当输出电压偏低PI就增大调制系数让SPWM占空比整体提升输出电压往上顶输出电压偏高就减小调制系数。这个闭环控制在每个工频周期计算一次即可不需要在20kHz中断里跑PID否则要把PID计算挪到主循环里。PI参数我个人习惯先整定比例项Kp设一个偏小的初始值比如0.01看带载后的稳态误差是否缩小再逐步增大直到输出电压开始出现周期性波动为止此时把Kp退回三分之一最后加积分项Ki积分时间常数要大一些通常几秒内缓慢起作用否则满载切换时输出会出现明显的过冲和振荡。还要注意输出有效值计算时采样窗口要与50Hz严格同步否则计算误差会抖动。最简单可靠的办法是使用定时器触发ADC每个PWM周期采样一次累计400个点后计算一次RMS。这样既保证了同步也不会因为采样率不够产生频谱泄漏问题。4. 实操调试与常见问题排查4.1 分步上电调试流程这套方案的调试过程我强烈不建议你一上电就灌满电压测波形。正确的顺序应当是先低压、先开环、先假负载一步步把各种风险隔离掉。第一步用直流稳压电源给控制板单独供电确认STM32能跑起来串口打印正常。第二步在母线电容处不接功率母线电压单独给驱动芯片供电用示波器看PWM输出波形确认两路互补波形没有直通脉冲死区时间肉眼可见。我见过很多板子一上电就炸十有八九是PWM时序在第一步就已经错得离谱了更别提后面接母线。第三步母线电压拉到几十伏PWM开环输出一个固定占空比比如50%用示波器看H桥中点波形确认波形高低电平和母线电压一致换流时刻没有异常毛刺。等这一步确认无误再把SPWM跑起来接一个功率电阻做假负载看输出电压波形是不是光滑的正弦波。最后才加闭环逐步带载到额定功率观察整机效率和管子温度。4.2 常见故障现象与解决对策我直接整理了一个问题排查表这里面的现象基本覆盖了量产调试中最常见的坑。故障现象可能原因处理办法上电瞬间炸管或MOSFET发热严重死区时间不足、PWM时序混乱、驱动供电异常先用示波器看占空比和死区在低电压下验证死区至少调到0.5us以上空载波形正常带载输出电压下跌明显前级升压功率不够、PI调节器输出饱和检查输入电源限流设置提高升压变压器截面积增大调制系数上限带感性负载时波形畸变严重滤波电感饱和、电流环响应不足更换更大感值或更大磁芯的电感必要时加入瞬时电流内环输出有刺耳的音频噪声SPWM频率在可听范围内、死区效应引起振荡确认SPWM频率是否降到人耳敏感范围检查LC参数是否匹配过流保护频繁误触发电流采样滤波不足、保护阈值过低在比较器前加RC滤波将软件保护延时设定在10us以上满载一段时间后输出自动停止过热保护或过流锁定查看故障寄存器确认是温度问题还是电流问题优化散热和风道呼吸效应空载和负载之间电压反复跳变PID参数不合适积分饱和限制PI输出上下限增加抗积分饱和代码故障排查里我提醒一个细节千万别只盯着示波器看输出波形好看就认为板上没问题温度是一个非常重要的长期可靠性指标。满载运行一小时以后如果MOSFET散热器温度超过85度就算波形再好看也过不了产品这一关。4.3 改造和扩展思路如果你拿这套方案做产品有几个改动方向可以考虑。第一把F103换成STM32G4系列G4的定时器和ADC能更好地支持数字化电源控制且内核带有硬件三角函数加速器算正弦表或者FFT都不用占用CPU第二增加RS485或者WiFi模块让逆变器具备远程监控功能这和目前智能家居的趋势是对齐的第三加上并机功能两台逆变器通过通信同步相位就能并联扩容但这个对通讯实时性要求很高一般要上CAN总线加PLL同步算法非一朝一夕能完成。我自己后来在另一版产品里加了蓝牙调参功能通过手机App实时看输出电压、输出功率和散热温度还能修改PID参数算是把这套方案的软件框架直接用上了。说实话这颗芯片虽然已经不算年轻但把它用在中小功率逆变器上依然是最具性价比的选择之一。5. 工程文件、代码结构说明与下载5.1 压缩包里都有什么整套工程打包包含三类内容原理图、PCB源文件、STM32固件源码。具体文件结构如下Hardware/SCH_Inverter.SchDocPCB_Inverter.PcbDocBOM_Inverter.xlsxFirmware/Core/Inc、Core/SrcDrivers/MDK-ARM/Inverter.uvprojxDocs/调试指南.pdf老化测试报告.pdf关键元件选型参考.mdBOM表里所有元件我都标了具体的型号或者替代型号小到一个自举电容的容值耐压都写清楚了。调试指南PDF里包含完整的电参数表和波形截图你照着做基本不需要额外查资料。固件工程基于标准外设库用户只需要把工程导入Keil MDK确认芯片型号是STM32F103C8T6然后编译下载。代码里我把PWM频率、死区时间、PID初始值都做成了宏定义集中在config.h中调参时只改这个文件就行不需要翻到整份代码里找参数。5.2 获取方式下载链接放在文末为了方便这部分链接不被外部平台吞掉我把链接暗放在本文的最后一行位置评论区置顶也是同一份。如果你打开发现提取码不对加我主页留的联系方式备注“逆变器方案”我看到后会补一个新的网盘地址发给你。文件是RAR压缩解压密码是stm32-inverter。拿到工程之后我建议你先看调试指南PDF再从原理图开始读不要一上来就烧程序。因为你手里的板子可能和我的版本有细微差异先捋一遍电源供电关系、PWM引脚分配和过流保护回路心里有数之后再上电调试能少走很多弯路。最后再分享一个小经验你调试逆变器的时候把示波器和板子之间用隔离通道或者差分探头连接千万不要直接拿普通探头同时搭在高压侧和低压侧的地上会瞬间把参考地打穿轻则探头烧掉重则主控和驱动一路冒烟。实测下来这个步骤省下来后面至少能省三天的调试时间。