ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

STM32光储逆变器实时控制:采样、调制与保护实战解析

STM32光储逆变器实时控制:采样、调制与保护实战解析 光储逆变器这个行业聊到后面大家都会认同一句话它本质不是“逆变”而是一台要打进电网、带起负载、还得伺候好电池的可编程电源。而STM32在这台电源里干的活远不只是“跑跑逻辑”而是把采样、调制、保护、通信这些事在一个实时的框架里捏合起来。这篇是STM32在光伏储能应用的下篇。上篇我们把精力放在了主电路拓扑、器件选型和硬件架构上这篇我们把视角切换到控制链路本身ADC怎么采得准、PWM怎么发得好、状态机怎么设计不打架以及那些在调试现场才能撞见、但datasheet里永远查不到的坑。内容偏工程实战适合刚转行做光储的嵌入式工程师也适合那些已经在做电源、想从“能用”进阶到“好用”的同行。1. 换个视角看问题为什么非要把逆变器理解成“电源”先说清楚我这句话的意思。传统电源设计里我们习惯把产品分为电压源和电流源电压源对外输出稳定电压电流源对外输出稳定电流。光伏逆变器并网工作时它的控制目标就是“向电网注入一个可控的正弦电流”所以从电网侧看它就是一台电流源。而离网模式下逆变器要独立建立交流电压给负载供电这时候它就是一台电压源。光储系统比普通逆变器更复杂在于它有三个功率端口光伏输入端口、电池端口、交流输出端口。任何一个端口的变化都会影响另外两个。光伏板功率飘忽不定电池的充放电状态由BMS说了算交流侧可能是并网也可能是离网三个端口之间靠直流母线电压串联在一起。所以这套系统的本质是一台多输入多输出的受控电源所有控制策略的终点都是让能量按预期方向、预期大小流动同时保证母线电压稳定。STM32在这个系统里的角色用一句话概括对外是通信节点对内是实时控制器。它要通过CAN和BMS通信拿到电池允许的充电电流要通过ADC采样光伏电压电流算出MPPT的占空比要捕获电网相位调整逆变桥的调制波还要在过流、过压、过温发生的瞬间比功率器件炸掉之前更快地封锁PWM。这每一件事都不是孤立的它们共享同一个定时器时基、同一个ADC序列、同一个中断优先级。我一直觉得做光储嵌入式开发和做普通消费电子有本质区别。消费电子里MCU是主角外设是陪衬而光储逆变器里MCU是配角功率电路才是主角MCU的任务是“伺候好”功率电路。这个视角一旦建立很多软件上的取舍就变得清晰——比如为什么电流环必须放在中断里为什么CAN通信不能抢占控制周期为什么保护逻辑不能等主循环慢慢轮询。理解了“逆变器本质是电源”这个前提下面这些技术细节才有落脚的框架。2. 核心控制链路采样、调制、保护三件事必须闭环一个并网逆变器的控制周期通常在一百微秒以内。在这个周期里STM32要完成采样、坐标变换、PI运算、PWM占空比更新这一整套动作。但真正决定系统可靠性的并不是这套算法跑得多快而是三个基础环节有没有做好ADC采到的数值是不是真值、PWM发出的波形是不是符合预期、保护路径是不是足够短。这三个环节任何一个掉链子算法再漂亮也白搭。2.1 采样链路ADC读取精度才是控制精度的地基电流采样常见两种方案低功率用采样电阻加差分运放中大功率用霍尔传感器或隔离放大器。采样电阻方案便宜、线性度好但采样电阻上的压降会带来损耗而且电阻功率选型要算清楚。霍尔方案隔离性好、不引入损耗但带宽和温漂要留意。无论是哪种信号进入STM32 ADC之前都要经过一级运放调理把信号幅度映射到ADC的满量程范围。这里有一个非常容易被忽视的问题采样时刻。开关管导通和关断瞬间母线上会叠加极高的dv/dt和di/dt噪声这时候ADC如果刚好在采样读到的数据必然包含大量毛刺。工程上通用的做法是让PWM定时器的溢出事件或某个比较事件去触发ADC启动把采样点放在PWM波形的中点。因为中点处开关管已经稳定母线电压和电流都处于相对平静的状态。用生活类比来说就是不要在放鞭炮的时候去听心跳采样时机选对了后面滤波才能少干活。多通道采样时还要注意通道切换的建立时间。STM32的ADC是单次转换结构通道切换后采样电容需要时间充电到输入电压如果采样时间配得太短相邻通道之间会串扰。我自己的习惯是关键通道如母线电压用独立ADC或者独立采样序列并且每个通道最少配置1.5个采样周期以上DMA方式搬运结果避免CPU逐个读取。软件上再加一阶低通滤波和中位值滤波两级处理中位值滤波专门对付尖峰毛刺低通滤波负责平滑两个滤波器叠加之后波形已经相当干净。采样基准的问题也值得一提。ADC的参考电压如果直接用MCU的工作电压一旦母线波动或电源纹波大参考就会飘。对光储这种功率环境外部基准源比如REF3030这类花不了几块钱却能明显提升采样稳定性。实在不想加外部基准至少也要用内部VREFINT做软件校准把零偏和增益误差修正掉。2.2 PWM调制高级定时器不是拿来点灯的是拿来发波的STM32里能输出互补PWM的定时器不外乎TIM1和TIM8这两路高级定时器。互补输出是驱动全桥/三相桥的刚需因为上下桥臂必须严格保证先关断一个、再开通另一个这个间隔就是死区。死区太短上下管直通炸模块死区太长电流波形畸变、THD劣化。IGBT通常在微秒量级MOSFET可以更短。具体数值要看栅极驱动芯片的传播延时和开关管的关断延时一般留出两倍余量比较稳妥。调制算法上三相并网逆变器主流是SVPWM。它的母线电压利用率比SPWM高大约15%意味着同样的直流电压能输出更高的交流电压而且谐波性能更好。SPWM含三次谐波注入实现简单、适合单相和小功率但三相系统建议直接上SVPWM。软件实现SVPWM就是先判断扇区再计算占空比核心是Clarke变换和扇区判断这部分网上代码很多但真正要命的是载波频率选择。载波频率越高电流纹波越小、电感可以做得更小但开关损耗线性上升。并网逆变器用IGBT一般取8k~16k用碳化硅MOSFET可以到20k以上。载波频率定了之后控制周期就是载波周期的两倍对称PWMADC触发和中断优先级就要围绕这个周期来设计。死区效应在轻载时尤其明显。死区期间电感电流流过续流二极管导致实际输出电压和理想电压有偏差电流过零点附近会产生一段“平台”失真。工程上有做死区补偿的根据电流方向对占空比做前馈调整但电流方向判断不准反而会越补越差。我的建议是先用示波器看电流过零波形确认畸变是否真的影响并网电流THD再决定是否值得花精力做补偿。小功率家用光储产品死区补偿往往是优化项不是必须项。2.3 保护逻辑硬件先挡一刀软件再算账功率器件的损坏时间是微秒级的STM32哪怕中断响应再快也快不过比较器。所以**逐波限流cycle by cycle**这层保护必须用硬件实现电流采样信号进比较器超过阈值直接拉低PWM输出这个周期内的脉冲立即切断不需要CPU参与。等下一个PWM周期到来再重新开通如果过流消失就恢复正常如果持续过流就继续限流。这套机制的响应时间在百纳秒到微秒级是逆变器保护的真正第一道防线。IGBT驱动芯片自带的DESAT保护也很重要。DESAT引脚检测集电极-发射极的饱和压降管子退饱和说明电流过大或者短路了驱动芯片会软关断并将故障信号送给MCU。很多功率模块故障都是这个通道识别的。MCU这边的固件保护主要处理的是过压、欠压、过温这类“慢故障”。慢故障不代表可以慢处理一般推荐在1kHz~10kHz的中断里巡检一旦发现越限先按策略降功率或封锁PWM同时记录故障标志。故障锁存是必须的不能因为过温信号短暂抖动就反复启停要在满足复位条件比如温度降到阈值以下并且用户手动复位之后才能清标志。保护阈值的设计有个经验硬件阈值要宽于软件阈值。软件率先介入通过降功率或者软封锁来恢复正常工况硬件阈值只是最后一道物理防线平时最好碰不到它。这样既能保护设备又不会因为一点小扰动就动不动切机用户体验会好很多。3. 通信与调试通道系统不是一块孤立的控制板光储逆变器从来不单机工作。它要跟BMS说电池剩余电量跟电表说当前输出功率跟EMS能量管理系统收调度指令可能还要跟手机App通信让用户远程看发电数据。这些通信链路看起来是“杂活”但往往直接决定系统能不能在真实场景里长期稳定运行。3.1 CAN与BMS的握手先问清楚电池能承受多大的电流BMS是整个储能系统的“话事人”它最清楚当前电池包的最高单体电压、最低单体电压、SOC和允许充放电电流。逆变器收到这些信息后要动态调整自己的充放电功率绝对不能自己想充多少就充多少。锂电池一旦过充轻则衰减、重则起火这个责任在系统层面是“一票否决”的。CAN硬件设计上收发器推荐用带隔离的方案因为功率板的地和电池包的地之间存在电位差隔离可以避免共模干扰打坏MCU。终端电阻必须是两个120欧姆跨接在总线两端少一个或者多一个都会导致反射通信异常率升高。STM32的bxCAN外设相对老旧发送邮箱只有三个如果数据帧多建议用FIFO思路管理发送并且留一个邮箱给最高优先级的故障帧。接收侧配置好滤波器只放行本机关心的ID避免无效中断抢占CPU时间。实际项目里BMS报文往往会定义心跳机制——BMS每100ms发一帧在线报文逆变器如果在500ms内没收到就认为BMS失联应当按安全的默认策略降功率或关机。这个超时判断不能只靠CAN中断里计数要放到定时器或者主循环里去检查因为中断里计数如果没人定时清很容易出现虚假在线。协议上还有一个容易踩的坑CAN报文的CRC和位填充是硬件做的但数据的有效性要软件确认。收到一帧电池电流指令先判断是否在合理范围内比如0到200A再判断变化率是否合理防止BMS本身发了一帧异常数据导致逆变器跟着犯错。3.2 串口和本地调试printf出去的东西要有用并网逆变器调试最常用的是串口。把printf重定向到UART用USB转串口线连电脑实时打印母线电压、电网相位、MPPT功率、电池电流这些关键量。这里有个实用技巧定义一套简单的命令行解析通过串口输入指令就能修改PID参数、MPPT步长、过压保护阈值等运行参数不用每次改一个参数就重新编译烧录。这个功能前期开发的投入成本不高后期现场调试能省下大量来回改固件的时间。日志输出一定要分级。错误、警告、信息各自用不同的前缀和宏开关控制平时只开信息和错误查问题的时候再开详细调试日志。产品量产之后串口可以保留一个隐藏的诊断模式维护人员进入诊断模式后能看到内部状态变量这比盲猜问题高效得多。另外采样值和控制量打成日志是好事但日志频率不要太高串口115200波特率每行50个字节一秒钟也就打印两百多次超过这个量日志本身就会拖延控制周期一定要控制好打印节奏。除了串口示波器才是控制环调试的真正主角。我的习惯是在板子上预留两个DAC输出或PWM滤波输出把内部控制量比如电流环PI输出、锁相环角度实时输出到示波器上。这样不用拆代码加断点就能看到控制量在动态过程中的真实走向配合功率波形对比问题定位速度比纯靠串口打点快一个数量级。4. 系统状态机与软件架构把“电源”跑稳的核心采样、PWM、通信这些模块是零件真正把它们组装成一套可靠系统的是状态机和调度架构。光储逆变器至少包含这些状态待机、软启动、光伏MPPT、电池充电、电池放电、并网输出、离网输出、故障停机。状态之间怎么切换、切换时PWM怎么处理、切换后控制目标怎么变这是整个软件设计里最容易出bug的地方。4.1 状态机设计切换瞬间的控制“接力”先看一个最典型的切换场景离网转并网。离网模式下逆变器建立自己的电压负载由逆变器供电并网模式下逆变器要跟电网同步、转为电流控制。切换的瞬间如果处理不好轻则负载闪断重则冲击电流烧保险。工程上通常分两步先让逆变器进入电网电压同步状态通过软件锁相环把输出相位锁定到电网相位幅值也调整到与电网一致然后闭合继电器继电器闭合之后再把控制目标从电压控制切换为电流控制。关键是切换的瞬间PI控制器输出的初始值要平滑衔接通常做法是先把电流环给定设为0等稳定一两个工频周期后再逐渐加载目标功率。同样的道理也适用于并网转离网。电网失电瞬间逆变器必须在几个毫秒内从电流源切到电压源模式否则负载感知到断电就掉电了。这个切换速度取决于电压环的响应能力和中断里能否快速更改变换状态软件上建议提前把电压环的PID参数和初始占空比准备好切换发生时直接无缝启用而不是现场重新计算一遍。状态机在代码上的一个重要原则状态入口和出口做集中处理不在主循环里散落一堆“if (状态 某个值)”逻辑。每个状态对应一个enter函数、一个tick函数、一个exit函数切换只在指定的transition函数里发生这样排查状态卡死或者跳变问题会轻松很多。状态机切换前要检查所有前提条件比如并网继电器闭合前必须确认电网电压和频率在允许范围内MPPT启动前必须确认母线电压已经建立否则一上来就是故障。4.2 MPPT与充放电策略能量管理的“三权分立”光伏侧的核心算法是MPPT。最常见的扰动观察法PO思路非常简单往一个方向改变占空比观察功率变化如果功率变大就继续这个方向功率变小就反向。但实际使用中云层遮挡导致的功率突变会让PO误判扰动步长太大会在最大功率点附近来回震荡步长太小又会拖慢跟踪速度。工程上会做变步长处理功率变化大时用大步长快速逼近接近最大功率点时用小步长精细收敛。电导增量法理论上更优但对采样精度要求更高很多产品最后还是PO加变步长的组合成本和复杂度都更可控。电池侧的策略相对直接BMS下发允许充电电流逆变器按恒流充电电池电压接近满充时切换为恒压模式电流自然下降。这个CC-CV切换逻辑要放在控制环外面由状态机根据电池电压主动切换目标值不能等PI控制器自己慢慢绕。另外还需要一个恒功率CP模式用于限制母线电压或者响应电网调度指令说白了就是“规定时间内最多充多少瓦”。这三个功率端口光伏、电池、交流之间的协调最后都归结为母线电压稳定的问题。母线电压是三个端口能量吞吐的中枢光伏输入多了母线电压就升高逆变器要多往电网送电或者加大电池充电功率把母线拉下来电网断电时母线电量少了就要靠电池补。母线电压控制环的带宽通常不高但它是系统级稳定性的关键PID参数不合适时三个端口会互相“抢能量”表现出来就是母线电压低频振荡。调试时务必先用示波器看母线电压的环路响应再决定每个端口各自的内环参数别一上来就盲目加PI增益。4.3 电网锁相过零检测只能做备份软件PLL才能上强度并网控制需要知道电网电压的实时相位用来做dq变换和电流指令合成。早期产品常用过零检测加定时器捕获每个周期抓一个过零点然后按50Hz匀速推算相位。这个方案在电网质量好的时候能用但电网谐波大、频率波动快或者电压跌落时过零检测会产生抖动甚至误触发锁相环相位就会失真。现代工程实现普遍用软件锁相环比如SOGI-PLL二阶广义积分器锁相环。它在静止坐标系下构造一个正交虚拟信号通过PI调节器把电网电压的q轴分量调节到零从而跟踪实时相位。SOGI本身是一个带通滤波器对谐波有一定抑制能力配合PI可以做到几个工频周期内收敛。在STM32上实现SOGI-PLL也就是在每个采样周期跑一次二阶滤波器加一次PI几十微秒的运算量对F103都算不上压力。电网频率的测量倒是可以用定时器捕获来做用于频率保护和电网异常判断但相位跟踪的重任必须交给软件PLL这个分工组合是我比较推荐的架构。4.4 实时性设计控制环放中断业务逻辑放任务光储逆变器的控制实时性要求非常高电流内环周期通常在50到100微秒之间电压外环在1到10毫秒之间。电流内环必须用定时器中断或者ADC中断来调度不能放在操作系统的任务里跑因为任务调度的抖动会直接反映在电流波形上。如果用了FreeRTOS我建议把控制环拿到中断上下文去执行或者给控制任务设置最高优先级并禁止时间片轮转保证一到周期就立刻执行。其他业务逻辑——通信解析、状态上报、按键扫描、显示刷新——放在主循环或者低优先级任务里就可以了。这些逻辑的响应哪怕是几十毫秒对系统稳定性几乎没有影响。中断里只做采样、控制运算和PWM更新不做串口打印、不做CAN发送更不做阻塞等待。很多人在中断里加了teatime的浮点运算导致中断时间过长后续所有任务都被拖慢这一点要特别注意。关于M3和M4的选择如果项目还在选型阶段建议直接选带FPU的M4或M7内核比如STM32F334、G474、F407或者H7系列。三相并网控制里涉及大量的Clarke、Park变换和PI运算没有FPU的话浮点计算会吃掉大量CPU周期控制周期做短就很难了。F334这类带高分辨率定时器HRTIM的型号尤其适合光储这种对PWM精度要求高的场景输出分辨率能到几百皮秒比普通定时器强很多。预算允许的话控制板选型优先看这几个系列而不是盯着F103不放。5. 调试手记与问题排查那些datasheet上查不到的坑这节内容全部来自实战。我不打算系统性地教某个模块怎么用那东西看参考手册就行。我想分享的是几个我在光储项目中真实遇到过、排查了很久才定位的问题每个问题都对应一条可以复用的经验。5.1 ADC多通道切换时数据串扰现象母线电压采样值和实测值偏差大尤其当ADC序列里前一通道是高电压信号时。排查到最后发现是通道切换后采样电容没有充分建立电压——STM32的ADC在通道切换后内部采样电容需要时间充电到目标电压如果采样时间配的过短前一通道的残余电荷会残留造成“串扰”。解决一是把各通道的采样时间配置至少到2.5个周期以上二是把无关紧要的通道排在后面优先保证关键通道的精度三是用DMA循环采集并丢弃每次序列的前两次结果让采样电容充分稳定。如果硬件允许关键信号母线电压、两路电流建议用同一个ADC的不同注入组利用注入通道的独立采样时间配置干扰可以压到最低。5.2 CAN通信跑着跑着“失联”现象系统运行几小时后上位机突然收不到数据重新上电又好了。用CAN分析仪抓总线发现器件进入bus-off状态。原因通常是总线上连续错误太多CAN控制器自动离线。背后的诱因往往是总线上某个节点的时钟偏差过大或者终端电阻匹配不良反射导致位错误累积。解决CAN波特率不要卡在极限值预留余量终端电阻严格检查收发器地线必须和总线共地隔离方案也要保证两侧地电位在安全范围。软件上必须做bus-off恢复STM32的bxCAN有主动恢复模式但恢复之后要做状态同步把自己节点重新接入由外部主机发现。之前项目里做的方案是bus-off后先等50ms然后恢复通信恢复之后先发一帧优先级最高的“节点上线”报文通知主机让主机重新分配发送任务。注意不要在bus-off期间频繁重发越急越乱。5.3 定时器延时函数突然卡死现象程序里用HAL_Delay或者自己写的while延时运行一段时间后卡死在延时函数里看门狗把系统复位。排查发现SysTick的中断被另外一个更高优先级的中断长期挤占或者SysTick的重装载值被某个库函数改掉了。更多的情况是在ADC中断里调用了延时函数而ADC中断的优先级高于SysTickSysTick一直得不到执行延时函数永远数不完。解决第一中断服务函数里绝对不要调用延时函数第二如果确实需要延时用DWT计数器做延时DWT是内核调试单元不受SysTick优先级影响精度高而且不会卡死第三SysTick的优先级不要设成最低至少在定时器中断和ADC中断之下保证系统的时基不能被极端情况饿死。DWT延时的实现网上很多代码就几行值得封装成工具函数存到自己的库里。5.4 按键处理光储设备的人机交互比想象中烦人现象设备面板上的按键按下之后程序要么没反应要么一次按了两次。这是因为按键抖动没有正确处理。光储设备的按键往往直接接在长线缆上感应到的工业干扰比玩具键盘严重得多。解决按键扫描不要在主循环里忙等放一个10ms的定时器中断扫描。扫描逻辑用状态机读到低电平进入“可能按下”状态连续两次都低电平才确认为有效按下释放也一样做两次确认。按键消抖时间要超过振荡周期实践上20ms比较稳妥。长按和短按属于给用户的功能可以通过记录按下持续时长区分一般短按300ms以内长按1秒以上系统别在中断里解析长按逻辑只记录事件主循环里根据事件执行动作。另外按键电路上最好加一个RC滤波和二极管防护软件消抖解决不了所有问题硬件上先挡住一大半干扰后面会省心很多。5.5 打印日志淹没控制节奏现象系统运行基本正常但只要打开串口调试日志电流波形马上出现毛刺逆变器甚至触发过流保护。原因是日志打印阻塞了主循环或者串口中断占用了太多CPU时间导致控制周期被拉长PI控制器在一个周期内执行了两次甚至三次运算输出突变。解决日志输出加节流。一是按时间节流比如每200ms只输出一帧调试数据二是按内容节流用环形缓冲区异步打印中断填缓冲区主循环低优先级任务负责真正发送三是最狠的做法调试模式下关掉控制环只输出开环测试数据避免日志干扰真实控制。我在自己项目里采用的方案是正常模式下只输出错误和告警调试模式下用命令行主动开启详细日志并且日志通过DMA发送不占用CPU——这个组合目前用下来基本没有副作用。5.6 浮点运算性能不足导致的控制周期毛刺现象用STM32F103做三相并网控制控制周期写的是100微秒实际用GPIO翻转测试发现周期抖动达到30%以上电流波形自然也不干净。原因是M3没有FPUClarke变换和PI运算的浮点库调用开销太大再加上中断里可能有隐式类型转换CPU在某个采样点瞬间算不过来下溢事件被拖后PWM更新就发生了抖动。解决选型时优先带FPU的M4/M7代码里如果实在要跑在M3上把坐标变换里的三角函数用查找表替代浮点运算改造成Q格式定点运算。还有一个容易忽略的点整个控制中断代码块里的全局变量尽量声明为volatile避免编译器优化掉重复加载这个虽然影响不大但积少成多。引脚翻转测中断延时的办法建议常驻调试代码里软发布版本里可以留着排查偶发性毛刺时特别有用。5.7 PID参数整定示波器比凭感觉快控制环参数整定这块很多新手喜欢用理论公式算一遍然后直接填参数试机。但功率电路的参数受到母线电容ESR、电感饱和特性、滤波电容寄生参数影响理论计算值和实际差个两三倍都很正常。我的做法是从小PI增益开始先让系统稳定不振荡然后慢慢加大P观察母线电压或电流波形直到出现轻微振荡再回退一点之后加大I消除稳态误差同样以波形临界振荡为参考。整定过程中一定要用示波器看控制量输出比如电流环的PI输出就是调制波如果调制波上下饱和说明增益过大或者母线电压不够。如果调制波形平滑但电流波形畸变大概率是采样问题而不是PI问题先回头查采样别在参数上反复浪费时间。这个“先波形后参数”的排查顺序能帮你少走很多弯路。6. 写在最后把系统装进脑子里从事光储逆变器开发这几年我最大的体会是如果一个工程师只是把自己定位成“写MCU程序的”那他大概率会在系统联调时被各种跨模块的诡异问题折磨到怀疑人生。但如果能从“我做的是一台受控电源”这个角度去理解整个项目很多设计决策会变得非常自然——采样时机跟着PWM走保护层次从硬件到软件逐级递进状态切换优先考虑能量流向是否安全通信和业务逻辑主动避开控制周期。最后分享一个实用的小技巧。调试光储逆变器时强烈建议在硬件设计阶段就预留两路DAC或者用两路PWM经过RC滤波引出模拟信号把母线电压和一路电流的内部控制量实时输出给示波器。这样你能同时看到功率波形和内部控制量两者对照问题定位速度会快得惊人。这个预留电路成本不到十块钱但对开发调试效率的提升是巨大的。这个项目往后走还可以把单向逆变升级成双向储能变流把控制算法从PQ控制扩展到虚拟同步机底层这套“电源思维”的软件框架不需要推倒重来这正是我坚持从电源本质去理解光储逆变器的原因。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表