1. 从电赛A题说起:单相交流电子负载到底是个什么东西
如果你参加过电子设计竞赛,或者正在准备某个电力电子方向的毕业设计,大概率听过“单相交流电子负载”这个题目。我第一次接触它是在帮学弟看电赛A题的方案,当时他拿着一堆MOS管和电感问我:“这玩意儿到底怎么把电能‘吃’进去又‘吐’出来?”这个问题其实问到了核心——电子负载不是把能量变成热耗散掉,而是要把被测电源输出的交流电能“回收”利用,或者至少做到可控地模拟各种负载特性。
传统负载就是电阻、电感、电容,接上去之后功率因数固定、电流波形固定,想测一个电源在不同负载条件下的表现,你得换一堆电阻箱,又笨又热。电子负载用电力电子变换器来模拟负载,你可以通过程序设定它呈现阻性、感性、容性,甚至模拟一个非线性负载,电流波形想怎么捏就怎么捏。单相交流电子负载就是针对单相交流电源的测试设备,输入侧接被测电源,输出侧通常接电网或者直流母线,把能量回馈回去。
那SPWM在这里扮演什么角色?简单说,SPWM就是“用开关管拼出一个正弦波”的技术。你有一堆直流电压,想让输出端得到一个正弦交流电压或者电流,最直接的办法就是让开关管按照正弦规律通断,输出一系列宽度按正弦变化的脉冲,再经过电感电容滤波,就得到了正弦波。这个“按正弦规律改变脉冲宽度”的过程就是SPWM。在单相交流电子负载里,SPWM用来控制输入侧变换器的电流,让输入电流跟踪给定参考,从而实现功率因数可控、电流波形可控。
STM32在这套系统里就是大脑。它要完成几件事:采集输入电压电流、计算参考电流、生成SPWM驱动信号、处理保护逻辑、跟上位机通信。为什么选STM32而不是其他MCU?因为STM32的定时器资源丰富,高级定时器带互补输出和死区插入,正好驱动全桥电路;ADC采样速度快,配合DMA可以做到无CPU干预的连续采样;主频够高,跑一个电流环加SPWM生成绰绰有余。我见过有人用DSP做,性能确实好,但成本和开发门槛对电赛或者本科毕设来说偏高,STM32是性价比最平衡的选择。
这套东西适合谁看?如果你正在做电赛电源类题目、电力电子课程设计、或者想入门数字电源控制,这篇文章就是给你写的。我会从整体方案讲起,把SPWM生成的原理、STM32的配置、电路参数计算、调试中踩过的坑全部摊开讲。不需要你有很深的电力电子背景,但至少得知道MOS管怎么开关、电感电容的基本特性。
2. 整体方案设计与核心思路拆解
2.1 为什么选全桥+SPWM+电流闭环这套架构
单相交流电子负载的拓扑选择其实有好几种:Boost型、Buck型、全桥型、半桥型。Boost型只能升压,输入电压低于母线电压时没法工作;Buck型只能降压,输入电压高于母线时受限。全桥结构最灵活,四个开关管组成H桥,通过SPWM控制可以实现输入电流的双向流动,既能吸收能量也能回馈能量,而且输入电压范围宽,母线电压只要高于输入电压峰值就能正常工作。
我最终选的是电压型全桥PWM整流器拓扑,输入侧接电感,输出侧接直流母线电容。这个结构的好处是:输入电流连续、功率因数可调、能量可以双向流动。具体来说,输入电感的作用是储能和滤波,让电流纹波控制在合理范围;直流母线电容稳定母线电压,给开关管提供稳定的直流源;四个MOS管组成两个桥臂,每个桥臂的上下管互补导通,通过SPWM调制让桥臂中点输出一个高频脉冲序列,其基波分量跟踪输入电压。
为什么不用半桥?半桥结构少两个管子,但输入电流只能单向流动,没法实现能量回馈,而且直流母线电压利用率低。全桥虽然多两个管子和驱动电路,但换来的性能提升完全值得。在电赛这种需要展示“能量回馈”功能的场合,全桥是标配。
2.2 SPWM调制策略的选择:单极性还是双极性
SPWM调制方式直接决定了输出波形质量和开关损耗。双极性SPWM是同一个桥臂的上下管互补导通,输出在两个电平之间切换,谐波含量大,但实现简单。单极性SPWM是每个桥臂独立控制,输出在三个电平之间切换,谐波含量小,但控制逻辑复杂一些。
我选的是单极性倍频SPWM。具体做法是:左桥臂用正弦波和三角波比较生成驱动信号,右桥臂用反相的正弦波和同一个三角波比较生成驱动信号。这样输出端的等效开关频率是载波频率的两倍,谐波集中在两倍载波频率附近,滤波器设计更容易。实测下来,同样20kHz载波频率,单极性倍频的输出电流纹波比双极性小一半左右。
这里有个细节要注意:单极性调制时,两个桥臂的驱动信号必须严格同步,否则会出现桥臂直通。STM32的高级定时器可以生成互补带死区的PWM,但两个桥臂之间还需要相位关系正确。我的做法是用一个定时器生成两路比较值,分别控制两个桥臂,通过更新比较值来实现正弦调制。
2.3 STM32的选型与资源分配
我用的STM32F103C8T6,也就是常说的“蓝板子”。有人会问,F103主频才72MHz,够用吗?实测下来,跑一个20kHz的电流环加SPWM生成,CPU占用率不到30%。关键是资源分配要合理。
定时器方面,TIM1是高级定时器,带互补输出和死区插入,用来生成四路PWM驱动全桥。TIM2用来做系统时基和任务调度。TIM3用来捕获输入电压的过零信号,做同步。ADC用规则通道扫描模式,配合DMA搬运,采样输入电压、输入电流、母线电压三个量。DMA通道要配置好,不然ADC数据会覆盖。
GPIO分配要提前规划:PWM输出占用PA8、PA9、PA10、PA11,这是TIM1的通道1到4。ADC输入用PA0到PA2。串口用PA9和PA10,但注意PA9和PA10和TIM1的通道2、3冲突,所以要么用重映射,要么换串口。我最后用的是USART2,PA2和PA3,避开冲突。
2.4 关键参数计算:电感、电容、开关频率怎么定
输入电感的值决定了电流纹波大小。电感越大,纹波越小,但体积和成本上去了,动态响应也变慢。计算公式是:L = (Vin_peak × D) / (ΔI × fsw)。Vin_peak是输入电压峰值,D是占空比,ΔI是允许的电流纹波,fsw是开关频率。
假设输入电压有效值24V,峰值就是34V。开关频率20kHz,允许纹波为额定电流的20%,额定电流5A,那ΔI就是1A。最恶劣工况是占空比0.5的时候,代入公式:L = (34 × 0.5) / (1 × 20000) = 850μH。实际取1mH,留点余量。
直流母线电容的选择要看母线电压纹波要求。母线电压纹波主要来自输入电流的二次谐波分量。计算公式是:C = Iin_peak / (2 × ω × ΔVbus)。Iin_peak是输入电流峰值,ω是电网角频率,ΔVbus是允许的母线电压纹波。假设输入电流峰值7A,电网频率50Hz,允许纹波5V,那C = 7 / (2 × 314 × 5) = 2229μF。实际取2200μF,再并一个薄膜电容滤高频。
开关频率的选择要权衡:频率高,电感和电容可以小,但开关损耗大,驱动电路要求高;频率低,损耗小,但滤波器体积大。20kHz是个甜点,刚好在音频范围之上,不会产生可听噪声,开关损耗也可以接受。
3. SPWM生成与STM32定时器配置的硬核细节
3.1 SPWM的本质:用面积等效原理拼出正弦波
SPWM的核心思想是“面积等效”——把正弦波分成N等份,每一份的面积用一个等幅不等宽的矩形脉冲来等效。脉冲的宽度按正弦规律变化,中心位置对齐。这样得到的脉冲序列经过低通滤波后,基波就是原来的正弦波。
具体实现时,用一条正弦调制波和一条高频三角载波比较,正弦波大于三角波时输出高电平,小于时输出低电平。三角波的频率就是开关频率,正弦波的频率就是输出基波频率。调制比M = 正弦波幅值 / 三角波幅值,决定了输出基波幅值。M最大为1,此时输出基波幅值为母线电压的一半(单极性)或母线电压(双极性)。
这里有个常见误区:很多人以为SPWM的直流电压利用率只有86.6%,其实那是SPWM在线性调制区的情况。86.6%的来源是:SPWM线性调制时,输出相电压基波峰值最大为Vdc/2,而方波逆变时相电压基波峰值为2Vdc/π,两者比值为(π/4)/√3 ≈ 0.866。这个数字在选母线电压时很重要,意味着如果你需要输出220V交流,母线电压至少要220×√2/0.866 ≈ 359V。
3.2 STM32定时器生成SPWM的三种方法
第一种是查表法。提前算好一个正弦周期的PWM比较值,存在数组里,定时器更新中断里依次读取数组更新比较寄存器。优点是计算量小,缺点是频率分辨率受表长限制,变频时需要重新算表。
第二种是实时计算法。在定时器中断里用sin函数实时计算比较值。优点是频率任意可调,缺点是sin计算耗时,F103没有浮点单元,用查表加插值更实际。
第三种是DMA搬运法。把正弦表存在内存里,配置DMA在定时器更新事件时自动把比较值搬到CCR寄存器。CPU完全不参与,可以腾出时间做其他事。我最后用的就是这种方法,20kHz开关频率,正弦表256点,DMA循环搬运,CPU占用率几乎为零。
具体配置:TIM1设置为中央对齐模式,ARR设为系统时钟除以开关频率再除以2。比如72MHz主频,20kHz开关频率,ARR = 72000000 / (2 × 20000) = 1800。预分频器设为0。CCR1到CCR4分别对应四个通道。DMA配置为循环模式,源地址是正弦表数组,目标地址是TIM1->CCR1,每次传输半字。注意DMA请求要选TIM1的更新事件。
3.3 死区时间计算与设置
死区时间是为了防止同一桥臂上下管直通。MOS管关断需要时间,如果上管还没完全关断下管就开了,母线直接短路,管子瞬间炸掉。死区时间要大于开关管的关断时间加上驱动电路的延迟。
我用的IRF540N,关断时间约100ns,驱动芯片IR2110的延迟约200ns,所以死区时间至少设300ns。STM32的死区寄存器BDTR可以设置死区时间,计算公式是:DTG[7:0] × Tdtg,Tdtg = 1/72MHz ≈ 13.9ns。300ns / 13.9ns ≈ 22,所以DTG设为22。实际我设了500ns,留足余量。
注意:死区时间不是越大越好。死区太大会导致输出波形畸变,因为死区期间输出电压由电流方向决定,会产生额外的谐波。一般取开关管关断时间的2到3倍就够了。
3.4 电流环设计:PI参数怎么调
电流环是让输入电流跟踪参考电流的关键。参考电流由输入电压乘以一个导纳值得到,导纳值决定了输入阻抗,也就决定了功率因数。如果导纳是纯实数,输入电流和输入电压同相,功率因数为1。
PI调节器的参数整定是个经验活。我的做法是:先只加比例环节,慢慢增大Kp直到电流波形开始振荡,然后取振荡临界值的60%作为最终Kp。然后加积分环节,Ki从很小的值开始加,观察稳态误差消除的速度,直到响应速度满足要求又不超调。
具体数值:Kp = 0.5,Ki = 0.01。这个值跟电感、采样周期都有关系,换硬件就要重新调。有个技巧是把PI输出限幅在母线电压的90%,防止过调制。
4. 完整电路图解析与关键元器件选型
4.1 主功率电路:从输入到母线的每一个环节
主功率电路分三部分:输入滤波、全桥变换、母线电容。
输入滤波是一个共模电感和一个X电容组成,滤除开关频率的共模噪声。共模电感用锰锌铁氧体磁环,双线并绕20匝,电感量约1mH。X电容用0.47μF的薄膜电容,耐压630V。
全桥变换的四个MOS管用IRF540N,耐压100V,电流33A,导通电阻44mΩ。为什么选它?因为耐压够用(母线电压最高60V),电流余量大,导通电阻小,发热少。驱动芯片用IR2110,自带自举电路,可以驱动高压侧MOS管。自举电容用1μF的陶瓷电容,自举二极管用UF4007。
母线电容用两个2200μF/100V的电解电容并联,再并一个10μF的薄膜电容。电解电容负责低频储能,薄膜电容负责高频滤波。母线电容的耐压要高于母线电压的1.5倍,100V耐压对应60V母线,余量足够。
4.2 采样电路:电压电流怎么采才准
输入电压采样用电阻分压。输入电压峰值34V,ADC参考电压3.3V,分压比取1:12,用1kΩ和11kΩ的电阻串联。分压后的电压经过一个电压跟随器缓冲,再送到ADC。电压跟随器用LM358,单电源供电,注意输入共模范围要包含0V。
输入电流采样用霍尔电流传感器,型号ACS712-20A。它的输出是电压信号,零点在2.5V,灵敏度100mV/A。电流为正时输出大于2.5V,为负时小于2.5V。这个信号直接送ADC,但要注意ACS712的输出范围是0到5V,而STM32的ADC参考是3.3V,所以需要分压或者用运放调整。我的做法是用一个同相放大器,把2.5V零点移到1.65V,增益设为0.66,这样±10A对应0到3.3V。
母线电压采样也用电阻分压,分压比1:20,用1kΩ和19kΩ串联。同样经过电压跟随器送ADC。
4.3 辅助电源:从母线取电给控制电路供电
控制电路需要3.3V和12V两路电源。3.3V给STM32和ADC,12V给驱动芯片和运放。从母线60V降到12V,用LM2596降压模块,效率高,发热小。再从12V降到5V,用7805线性稳压,给霍尔传感器和部分运放供电。最后从5V降到3.3V,用AMS1117-3.3,给STM32供电。
这里有个坑:LM2596的输入电压范围是4.5V到40V,母线60V超了。所以要么用更高耐压的降压芯片,要么从母线电容中间抽头取电。我的做法是用两个电容串联,中间点作为30V,再给LM2596供电。但要注意电容均压问题,每个电容并一个均压电阻。
4.4 驱动电路:IR2110的自举原理与布线要点
IR2110的高压侧驱动需要自举电容。原理是:当低侧MOS管导通时,自举电容通过自举二极管从12V电源充电;当高侧MOS管需要导通时,自举电容上的电压作为高侧驱动的电源。自举电容的容量要足够大,保证在一个开关周期内电压下降不超过1V。计算公式是:C ≥ Qg / ΔV,Qg是MOS管栅极电荷,IRF540N的Qg约70nC,ΔV取1V,所以C ≥ 70nF。实际取1μF,余量充足。
布线要点:自举电容和自举二极管要尽量靠近IR2110的VB和VS引脚,走线要短而粗。高侧和低侧的栅极驱动走线要分开,避免耦合。功率地和信号地要单点连接,防止开关噪声串入控制电路。
5. 软件架构与核心代码实现
5.1 主程序框架:前后台+中断
软件架构采用前后台系统。后台是主循环,处理串口通信、按键扫描、状态显示这些实时性要求不高的任务。前台是中断,包括定时器更新中断、ADC采样完成中断、串口接收中断。
主循环里做三件事:一是每10ms更新一次参考电流的幅值,根据设定的功率因数计算导纳;二是每100ms更新一次OLED显示;三是响应串口命令,修改工作模式。
定时器更新中断里做电流环计算。中断频率就是开关频率20kHz,每次中断读取ADC最新值,计算误差,跑PI,更新比较值。注意中断里不要做浮点运算,全部用定点数。我把电流值放大100倍存成int16,PI参数也放大100倍,最后结果右移7位还原。
5.2 ADC采样与DMA配置
ADC配置为规则通道扫描模式,扫描顺序是输入电压、输入电流、母线电压。触发源选定时器更新事件,这样采样时刻和PWM同步,避免采样到开关噪声。DMA配置为循环模式,每次传输3个半字到数组。
采样时刻很关键。如果采样时刻正好在开关管切换瞬间,会采到尖峰噪声。我的做法是在定时器计数到ARR值的时候触发ADC,这时候开关管已经稳定导通或关断,噪声最小。STM32的ADC可以配置为在定时器上升沿触发,配合中央对齐模式,采样点正好在PWM周期的中点。
5.3 电流环PI代码实现
typedef struct { int16_t Kp; int16_t Ki; int32_t integral; int16_t out_max; int16_t out_min; } PI_Controller; int16_t PI_Update(PI_Controller *pi, int16_t error) { int32_t p_term = (int32_t)pi->Kp * error; pi->integral += (int32_t)pi->Ki * error; if (pi->integral > pi->out_max) pi->integral = pi->out_max; if (pi->integral < pi->out_min) pi->integral = pi->out_min; int32_t output = p_term + pi->integral; if (output > pi->out_max) output = pi->out_max; if (output < pi->out_min) output = pi->out_min; return (int16_t)output; }这段代码里,Kp和Ki都是放大100倍的定点数。integral是积分累加器,做了限幅防止积分饱和。输出也做了限幅,防止过调制。实际运行时,error是参考电流减去实际电流,输出是调制波幅值。
5.4 SPWM正弦表生成与DMA搬运
正弦表用Excel或者Python生成,256个点,每个点是sin(2πi/256) × 1800 + 1800,范围0到3600,对应CCR值0到ARR。为什么加1800?因为CCR值不能为负,而且中央对齐模式下,CCR值决定占空比,1800对应50%占空比。
DMA配置为循环模式,源地址是正弦表数组,目标地址是TIM1->CCR1,传输长度256,每次传输半字。DMA请求选TIM1的更新事件。这样每个PWM周期,DMA自动把下一个正弦值搬到CCR1,同时CCR2、CCR3、CCR4也需要更新,但它们的值跟CCR1有相位关系。我的做法是用四个DMA通道,分别搬运四路PWM的比较值,正弦表有四个,相位分别是0、π、π、0。
6. 调试实录:从炸管到稳定运行的踩坑记录
6.1 第一次上电就炸管:死区时间不够
第一次上电,我信心满满地给了24V输入,结果一按启动按钮,啪的一声,两个MOS管炸了。用示波器看驱动波形,发现上下管的驱动信号有重叠,死区时间设了100ns,但IR2110的传输延迟就有200ns,实际死区是负的。
教训:死区时间必须大于驱动芯片延迟加上开关管关断时间。我后来把死区设到500ns,再也没炸过。另外,第一次上电一定要用低压,比如12V,并且串一个灯泡限流,炸管也不会太惨。
6.2 电流波形畸变:采样时刻不对
炸管修好后,电流波形出来了,但畸变严重,过零点附近有明显的平顶。用示波器同时看PWM和电流,发现电流在开关瞬间有尖峰,而ADC正好采到了尖峰。
解决:调整ADC触发时刻,从定时器更新事件改为定时器比较事件,让采样点落在PWM周期中点。具体做法是把ADC触发源设为TIM1的CC4事件,CC4的比较值设为ARR的一半。这样采样时刻正好在开关管稳定导通期间,噪声最小。
6.3 功率因数上不去:参考电流相位偏差
设定功率因数为1,但实测只有0.85。用示波器看输入电压和输入电流的相位,发现电流滞后电压约10度。原因是参考电流是由输入电压乘以导纳得到的,但输入电压采样有延迟,导致参考电流滞后。
解决:在参考电流计算里加一个相位超前补偿。具体做法是用一个二阶广义积分器(SOGI)生成输入电压的正交分量,然后用正交分量和原分量合成超前相位。SOGI的代码不复杂,两个积分器加交叉反馈,带宽设为电网频率的2倍。
6.4 母线电压泵升:能量回馈没做好
电子负载在吸收能量时,母线电压会泵升。如果能量回馈回路没做好,母线电压会一直升到电容炸掉。我的做法是在母线上并一个泄放电阻,当母线电压超过设定值时,用MOS管接通泄放电阻,把多余能量消耗掉。泄放电阻用100Ω/50W的铝壳电阻,MOS管用IRF540N。
但泄放电阻只是权宜之计,真正要做能量回馈,需要在母线侧接一个并网逆变器,把能量送回电网。这个复杂度就高了,电赛阶段一般不做要求,泄放电阻够用。
6.5 常见问题速查表
| 现象 | 可能原因 | 排查方法 | 解决方法 |
|---|---|---|---|
| 上电炸管 | 死区不够、驱动故障 | 示波器看驱动波形 | 增大死区、检查驱动 |
| 电流畸变 | 采样时刻不对 | 看采样点与PWM关系 | 调整ADC触发时刻 |
| 功率因数低 | 参考电流相位偏差 | 看电压电流相位差 | 加相位补偿 |
| 母线泵升 | 能量回馈不足 | 测母线电压 | 加泄放电路 |
| 波形振荡 | PI参数太激进 | 减小Kp观察 | 重新整定PI |
| 管子发热 | 开关损耗大 | 测管壳温度 | 降低开关频率、加散热片 |
7. 实测性能与优化方向
7.1 实测波形与效率数据
在24V输入、5A电流条件下,实测输入电流THD约3.5%,功率因数0.99,效率约92%。效率损失主要来自开关损耗和电感铜损。开关损耗跟开关频率成正比,如果把频率从20kHz降到10kHz,效率能到95%,但电感体积要翻倍。
电流跟踪误差在稳态下小于2%,动态响应时间约5ms。这个性能对于电赛和本科毕设来说完全够用。如果要进一步提升,可以从几个方面入手:一是用SiC或者GaN器件,开关损耗大幅降低,频率可以提到100kHz,滤波器体积缩小;二是用预测控制代替PI,动态响应更快;三是用锁相环精确同步电网相位,功率因数可以做到0.999。
7.2 从电赛到产品的差距
电赛作品和工业产品之间还有很大距离。工业产品要考虑EMC、安规、热设计、可靠性、成本。比如EMC,电赛作品一般不做传导辐射测试,但产品必须过CE认证。热设计方面,电赛作品加个风扇就行,产品要做热仿真,确保最恶劣工况下结温不超过限值。
但电赛这套东西作为学习平台是极好的。你把SPWM、电流环、功率变换这些核心概念都摸了一遍,再去看工业产品,会发现底层原理是相通的。我在调试过程中最大的收获不是把电路调通了,而是理解了“为什么采样时刻这么重要”“为什么死区不能太大”“为什么PI参数要折中”——这些经验在书本上是学不到的。
7.3 后续扩展思路
这套平台可以扩展成三相版本,做三相交流电子负载,用于测试三相电源。也可以加上并网功能,把能量回馈到电网,效率更高。还可以加上谐波发生功能,模拟非线性负载,测试电源的抗谐波能力。
软件方面,可以加上上位机界面,用LabVIEW或者Qt做,实时显示波形和参数。通信可以用串口或者CAN,CAN抗干扰能力更强,适合工业现场。
最后分享一个小技巧:调试电流环的时候,先用电阻负载代替被测电源,这样输入电压是稳定的直流,电流环更容易调。等电流环调好了,再换成交流输入,加上锁相环和相位补偿。这个顺序能帮你省下大量炸管的时间。