Buck-Boost变换器介绍之电压模式控制Boost
本文主要介绍Buck-Boost的电压模式控制的Boost原理和仿真。
仿真文件在开发板的资料中。
Boost工作模式的基本工作原理
Boost工作模式
Boost(升压)工作模式是DC-DC转换器的另一种基本拓扑结构,主要用于将输入电压转换为高于输入电压的输出电压。以下是其工作原理介绍:
- 电感充电阶段(Q4导通,Q2关断)
- Q4闭合(TC1高电平),Q2断开(TC2低电平)
- 输入电压VIN施加在电感上,电流线性增加
- 输出电容向负载供电
- 电流路径如图蓝色箭头所示
- 电感放电阶段(Q4关断,Q2导通)
- Q4断开(TC1低电平),Q2闭合(TC2高电平)
- 电感通过Q2续流释放能量,电流线性减小电感向负载释放能量
- 输出电容充电
- 电流路径如图绿色箭头所示
原则上此模式下会期望Q1长闭,但是Q1需要自举驱动,Q3就要导通一段时间维持自举电压。所以在Boost工作模式下,软件会设定Q1的占空比为90%,Q3的占空比为10%(占空比太小会自举失败,需要根据实际情况确定Q3占空比大小)。
电压模式控制
本节主要介绍如何使用STM32G474实现电压模式控制的Boost。
- 电路增益计算
使用DSP控制,我们需要考虑PWM模块、ADC模块和反馈电路的增益。
开发板的电压采用的是差分电路采样的,所以反馈电路的增益计算如下:
MCU的ADC采样电压范围是,12位ADC的输出范围是,所以ADC的增益如下:
假设输出电压为24V,则对应的ADC基准值计算如下:
MCU使用的是高分辨率的PWM,PWM的时钟为170MHz×32=5440MHz,Boost的开关频率为200kHz,所以PWM的周期寄存器为27200。PWM的增益计算如下:
Boost 数字控制的K如下:
计算的Python代码如下:
详情
import math
Vout = 24.00
PWM_Clock = 170.0e6*32
PWM_frequency = 200.0e3 # Switching frequency
PWM_Period = int(PWM_Clock/PWM_frequency)
Gpd = 3300/(56000+51)
Gadc = (math.pow(2,12)-1)/(3.3)
Gpwm = (1)/(PWM_Period)
K = 1/(Gpd*Gadc*Gpwm)
Vref = Vout*Gpd*Gadc
print("Gpd",Gpd)
print("Gadc",Gadc)
print("Vref",Vref)
print("PWM_Period",PWM_Period)
print("Gpwm",Gpwm)
print("K",K)
"""
Gpd 0.05887495316765089
Gadc 1240.909090909091
Vref 1753.403150702039
PWM_Period 27200
Gpwm 3.676470588235294e-05
K 372.30456654456657
"""
III型数字补偿器
连续系统III型补偿器有3个极点和2个零点,相位提升可以达到180°,传递函数如下。
利用双线性变换,将带入上式,可得到如下形式的离散传递函数。
由上式的离散传递函数可得III型补偿器(3P3Z)的差分方程公式如下。
其中:
注:极点和零点的单位都是rad/s
系数的推导视频:基于python - 学习电源系统模拟补偿器的数字化
使用Python推导A和B系数,代码如下。
详情
# import libraries
import numpy as np
import sympy as sp
# 符号定义
wp0,wp1,wp2,wz1,wz2,s,z,Ts = sp.symbols('wp0 wp1 wp2 wz1 wz2 s z Ts')
# 双线性变换
s = (2/Ts)*((1-z**(-1))/(1+z**(-1)))
# 连续系统III型补偿器
H3P3Z = (wp0/s)*(((1+s/wz1)*(1+s/wz2))/((1+s/wp1)*(1+s/wp2)))
# sympy.cancel()方法,将表达式化简为标准p/q形式,相对分子和分母幂次展开
H3P3Z_D = sp.cancel(H3P3Z,z)
# sympy.fraction()方法,提取表达式的分子和分母
numerator,denominator = sp.fraction(H3P3Z_D)
# sympy.collect()方法,配合coeff可将特定变量幂次的系数收集起来
Scaled = sp.collect(denominator,z).coeff(z,3)
# 先提取相应变量幂次的系数,接着借助sympy.factor()方法,找到数学表达式因式分解的因子。
B3 = sp.factor(sp.collect(numerator,z).coeff(z,0)/Scaled)
B2 = sp.factor(sp.collect(numerator,z).coeff(z,1)/Scaled)
B1 = sp.factor(sp.collect(numerator,z).coeff(z,2)/Scaled)
B0 = sp.factor(sp.collect(numerator,z).coeff(z,3)/Scaled)
A3 = sp.factor(-sp.collect(denominator,z).coeff(z,0)/Scaled)
A2 = sp.factor(-sp.collect(denominator,z).coeff(z,1)/Scaled)
A1 = sp.factor(-sp.collect(denominator,z).coeff(z,2)/Scaled)
#打印相关系数表达式
print("H3P3Z_D = ",H3P3Z_D)
print("\n")
print("B3 = ",B3)
print("B2 = ",B2)
print("B1 = ",B1)
print("B0 = ",B0)
print("A3 = ",A3)
print("A2 = ",A2)
print("A1 = ",A1)
# 计算实例化系数
wp0_res = 2*np.pi*100
wp1_res = 2*np.pi*10e3
wp2_res = 2*np.pi*100e3
wz1_res = 2*np.pi*100
wz2_res = 2*np.pi*10e3
Ts_res = 1.0/100e3
# 借助sympy.subs()方法,将数学表达式中的变量或表达式的所有实例替换为其他变量或表达式或值。
B3_res = B3.subs([(wp0,wp0_res),(wp1,wp1_res),(wp2,wp2_res),(wz1,wz1_res),(wz2,wz2_res),(Ts,Ts_res)])
B2_res = B2.subs([(wp0,wp0_res),(wp1,wp1_res),(wp2,wp2_res),(wz1,wz1_res),(wz2,wz2_res),(Ts,Ts_res)])
B1_res = B1.subs([(wp0,wp0_res),(wp1,wp1_res),(wp2,wp2_res),(wz1,wz1_res),(wz2,wz2_res),(Ts,Ts_res)])
B0_res = B0.subs([(wp0,wp0_res),(wp1,wp1_res),(wp2,wp2_res),(wz1,wz1_res),(wz2,wz2_res),(Ts,Ts_res)])
A3_res = A3.subs([(wp0,wp0_res),(wp1,wp1_res),(wp2,wp2_res),(wz1,wz1_res),(wz2,wz2_res),(Ts,Ts_res)])
A2_res = A2.subs([(wp0,wp0_res),(wp1,wp1_res),(wp2,wp2_res),(wz1,wz1_res),(wz2,wz2_res),(Ts,Ts_res)])
A1_res = A1.subs([(wp0,wp0_res),(wp1,wp1_res),(wp2,wp2_res),(wz1,wz1_res),(wz2,wz2_res),(Ts,Ts_res)])
print("\n")
#round,四舍五入保留几位小数
print("B3 = ",round(B3_res,6))
print("B2 = ",round(B2_res,6))
print("B1 = ",round(B1_res,6))
print("B0 = ",round(B0_res,6))
print("A3 = ",round(A3_res,6))
print("A2 = ",round(A2_res,6))
print("A1 = ",round(A1_res,6))
"""
H3P3Z_D = (Ts**3*wp0*wp1*wp2*wz1*wz2 - 2*Ts**2*wp0*wp1*wp2*wz1 - 2*Ts**2*wp0*wp1*wp2*wz2 + 4*Ts*wp0*wp1*wp2 + z**3*(Ts**3*wp0*wp1*wp2*wz1*wz2 + 2*Ts**2*wp0*wp1*wp2*wz1 + 2*Ts**2*wp0*wp1*wp2*wz2 + 4*Ts*wp0*wp1*wp2) + z**2*(3*Ts**3*wp0*wp1*wp2*wz1*wz2 + 2*Ts**2*wp0*wp1*wp2*wz1 + 2*Ts**2*wp0*wp1*wp2*wz2 - 4*Ts*wp0*wp1*wp2) + z*(3*Ts**3*wp0*wp1*wp2*wz1*wz2 - 2*Ts**2*wp0*wp1*wp2*wz1 - 2*Ts**2*wp0*wp1*wp2*wz2 - 4*Ts*wp0*wp1*wp2))/(-2*Ts**2*wp1*wp2*wz1*wz2 + 4*Ts*wp1*wz1*wz2 + 4*Ts*wp2*wz1*wz2 - 8*wz1*wz2 + z**3*(2*Ts**2*wp1*wp2*wz1*wz2 + 4*Ts*wp1*wz1*wz2 + 4*Ts*wp2*wz1*wz2 + 8*wz1*wz2) + z**2*(2*Ts**2*wp1*wp2*wz1*wz2 - 4*Ts*wp1*wz1*wz2 - 4*Ts*wp2*wz1*wz2 - 24*wz1*wz2) + z*(-2*Ts**2*wp1*wp2*wz1*wz2 - 4*Ts*wp1*wz1*wz2 - 4*Ts*wp2*wz1*wz2 + 24*wz1*wz2))
B3 = Ts*wp0*wp1*wp2*(Ts*wz1 - 2)*(Ts*wz2 - 2)/(2*wz1*wz2*(Ts*wp1 + 2)*(Ts*wp2 + 2))
B2 = Ts*wp0*wp1*wp2*(3*Ts**2*wz1*wz2 - 2*Ts*wz1 - 2*Ts*wz2 - 4)/(2*wz1*wz2*(Ts*wp1 + 2)*(Ts*wp2 + 2))
B1 = Ts*wp0*wp1*wp2*(3*Ts**2*wz1*wz2 + 2*Ts*wz1 + 2*Ts*wz2 - 4)/(2*wz1*wz2*(Ts*wp1 + 2)*(Ts*wp2 + 2))
B0 = Ts*wp0*wp1*wp2*(Ts*wz1 + 2)*(Ts*wz2 + 2)/(2*wz1*wz2*(Ts*wp1 + 2)*(Ts*wp2 + 2))
A3 = (Ts*wp1 - 2)*(Ts*wp2 - 2)/((Ts*wp1 + 2)*(Ts*wp2 + 2))
A2 = (Ts**2*wp1*wp2 + 2*Ts*wp1 + 2*Ts*wp2 - 12)/((Ts*wp1 + 2)*(Ts*wp2 + 2))
A1 = -(Ts**2*wp1*wp2 - 2*Ts*wp1 - 2*Ts*wp2 - 12)/((Ts*wp1 + 2)*(Ts*wp2 + 2))
B3 = 0.394631
B2 = -0.758651
B1 = -0.392352
B0 = 0.760930
A3 = -0.269864
A2 = 0.265072
A1 = 1.004792
"""
开环仿真
打开仿真文件 5_Boost_OpenLoop.plecs
Simulation -> Analysis Tools -> AC Sweep ->Start analysis,执行 AC Sweep,查看仿真的伯德图。
仿真的低频增益和LC双极点为:
环路设计
使用零极点对消方法,可以将III型补偿器的零极点放置于以下位置:
频率 | 说明 |
---|---|
开关频率或采样频率【单周期采样】 | |
补偿器的第1个极点,调节低频增益 | |
补偿器的第2个极点,对消ESR零点 | |
补偿器的第3个极点,对消右半平面零点 | |
补偿器的第1个零点,放置于LC双极点附近 | |
补偿器的第2个零点,放置于LC双极点附近 |
计算的Python代码如下:
详情
import math
import numpy as np
import matplotlib.pyplot as plt
import control as ctrl
Vin = 12.0
Vout = 15.00
IoutMax = 4.0
PWM_Clock = 170.0e6*32
PWM_frequency = 200.0e3 # Switching frequency
PhaseMargin = 50.0 # Phase margin
PWM_Period = int(PWM_Clock/PWM_frequency)
R = Vout/IoutMax
Gpd = 3300/(56000+51)
Gadc = (math.pow(2,12)-1)/(3.3)
Gpwm = (1)/(PWM_Period)
print("Gpd",Gpd)
print("ADC",Gadc)
print("Gpwm",Gpwm)
K = 1/(Gpd*Gadc*Gpwm)
Vref = Vout*Gpd*Gadc
# 电感参数
L = 22 * math.pow(10,-6) #uH
rL = 0.001
# 电容参数
C = 220 * math.pow(10,-6)*2.0 #uF
R_C = 53*math.pow(10,-3)/2.0 #mR
f_0 = 1/(2*np.pi*np.sqrt(L*C))*(Vin/Vout) # Double-Pole
f_ESR = 1/(2*np.pi*R_C*C)
#f_LC = 1/(2*np.pi*np.sqrt(L*C))
f_LC = f_0
f_RHP_zero = (R/(2*np.pi*L))*(Vin/Vout)*(Vin/Vout) # RHP-Zero
#
print("f_LC = ",f_LC)
print("f_esr = ",f_ESR)
print("f_RHP_zero = ",f_RHP_zero)
print("#define _40V_REF ("+str(int(40.0*Gpd*Gadc))+")")
print("#define _36V_REF ("+str(int(36.0*Gpd*Gadc))+")")
print("#define _24V_REF ("+str(int(24.0*Gpd*Gadc))+")")
print("#define _15V_REF ("+str(int(15.0*Gpd*Gadc))+")")
print("#define _5V_REF ("+str(int(5.0*Gpd*Gadc))+")")
print("#define _3V3_REF ("+str(int(3.3*Gpd*Gadc))+")")
print("#define _2V5_REF ("+str(int(2.5*Gpd*Gadc))+")")
# https://www.ti.com/lit/an/slva274a/slva274a.pdf?ts=1749389812554&ref_url=https%253A%252F%252Fwww.bing.com%252F
def Bode_plt(index,Input_p0,Input_p1,Input_p2,Input_z1,Input_z2):
fp0 = Input_p0 # Pole at the origin
fp1 = Input_p1 # First pole
fp2= Input_p2 # Second pole
fz1 = Input_z1 # First zero
fz2 = Input_z2 # Second zero
# 计算实例化系数
wp0 = 2*math.pi*fp0
wp1 = 2*math.pi*fp1
wp2 = 2*math.pi*fp2
wz1 = 2*math.pi*fz1
wz2 = 2*math.pi*fz2
Ts = 1.0/PWM_frequency
B3 = Ts*wp0*wp1*wp2*(Ts*wz1 - 2)*(Ts*wz2 - 2)/(2*wz1*wz2*(Ts*wp1 + 2)*(Ts*wp2 + 2))
B2 = Ts*wp0*wp1*wp2*(3*Ts**2*wz1*wz2 - 2*Ts*wz1 - 2*Ts*wz2 - 4)/(2*wz1*wz2*(Ts*wp1 + 2)*(Ts*wp2 + 2))
B1 = Ts*wp0*wp1*wp2*(3*Ts**2*wz1*wz2 + 2*Ts*wz1 + 2*Ts*wz2 - 4)/(2*wz1*wz2*(Ts*wp1 + 2)*(Ts*wp2 + 2))
B0 = Ts*wp0*wp1*wp2*(Ts*wz1 + 2)*(Ts*wz2 + 2)/(2*wz1*wz2*(Ts*wp1 + 2)*(Ts*wp2 + 2))
A3 = (Ts*wp1 - 2)*(Ts*wp2 - 2)/((Ts*wp1 + 2)*(Ts*wp2 + 2))
A2 = (Ts**2*wp1*wp2 + 2*Ts*wp1 + 2*Ts*wp2 - 12)/((Ts*wp1 + 2)*(Ts*wp2 + 2))
A1 = -(Ts**2*wp1*wp2 - 2*Ts*wp1 - 2*Ts*wp2 - 12)/((Ts*wp1 + 2)*(Ts*wp2 + 2))
print("/**")
print("fsw:",str(PWM_frequency),"Hz")
print("Period:",str(PWM_Period))
print("Gpd:",str(Gpd))
print("Gadc:",str(Gadc))
print("Gpwm:",str(Gpwm))
print("fp0:",str(fp0),"Hz")
print("fp1:",str(fp1),"Hz")
print("fp2:",str(fp2),"Hz")
print("fz1:",str(fz1),"Hz")
print("fz2:",str(fz2),"Hz")
print("*/")
print("#define BOOST_LOOP_REF ("+str(int(Vref))+")")
print("#define BOOST_LOOP_K ("+str(K)+")")
print("#define BOOST_LOOP_B0 ("+str(B0)+")")
print("#define BOOST_LOOP_B1 ("+str(B1)+")")
print("#define BOOST_LOOP_B2 ("+str(B2)+")")
print("#define BOOST_LOOP_B3 ("+str(B3)+")")
print("#define BOOST_LOOP_A1 ("+str(A1)+")")
print("#define BOOST_LOOP_A2 ("+str(A2)+")")
print("#define BOOST_LOOP_A3 ("+str(A3)+")")
############ discrete z transfer function. ############
z = ctrl.tf('z')
f = np.logspace(1, 4, 201)
w = 2 * np.pi * f
Hpd = ((B3*z**(-3))+(B2*z**(-2))+(B1*z**(-1)) +B0 )/((-A3*z**(-3))-(A2*z**(-2))-(A1*z**(-1))+1)
Hpd.dt = Ts
mag,phase,omega=ctrl.bode_plot(Hpd,w,dB=True,Hz=True,deg=True,plot=True, grid=True, label='Hpd_'+str(index))
fp0 = 100 # 调节低频增益
fp1 = f_ESR
#fp1 = PWM_frequency
fp2 = f_RHP_zero
fz1 = (f_LC * 0.9) # 调节相位裕度
fz2 = (f_LC * 1.1) # 调节相位裕度
Bode_plt(0,fp0,fp1,fp2,fz1,fz2)
"""
Gpd 0.05887495316765089
ADC 1240.909090909091
Gpwm 3.676470588235294e-05
f_LC = 1294.1137153039585
f_esr = 13649.65206620029
f_RHP_zero = 17362.357428206768
#define _40V_REF (2922)
#define _36V_REF (2630)
#define _24V_REF (1753)
#define _15V_REF (1095)
#define _5V_REF (365)
#define _3V3_REF (241)
#define _2V5_REF (182)
/**
fsw: 200000.0 Hz
Period: 27200
Gpd: 0.05887495316765089
Gadc: 1240.909090909091
Gpwm: 3.676470588235294e-05
fp0: 100 Hz
fp1: 13649.65206620029 Hz
fp2: 17362.357428206768 Hz
fz1: 1164.7023437735627 Hz
fz2: 1423.5250868343546 Hz
*/
#define BOOST_LOOP_REF (1095)
#define BOOST_LOOP_K (372.30456654456657)
#define BOOST_LOOP_B0 (0.15123343465259712)
#define BOOST_LOOP_B1 (-0.13918375345732495)
#define BOOST_LOOP_B2 (-0.1509957233440628)
#define BOOST_LOOP_B3 (0.13942146476585926)
#define BOOST_LOOP_A1 (2.218321226795803)
#define BOOST_LOOP_A2 (-1.5879741727199352)
#define BOOST_LOOP_A3 (0.3696529459241324)
"""
使用Python代码计算出的补偿器的A和B系数如下(对应开发板中的环路参数代码):
/**
fsw: 200000.0 Hz
Period: 27200
Gpd: 0.05887495316765089
Gadc: 1240.909090909091
Gpwm: 3.676470588235294e-05
fp0: 100 Hz
fp1: 13649.65206620029 Hz
fp2: 17362.357428206768 Hz
fz1: 1164.7023437735627 Hz
fz2: 1423.5250868343546 Hz
*/
#define BOOST_LOOP_REF (1095)
#define BOOST_LOOP_K (372.30456654456657)
#define BOOST_LOOP_B0 (0.15123343465259712)
#define BOOST_LOOP_B1 (-0.13918375345732495)
#define BOOST_LOOP_B2 (-0.1509957233440628)
#define BOOST_LOOP_B3 (0.13942146476585926)
#define BOOST_LOOP_A1 (2.218321226795803)
#define BOOST_LOOP_A2 (-1.5879741727199352)
#define BOOST_LOOP_A3 (0.3696529459241324)
闭环仿真
打开仿真文件 7_Boost_CloseLoop_3P3Z _C Script.plecs
Simulation ->Start,执行仿真,然后双击Scope查看仿真的波形。
其中环路的代码在仿真文件的 C-Script 模块中。
实际电路环路测量
测试条件 | |
---|---|
输入电压 | 12V |
输出电压 | 24V |
输出负载 | 33Ω |
环路分析仪器 | 鼎阳SDS814X HD + SAG1021I |
按键说明 | 单击按键1 开机,单机按键2关机 |
我们可以使用环路分析仪器在R37两端(LoopA和LoopB)注入信号,测量Boost电路的环路。
测量的结果如下:
测量结果 | |
---|---|
穿越频率 | 1.3 kHz |
相位裕量 | 63.2° |
幅值裕量 | 16.28dB |
参考文档
[1] Buck-boost converter using the STM32F334 Discovery kit
[2] Designing Stable Digital Power Supplies
[3] Voltage Mode Boost Converter Small Signal Control Loop Analysis Using the TPS61030[7] Voltage Mode Boost Converter Small Signal Control Loop Analysis Using the TPS61030
提示
本人在此发布博文(包括但不限于汉字、拼音、阿拉伯字母 、图片、影像,以及前述之各种任意组合等等)均为随意敲击键盘所出,用于检验本人电脑键盘录入、屏幕显示的机械、光电性能,并不代表本人观点。如需要详查请直接与键盘发明者及生产厂商法人代表联系。