简介:这份PDF文档围绕国产GD32F330RBT6微控制器展开三相四桥臂逆变电源设计,面向嵌入式电源开发、电力电子实验教学及毕业设计人群,重点解决数字控制逆变系统的架构搭建、引脚规划与控制策略落地问题。压缩包内仅1个PDF文件,大小约185KB,篇幅紧凑,便于检索、打印和对照原理图阅读。内容从三相四线市电输入、电池充电、推挽升压DC/DC到三相四桥臂逆变的主结构讲起,列出10路PWM及15路AD采样的具体引脚分配,并说明DC/DC单电压环100kHz、逆变R/S/T三相独立电压外环加电流内环、N相开环且控制与开关频率均为19.2kHz的实现方式。文档还涉及基于CMSIS正余弦函数的软件锁相、串口通讯、Flash模拟EEPROM、电池容量检测与充放电保护、逆变过欠压/过流过载/短路/过温保护、串口在线升级及逻辑时序控制。现有533人学习,适合需要梳理数字电源控制框架、保护机制和国产芯片外设分配的工程师与学生参考。
1. 从一颗 GD32F330 说起:三相四桥臂逆变电源为什么值得自己搭一遍
三相四桥臂逆变电源这个题目,乍看像实验室里的东西,真上手才发现它是离网储能里最实用的一档拓扑:三个桥臂管 R、S、T,第四个桥臂专管 N 线,带不平衡负载时中点电压还能拉住。我当时把主控定在 GD32F330RBT6,理由很朴素——国产芯片里这颗料的外设组合刚好卡在够用的位置:TIMER0 三相互补、TIMER15 再补一组、15 个 AD 通道、Flash 塞得下参数区,10 路 PWM 加 15 路采样全塞进一颗芯片,没挂 CPLD,也没上第二颗 MCU。这篇就把这套设计从能量链路、引脚分配、控制环到调试台翻过的车,一次讲透,给正在做类似电源、或者准备把方案换到国产芯片上的人一份能照着搭的参考。
2. 系统结构与器件分工:先把电走通,再谈算法
电源设计里最容易犯的错,是算法还没跑通就开始抠控制参数,结果一上电发现母线根本撑不住、电池充电和逆变打架。所以顺序得反过来:先把能量从市电到电池、从电池到母线、从母线到负载这三段走通,再回头谈环路。
2.1 能量链路的三段拆法
这套系统按原文的结构,是一条「三相四线市电 → 充电电路 → 电池 → 推挽升压 DC/DC → 母线 → 三相四桥臂逆变」的链路。市电在的时候,充电电路给电池补能,同时系统可以由市电直供;市电掉了,电池通过 DC/DC 把电压抬到母线,再由四桥臂逆变出三相交流。
拆成三段来看会更清楚。第一段是充电,本质是个带电池管理的降压或隔离变换,要处理恒流、恒压、浮充三个阶段,还要判断电池有没有接、容量多少、是不是过充;第二段是升压,把电池的低压大电流抬到母线高压,这一段决定了整机能不能带满载启动;第三段才是逆变,把母线直流切出三相正弦。三段的时序耦合很紧:充电没退出就开逆变,母线容易被两头拉扯。
我一般会把三段的状态机分开写,用一个总的调度层串起来,每个状态只允许相邻状态跳转,中间加最小驻留时间。这么做不是为了架构好看,而是调试的时候能一眼看出卡在哪个状态——没有这个,出问题就只能靠猜,那才是真的玄学。
2.2 为什么是推挽升压而不是全桥
电池侧电压低、电流大,这是选拓扑的第一约束。同样输出功率下,全桥在低压侧要过两个管子的压降,推挽只用过一个,导通损耗差一倍。推挽还有两个好处:变压器双向励磁,磁芯利用率高;两管交替驱动,驱动电路不需要高边自举,一路一路下来很干净。
代价也很明确。推挽的开关管要承受两倍于输入电压的电压应力,漏感引起的关断尖峰得靠 RCD 或者有源钳位压住;另外两管交替时,如果占空比接近 50%,变压器偏磁风险会上升,所以实际工程里常把单边占空比压到 0.45 以内,留出死区和偏磁余量。100kHz 的开关频率是个折中:频率再往上,变压器和滤波电感能小一圈,但推挽的开关损耗和驱动损耗会迅速吃掉效率;往下走,滤波体积压不住。
母线电压的下限是可以反推的。四桥臂里每相桥臂相对 N 点输出的是半母线摆幅,要输出有效值 Uo 的相电压,母线至少得满足 Vbus_min ≈ 2×√2×Uo,再留 10% 到 15% 的调节裕量。输出 220V 相电压的话,母线下限就在 620V 往上,这还没算管压降和滤波压降。母线定下来,变压器匝比才能反算,占空比的工作点也才有意义。
2.3 控制板的职责边界:一颗芯片管到哪
原文把 DC/DC 和逆变都做成数字控制,共用一颗 GD32F330RBT6。这个决定省了硬件,但对软件的资源分配要求很高:100kHz 的 DC/DC 环和 19.2kHz 的逆变环跑在同一颗 M4 上,中断优先级排错一次,后面全是连锁反应。
我的排法是:DC/DC 的 PWM 由 TIMER2 产生,控制中断跟着它的更新事件走,优先级最高,因为它管的是母线,母线塌了后面全白搭;逆变环挂在 TIMER0 的更新中断上,19.2kHz 一次,做采样、坐标变换、双环、三次谐波注入和 PWM 占空比更新;锁相和电网检测放在逆变中断里顺带算,不再单开定时器;串口、Flash 模拟 EEPROM、电池管理这些慢任务全部塞进主循环,靠状态机分片执行,绝不占中断。
这个分法有个隐藏收益:中断里跑的东西是周期的、可测的,主循环里跑的是非周期的、可打断的,一旦哪次波形抖了,先看是不是主循环里的慢任务被拉长、把中断挤了。调试时能少走很多弯路。
3. PWM 与 AD 引脚分配:10 路 PWM 和 15 个采样点怎么落到引脚上
引脚分配看着是体力活,实际上是整套系统能不能跑起来的地基。分错一个引脚,后面要么改板,要么在软件里绕出一堆补丁,血泪经验。
3.1 10 路 PWM 的分配逻辑
系统要 1 组 DC/DC 驱动加 4 组逆变驱动,一共 10 路,正好对应 GD32F330 的 TIMER0、TIMER2、TIMER15 三个定时器:
| Pin | 功能 | 定时器通道 | 说明 |
|---|---|---|---|
| PC6 | DCDCPWM1 | TIMER2_CH0 | 推挽主管一路 |
| PC7 | DCDCPWM1 | TIMER2_CH1 | 推挽主管另一路,与 CH0 交替 |
| PA8 | R_PWM_H | TIMER0_CH0 | R 相上管 |
| PB13 | R_PWM_L | TIMER0_CH0_ON | R 相下管,CH0 互补脚 |
| PA9 | S_PWM_H | TIMER0_CH1 | S 相上管 |
| PB14 | S_PWM_L | TIMER0_CH1_ON | S 相下管,CH1 互补脚 |
| PA10 | T_PWM_H | TIMER0_CH2 | T 相上管 |
| PB15 | T_PWM_L | TIMER0_CH2_ON | T 相下管,CH2 互补脚 |
| PB8 | N_PWM_H | TIMER15_CH0 | N 相上管 |
| PN8 | N_PWM_L | TIMER15_CH0_ON | N 相下管,CH0 互补脚 |
排这张表有三个原则。第一,同一相的上下管必须来自同一个定时器的 CHx 和 CHx_ON,这样死区由硬件插入,软件只管给占空比,不会因为两条中断跑偏导致直通。第二,R、S、T 三相必须共用 TIMER0,三路 PWM 的载波相位天然对齐,三次谐波注入才有意义;如果三相分散到不同定时器,光是相位对齐就够折腾。第三,N 相单独用 TIMER15,因为它是开环输出,跟三相不需要严格同相,独立定时器反而方便单独调它的占空比。
3.2 互补输出与死区:19.2kHz 下死区怎么定
19.2kHz 的开关频率,一个周期是 52.08us。死区时间通常取开关管关断时间加驱动延时,再留一点余量,IGBT 方案常见 1us 到 2us,MOSFET 方案可以压到 0.5us 左右。取 1us 的话,占了一个周期的 1.9%,对占空比上限有实打实的挤压,算最大调制比的时候必须把这部分扣掉。
/* GD32F330 TIMER0 互补输出与死区配置(寄存器/库函数示意,字段名以对应手册为准) */ timer_parameter_struct tp; timer_struct_para_init(&tp); tp.prescaler = 0; /* TIMER0 时钟 120MHz,不分频 */ tp.period = 6249; /* 120MHz / (6249+1) = 19.2kHz */ tp.clockdivision = TIMER_CKDIV_DIV1; tp.counterdirection = TIMER_COUNTER_UP; timer_init(TIMER0, &tp); /* 三相互补:CH0/CH1/CH2 输出,CHx_ON 为硬件互补脚 */ timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0); timer_channel_output_shadow_config(TIMER0, TIMER_CH_0, TIMER_OC_SHADOW_ENABLE); timer_channel_complementary_output_enable(TIMER0, TIMER_CH_0); /* CH1、CH2 同样配置,略 */ /* 死区:DTCFG 编码是非线性的,按手册表反查接近 1.0us 的档位, 不要直接拿“周期数”当死区值往里写 */ timer_break_parameter_struct bp; timer_break_struct_para_init(&bp); bp.deadtime = DEADTIME_CODE_1US; /* 目标 1us,具体档位查表 */ bp.breakstate = TIMER_BREAK_DISABLE; timer_break_config(TIMER0, &bp); timer_primary_output_config(TIMER0, ENABLE); /* POEN 使能,互补脚才真正输出 */这段代码里两个参数最容易被写错。一个是period,它决定开关频率,也决定控制中断的节奏,改了它整个环路的时间常数都要跟着重算;另一个是死区档位,很多定时器的死区编码是分段步进的,前段一位一步、后段几位一步,直接填数字会得到完全不符实际的死区,轻则波形畸变,重则上下管直通。
timer_primary_output_config那一行也值得单独说。互补输出使能了、通道配好了,但如果 POEN 没开,引脚上什么都不会有,示波器一测全是低电平,新手很容易在这里怀疑人生。我习惯把它放在初始化最后一步,并且在调试阶段用 IO 翻转标记一下走到哪儿了。
3.3 15 路 AD 通道与采样时序预算
系统一共采 15 个量,覆盖输出、电流、市电、母线、电池、温度和两路参数:
| 通道 | 信号 | 用途 |
|---|---|---|
| PA0 / PA1 / PA2 | R/S/T 相输出电压 | 电压外环反馈 |
| PA3 / PA4 / PA5 | R/S/T 相电感电流 | 电流内环反馈、过流判断 |
| PA6 / PA7 / PB0 | R/S/T 相市电电压 | 锁相、市电有效性判断 |
| PB1 | 母线电压 | DC/DC 电压环、欠压保护 |
| PC0 | 电池电压 | 电池管理、低压保护 |
| PC1 | 充电电流 | 恒流充电控制 |
| PC2 | 散热器温度 | 过温降额与保护 |
| PC4 / PC5 | 参数 1 / 参数 2 | 档位或配置选择 |
时序预算得先算清楚。假设 ADC 时钟 12MHz,采样时间设 7.5 个周期,一次转换是 (7.5+12.5)/12MHz ≈ 1.67us,15 路全采完约 25us,塞进 52us 的控制周期里理论上够,但只剩一半余量,中断里再算双环和三次谐波注入就有点紧。
更稳的做法是分组:输出三相电压、三相电感电流、母线电压这 7 路是控制刚需,用 PWM 更新事件触发,走规则组加 DMA 自动搬运,保证采样点和开关时刻严格同步;市电三相、电池电压、充电电流、温度、两路参数这 8 路是慢变量,放到控制周期的偶数拍或直接在主循环里轮询,不占中断时间。
采样点对齐这件事必须强调。电感电流要在下管导通的中点采,采在开关沿上会混进开关噪声,波形上就是一个尖刺,环路上表现为莫名其妙的抖动。规则组由定时器触发的好处就在这——触发点跟着 PWM 走,不管主循环多忙,采样时刻不变。
4. DC/DC 与三相四桥臂的控制环:100kHz 和 19.2kHz 两套节奏
两个环跑在两个频率上,是这套设计最需要想清楚的地方。DC/DC 的 100kHz 环响应快、带宽高,管的是母线这个「全局变量」;逆变的 19.2kHz 环管的是三相输出这个「局部变量」,还得受母线波动影响。两个环不能各调各的,得有一个明确的从属关系。
4.1 推挽 DC/DC 的单电压环:100kHz 不是越高越好
推挽这一级用单电压环,采母线电压,跟给定值比较,PI 输出直接调占空比。100kHz 的开关频率给了环路很大的带宽空间,但真把带宽拉到几 kHz 并不明智——母线电容和负载的谐振点、采样噪声、变压器的漏感都会在某个频段给你难堪。
我通常把电压环穿越频率压到开关频率的 1/20 到 1/10,也就是 5kHz 到 10kHz 之间,相位裕度留 45 度以上。PI 的积分项要配合抗饱和:启动瞬间误差很大,积分器会一直累加,等母线追上来了还在往上冲,直接过压保护。做法是给积分项设上下限,或者用条件积分,误差大时先不积分,等进入线性区再放开。
还有一个容易忽略的点:推挽两管交替,如果两路占空比不完全一致,变压器会慢慢偏磁,偏到饱和就是一次炸管。软件上可以让两路共用同一个占空比寄存器值,硬件上靠隔直电容兜底,两边都做才踏实。
4.2 三相四桥臂:三次谐波注入、双环与 N 相开环
R、S、T 三相的控制结构是电压外环加电流内环,这跟常规三相逆变器一样。电压外环给电流内环下指令,电流内环追指令,两者的时间尺度要拉开:电压外环带宽一般在几百 Hz,电流内环可以做到 1kHz 到 2kHz,内环比外环快五到十倍,外环才不会因为内环的滞后而振荡。
三次谐波注入的作用是提高直流电压利用率。做法不复杂:算出三相调制波的瞬时最大值和最小值,取中点,再从每一相里减掉这个中点值——这等效于往调制波里注入幅值约 1/6 基波的三次谐波,把波峰削平,同样母线电压下能多输出约 15% 的基波幅值。实现上就是在双环输出之后、写比较寄存器之前加一步中点计算,几行代码的事,但省下来的母线电压是实打实的。
/* 三次谐波注入(中点钳位式),在双环计算之后、更新 PWM 之前执行 */ float va = duty_a, vb = duty_b, vc = duty_c; /* 双环输出的三相占空比指令,已归一化 */ float vmax = va > vb ? (va > vc ? va : vc) : (vb > vc ? vb : vc); float vmin = va < vb ? (va < vc ? va : vc) : (vb < vc ? vb : vc); float voff = 0.5f * (vmax + vmin); /* 取中点作为共模注入量 */ duty_a = va - voff; duty_b = vb - voff; duty_c = vc - voff; /* 注入后仍需限幅,防止调制比越界导致波形削顶 */这段的关键是voff取的是最大最小值的中间点,不是简单加一个三倍频正弦。用中点法的好处是不需要额外算 sin(3ωt),也不依赖锁相角的准确度,代价是共模分量的波形不太规整,但对四桥臂这种拓扑影响很小,因为 N 桥臂本来就是独立控制的。
N 相是开环,这是原文的取舍,也是这套方案最有意思的地方。四桥臂的第四桥臂本来是拿来补偿中点电压的,闭环做当然更好,但要多一路采样、多一个环、多一组参数,调试成本翻倍。开环的做法是给 N 桥臂一个接近 50% 的固定占空比,让 N 点通过滤波电感钉在母线中点附近。负载平衡的时候没问题,不平衡的时候中点会偏移,输出波形对称性下降。
我的处理是在开环基础上加一层慢修正:用三相输出电压的直流分量估出中点偏移方向,几 Hz 的慢环微调 N 相占空比,不动快环。这样既保留了开环的简单,又不会在带单相负载时波形歪得离谱。
4.3 软件锁相:CMSIS 正余弦用对了才不飘
市电检测要做锁相,目的是拿到电网的相位角,让逆变输出跟电网同步,切换的时候不至于打火。原文用了 CMSIS 库里的正余弦函数,这个选择很实际——比查表省 Flash,比手写泰勒展开精度稳定,M4 上跑一次几十个周期,19.2kHz 的周期里完全够用。
锁相的结构是派克变换加 PI。把三相市电电压做 Clarke 变换得到 α、β,再用当前角度做 Park 变换,q 轴分量就是相位误差,PI 把它压到零,输出的角速度积分成角度。
/* 基于 Park 变换的软件锁相,运行在 19.2kHz 控制中断里 */ static float theta = 0.0f; /* 当前相位角,弧度 */ static float pi_integ = 0.0f; /* 积分项 */ void pll_update(float ua, float ub, float uc, float dt) { /* Clarke 变换,三相到两相静止坐标 */ float alpha = (2.0f / 3.0f) * (ua - 0.5f * ub - 0.5f * uc); float beta = (2.0f / 3.0f) * 0.8660254f * (ub - uc); /* CMSIS 正余弦,比查表省 Flash,精度也稳 */ float s = arm_sin_f32(theta); float c = arm_cos_f32(theta); float uq = -alpha * s + beta * c; /* q 轴分量,锁定后应趋近于 0 */ float err = -uq; /* 负反馈,方向反了会直接发散 */ pi_integ += KI * err * dt; if (pi_integ > FREQ_MAX) pi_integ = FREQ_MAX; /* 限幅,防止失锁后积分跑飞 */ if (pi_integ < -FREQ_MAX) pi_integ = -FREQ_MAX; float omega = pi_integ + KP * err; /* 角速度,rad/s */ theta += omega * dt; /* 角度折回 [0, 2π),否则 float 精度随运行时间衰减,跑几小时就飘 */ if (theta >= TWO_PI) theta -= TWO_PI; if (theta < 0.0f) theta += TWO_PI; }参数上有三个地方要盯。dt必须和控制周期严格一致,用定时器计数值算,不要用理论值;FREQ_MAX是频率限幅,对应允许的电网频率偏移范围,限得太死正常波动也会失锁,限得太松失锁后角度会一路狂奔;KP、KI决定锁相带宽,带宽高了抗扰但抖动,低了平滑但跟不上电网频率变化,二十几 Hz 的带宽是个常见起点。
角度折叠那一行看着不起眼,但没有它,float 的尾数精度会随着 theta 不断增大而衰减,跑上几个小时相位误差就肉眼可见了。这种问题在台架上短时间测不出来,非得等整机老化才发现,属于典型的后悔药。
5. 避坑与排查:调试台上最容易翻车的五个坑
下面这五条基本覆盖了从第一次上电到带载老化最容易出问题的地方,每条按现象、原因、解决三步写,遇到对得上的直接照着查。
5.1 上电就炸管:死区没生效或没使能主输出
现象:第一次上电,保险丝直接断,拆开一看上下管全短。
原因多半有两个。一是死区配置写了但没生效,互补通道的时间参数没跟着改,写进去的值被硬件当成无效档位;二是互补输出配好了,但主输出使能(POEN)那一位置了 0,看起来引脚有波形,其实是驱动侧的浮空电平在作怪。
解决:上电前先用示波器看两路互补 PWM 的死区,量的是上下管驱动信号同时为低的那段时间,不是看占空比;确认timer_primary_output_config在初始化最后被调用;母线首次上电必须串限流电阻或者用可调电源限流,别直接怼。
5.2 电流波形全是毛刺:采样点落在开关沿上
现象:电感电流采样值在示波器上是一条粗线,FFT 一看开关频率及其倍频分量很大,电流环输出跟着抖。
原因:采样触发时刻跟着软件延时走,或者规则组由软件启动,正好撞上开关管动作的瞬间。功率回路的 dv/dt 通过采样电阻和走线耦合进来,幅度能盖过真实信号。
解决:改成由定时器更新事件触发 ADC,触发点设置在下管导通的中点;采样窗口不要贴着开关沿,前面留一点建立时间;硬件上采样走线远离功率回路,采样电阻用四线接法。改完之后毛刺能掉一个数量级,环路参数也就不用再迁就噪声了。
5.3 参数存进去读出来是乱码:Flash 模拟 EEPROM 没做双备份
现象:调好的参数掉电再上电就变了,有时候整片参数区读出来全是 0xFF。
原因:Flash 写之前没擦除,或者擦除过程中掉电,整页数据一起没了;也有的是把参数结构体直接按字节写进去,结构体对齐变了,读出来就错位。
解决:参数区至少分两页轮换写,写之前先校验旧数据,新数据写完再打标志;结构体加版本号和 CRC,读出来先校验再使用;擦写期间关中断,别让控制中断插进来打断时序。这一条吃过一次亏之后,我所有带参数存储的项目都会先验证掉电恢复。
5.4 市电畸变时锁相失锁:PI 限幅和滤波没配套
现象:市电波形带谐波或者电压跌落时,锁相角突然跳变,逆变输出跟着抖一下,严重时直接切离网。
原因:q 轴误差里混进了低次谐波,PI 把它当真实相位误差去追,积分项越积越大;或者频率限幅设得太窄,电网频率正常波动就顶到边界。
解决:进锁相之前先对三相电压做一次低通或者滑动平均,把五次、七次谐波压掉;PI 的积分项限幅要跟允许的频率偏移对应,别随手写个大数;再加一个失锁判据,q 轴误差持续超限超过若干个电网周期就报警,而不是让角度一路跑飞。
5.5 保护频繁误动作:阈值和滤波时间没配对
现象:带感性负载启动,过流保护偶发性动作,复位后又正常;或者短路了保护却不动作。
原因:保护判据只看瞬时值,启动冲击电流一下就顶到阈值;反过来,如果只看有效值又加了很长的滤波,真短路时响应就慢半拍。
解决:分两级,一级用瞬时值做硬件或者中断里的快速比较,阈值设在额定峰值的两倍以上,专门抓短路;另一级用几个周期的有效值做软件判断,管过载。两级的时间常数分开调,别用同一个滤波系数。逆变输出的过欠压、过温也是同理,阈值、延时、恢复条件三个都要明确写出来,不能只写个阈值了事。
6. 一颗芯片装下所有功能:资源账怎么算,以及一个能省很多事的技巧
功能列出来一大串:串口通讯、Flash 模拟 EEPROM、充电与电池管理、四类保护、串口在线升级、时序逻辑。听着像要两颗芯片,实际上一颗 GD32F330RBT6 就能兜住,前提是资源账要提前算。
| 资源 | 占用估算 | 备注 |
|---|---|---|
| Flash | 控制算法与保护约占一半,Bootloader 与参数区各留独立扇区 | 升级区不能和参数区重叠 |
| RAM | 采样缓冲、双环状态量、锁相状态、串口收发缓冲 | 中断里的变量全部用静态分配,不用动态内存 |
| 定时器 | TIMER0 三相、TIMER2 推挽、TIMER15 N 相、一路做系统节拍 | 系统节拍不能和高频 PWM 共用 |
| ADC | 15 通道,规则组 7 路加轮询 8 路 | 规则组走 DMA,不占 CPU |
| 串口 | 一路升级与通讯复用 | 升级期间业务通讯暂停 |
算完这笔账会发现,真正紧张的不是算力,是 Flash 的分区规划。串口在线升级要留 Bootloader,还要留升级标志和参数区,三块地址一旦重叠,升级时把参数擦了或者跳转跳错,整机就变砖。
/* Bootloader 跳转到应用前必须做的三件事,少一件都可能 HardFault */ void jump_to_app(uint32_t app_addr) { uint32_t sp = *(volatile uint32_t *)app_addr; /* 应用向量表第一个字是栈顶 */ uint32_t pc = *(volatile uint32_t *)(app_addr + 4); /* 第二个字是复位向量 */ if ((sp & 0xFFF00000) != 0x20000000) return; /* 栈顶必须在 RAM 区间,否则不跳 */ if (pc < app_addr || pc > 0x08040000) return; /* 复位向量必须在应用区,防止跳飞 */ __disable_irq(); /* 跳转前关总中断 */ for (int i = 0; i < 8; i++) NVIC->ICER[i] = 0xFFFFFFFF; /* 清所有中断使能 */ SCB->VTOR = app_addr; /* 重定向向量表 */ __set_MSP(sp); /* 设栈顶 */ ((void (*)(void))pc)(); /* 跳过去,不会返回 */ }两个地址校验是最值得加的几行代码。升级包传输出错、写 Flash 写了一半掉电,向量表里的值就是垃圾,不校验直接跳,表现是上电无反应,现场只能返修。加上校验之后,跳不过去就停在 Bootloader 等下一次升级,至少还能救回来。
回过头看这套设计,真正让我改了习惯的不是哪个算法,而是那次母线过压:积分项没限幅,启动瞬间母线冲到保护点,一串管子跟着报废。从那以后我每次写 PI,不管电压环电流环,都强制先把积分限幅、抗饱和和上电初值这三件事写完,再动别的参数。硬件上电也一律先限流、后满载。希望这些踩过的坑,能让你少走两段弯路。
本文还有配套的精品资源,点击获取