【电源入门】菜鸟读开关电源控制环路设计:第 4 章

引言

        线性电源或者开关电源补偿器的设计并不直接遵循经典 PID 理念,而是研究 PID 中各个环节作用,将其带入传函零极点视角,从而从零极点视角通过设定合理零极点来近似 PID 对系统的控制效果,此种方式较之经典 PID 算法响应更好

4.1 PID 补偿

        经典 PID 理论中

        比例项: kp 较大则响应速度较快,但存在超调的风险,若 kp 较小表现相反 

        积分项:可以消除设定值与输出值之间的静态误差,但对于瞬态过程,会减缓响应速度并增大过冲,由于误差信号的积累,积分模块(电容所带电荷量)可能饱和,因此在必要的时候增加抗饱和措施(并联电阻等)

        微分项:在静态中这一项对输出没有影响,动态中此环节有助于稳定输出并提高响应速度

4.1.1 拉普拉斯域的 PID 表达式

        首先研究并行 PID 的公式

        

        对于微分项,微分相当于为系统增加零点,在 w 到达高频的时候输出增益为无穷,于是需要在零点频率后一定位置增加一个极点,以免增益被无限放大

4.1.2 PID 补偿器的实际实现 

        对上式进行拉普拉斯变换,可得带高频极点的并行 PID 在复频域的表示式,包含 2 零点以及一个极点与原点极点

         易得零极点与 PID 系数表达式之间的关系如下

        其中 N 的式子与书中不符,应该是书上的写错了 

        接着计算零极点的表达式

        计算结果如下 

        如下图绘制电路仿真图  

         首先计算电路参数公式如下

        计算结果如下 

        仿真图如下 

        仿真结果的伯德图曲线完全吻合

        证实了两个不同方式构造的 PID 补偿电路性质相同,即使用零极点配置电路来代替经典 PID 是可行的 

 4.1.3 PI 补偿器的实际实现

        PI 补偿器即为去掉微分环节的 PID 补偿器,其零极点与 PI 系数之间的关系十分好找

         得出关系如下

        绘制仿真图

仿真结果如下 

 4.1.4 PID 在 Buck 变换器中的应用

         将 Buck 变换器的输入输出简化为以下形式,输出电压为输入电压乘以占空比

        同第二章 Boost 电路,此处需要推导从输入到输出的小信号传函 

        由平均以及小信号模型计算后的结果如下 

        仿真结果如下 

         开关电路可以实现电压的可调输出,输入量取决于 U(s) 基准电压以及各个环节的扰动 ,输出量为 Y(s),欲得到传递函数 T(s) 则需要得到 G(s) 和 H(s) 的表达式

        已知 G(s) 为单极点 + 原点极点 + 双零点传函,H(s) 为 双极点、单零点传函,则其直接级联将得到一个三级点 + 原点极点 + 三零点的 4 阶复杂传函,将来自 G(s) 的双零点和 H(s) 的双极点,可简化传函为原点极点 + 单极点 + 单零点的二阶传函

         进而得到闭环传函

        根据限制关系可算出 G(s) 参数的表达式 

         带入数据计算传函如下

        若要消除控制系统的零点,需要在一开始计算补偿器之前就将其消除,即需要重新计算不含此零点的 PID 参数等表达式如下

        计算结果如下 

        matlab 中输入下段代码用以验证级联效果

close all;  clc;    clear;

Gs = tf([6.5073359999999991777e34,1.1831519999999996657e38,3.9438399999999994541e42],[5.0e33,3.2432431999999994298e38,0]);

Hs = tf([2.9166666666666680411e19,1.8939393939393945675e24],[6.25e15,1.1363636363636365892e19,3.7878787878787891349e23]);

Ts = tf([3.9438399999999994243e24],[1.0e15,1.2559999999999999099e20,0]);

Tc = tf([1.9719199999999997121e41],[5.0e31,6.2799999999999995496e36,1.9719199999999997121e41]);

sys = { Gs, Hs, Ts, Tc };   freq = logspace(1,6,5000);  dB_range = {[-20 60],[-60 40],[-40 60],[-30 0]};

figure_handle = {}; dleft = {10,580,10,580}; dbottom = {560,560,50,50};

opts = bodeoptions; opts.FreqUnits = 'Hz';


for cycle = 1:4
    figure_handle{end+1} = figure;  movegui(figure_handle{cycle},[dleft{cycle} dbottom{cycle}]);
    bodeplot(sys{cycle}, freq, opts);  grid on;
    set(findall(figure_handle{end}, 'Type', 'axes'), 'YLim', dB_range{cycle});    ylim([-180 180]); xlim([10^1 10^5]);
end

        得到如下图像 

        值得注意的是,RLC 或类似振荡系统的传函,其相位穿过 90° 的时候正好是幅度的谐振尖峰 

 4.1.5 具有 PID 补偿的 Buck 变换器瞬态响应

        下图为带有补偿器的闭环系统的启动图像,基本没有静态误差

        带入基于滤波 PID 的仿真电路验证,首先用 mathcad 计算电路参数

        用 PSIM 仿真,在 0.001 秒的时候加输入电压阶跃,在 0.010 秒加输出电流阶跃

        得到波形如下,验证了在实际电路中滤波 PID 不能满足输出稳定的要求,原因是其在阻抗谐振处增益过小,不能够抑制增益带来的剧烈变化,其表现几乎和 RLC 电路相同

4.1.6 设定值固定:调节器

         如上是环路可能受到的扰动,图中的两项扰动分别是输入电压与输出电流(输出负载),这两项对于环路设计都至关重要,在电源工作的时候输入电压通常不会改变,输入电压阶跃的常见于电源启动或关闭,而电源开启的时候就需要时刻监控负载保证负载变化的时候能够迅速回到稳态值

4.1.7 具有谐振峰的输出阻抗响应曲线

        引用之前计算过的数据

        代码如下 

% /* USER CODE BEGIN SysInit */

DisplayInputs = false;
freq = logspace(2, 6, 5000);
time = linspace(0, 2e-4, 5000);
bodelim = { 1, [-42 8], [-20 180]};

strs{1} = '8.5116731517509763981e36*s.^2+5.640549463506663602e41*s.+7.3694139841999794578e44/1.25e38*s.^2+5.0123806154934573547e41*s.+7.6641905435679793412e45';
strs{2} = '3.4046692607003905593e47*s.^4+6.5324843768423556764e52*s.^3+2.8632897064025475082e57*s.^2+3.702393585662069414e60*s./5.0e48*s.^4+6.4804952246197378437e53*s.^3+2.2543987642966629089e58*s.^2+1.1757700195731638132e62*s.+1.2090536493338054093e66';
strs{3} = '0';
strs{4} = '0';

nums{1} = {1};
dens{1} = {1};
nums{2} = {1};
dens{2} = {1};
nums{3} = {1};
dens{3} = {1};
nums{4} = {1};
dens{4} = {1};

step = {0, 5, 0, 0};
sinu = {1, 1000, 0};

% /* USER CODE END SysInit */

% /* USER CODE BEGIN */

% figures deploy
close all;  clc;    system = {};    step_response = {}; sinu_input = {};

% figures deploy
figure_handle = {};   for cycle = 1:2 figure_handle{end+1} = figure;    end; dleft = {100,680}; dbottom = {400,400};
for cycle = 1:2    movegui(figure_handle{cycle},[dleft{cycle} dbottom{cycle}]); end

% transfer functions
for cycle = 1:4 if(strcmp(strs{cycle},'0'))
for cyclea = 1:numel(nums{cycle})-1  nums{cycle}{end} = conv(nums{cycle}{end},nums{cycle}{cyclea});   end
for cyclea = 1:numel(dens{cycle})-1  dens{cycle}{end} = conv(dens{cycle}{end},dens{cycle}{cyclea});   end
else    if(strcmp(strs,'1')) strs = '1/1'; end;	syms s;
strs{cycle} = strsplit(strrep(strs{cycle},'s.','s'),'/');
nums{cycle}{end} = double(coeffs(eval(['s*(' strs{cycle}{1} ')']),'All'));
dens{cycle}{end} = double(coeffs(eval(['s*(' strs{cycle}{2} ')']),'All'));
nums{cycle}{end} = nums{cycle}{end}(1:end-1); dens{cycle}{end} = dens{cycle}{end}(1:end-1); end
system{cycle} = tf(nums{cycle}{end},dens{cycle}{end}); end

% input signals
step_input = step{1}.*ones(size(time));  step{4} = max(step{4}, time(2)-time(1));    step_input(time > step{3} + step{4}) = step{2};
step_input(time>=step{3}&time<=step{3}+step{4}) = step{1}+(step{2}-step{1})/step{4}.*(time(time>=step{3}&time<=step{3}+step{4})-step{3});
for cycle = 1:4	step_response{cycle} = lsim(system{cycle},step_input,time,step{1});	end
for cycle = 1:4	sinu_input{cycle} = sin(sinu{2}.*2.*pi.*time+sinu{3}).*sinu{1};	end

% waveforms plot
figure(figure_handle{1});   hold on;
for cycle = 1:4    if ~isequal(system{cycle},tf(1,1))    margin(system{cycle});    end;  end
title('Bode Diagram');    grid on;
if(bodelim{1})  set(findall(figure_handle{1},'Type','axes'),'YLim',bodelim{2});	ylim(bodelim{3});   end;    xlim([freq(1) freq(end)]);
figure(figure_handle{2});   subplot(2,1,1); hold on;    
for cycle = 1:4 if ~isequal(system{cycle},tf(1,1))    plot(time, step_response{cycle});    end;  end
title('Step Response');   xlabel('time (s)');   ylabel('amplitude');
xlim([min(time) max(time)]);    if(DisplayInputs == true)   plot(time, step_input); end;    grid on;
figure(figure_handle{2});   subplot(2,1,2); hold on;
for cycle = 1:4 if ~isequal(system{cycle},tf(1,1)) plot(time, lsim(system{cycle},sinu_input{cycle},time,sin(sinu{3}).*sinu{1})); end; end
xlim([min(time) max(time)]);    title('Sinusoidal Response');   xlabel('time (s)');   ylabel('amplitude');
if(DisplayInputs == true)   plot(time, sinu_input{cycle}); end;    grid on;

% /* USER CODE END */

        曲线如下(需要将单位转为 Hz) 

        此处引入新概念群延时,可见 附录 4B 中公式, 即根据相位求群延时进而求品质因数,公式如下

        通过如下更新后的代码一次性获取传递函数的包括群延时在内的更多信息

% /* USER CODE BEGIN SysInit */

ComputeCloseLoop = true;
DisplayInputs = false;

freq = logspace(2, 6, 5000);
time = linspace(0, 2e-4, 5000);

bodelim = { 0, [-200 200], [-360 360]};

gain_ol = 0;
dlay_ol = 0;

strs_tf = '2.9166666666666680411e19*s.+1.8939393939393945675e24/6.25e15*s.^2+1.1363636363636365892e19*s.+3.7878787878787891349e23';
nums_tf = {1};
dens_tf = {1};

strs_fn = '0';
nums_fn = {1};
dens_fn = {1};

step = {0, 5, 0, 0};
sinu = {1, 1000, 0};

% /* USER CODE END SysInit */

% /* USER CODE BEGIN */

close all;  clc;

% figures deploy
figure_handle = {};   for cycle = 1:6 figure_handle{end+1} = figure;    end
dleft = {10,580,1150,10,580,1150}; dbottom = {560,560,560,50,50,50};
for cycle = 1:6    movegui(figure_handle{cycle},[dleft{cycle} dbottom{cycle}]); end

% transfer functions
[dlay_num,dlay_den] = pade(dlay_ol,1);  sys_ol = db2mag(gain_ol).*tf(dlay_num,dlay_den);
if(strcmp(strs_tf,'0'))
for cycle = 1:numel(nums_tf)-1  nums_tf{end} = conv(nums_tf{end},nums_tf{cycle});   end
for cycle = 1:numel(dens_tf)-1  dens_tf{end} = conv(dens_tf{end},dens_tf{cycle});   end
else    if(strcmp(strs_tf,'1')) strs_tf = '1/1'; end;	syms s;
strs_tf = strsplit(strrep(strs_tf,'s.','s'),'/');
nums_tf{end} = double(coeffs(eval(['s*(' strs_tf{1} ')']),'All'));
dens_tf{end} = double(coeffs(eval(['s*(' strs_tf{2} ')']),'All'));
nums_tf{end} = nums_tf{end}(1:end-1); dens_tf{end} = dens_tf{end}(1:end-1); end
if(strcmp(strs_fn,'0'))
for cycle = 1:numel(nums_fn)-1  nums_fn{end} = conv(nums_fn{end},nums_fn{cycle});   end
for cycle = 1:numel(dens_fn)-1  dens_fn{end} = conv(dens_fn{end},dens_fn{cycle});   end
else    if(strcmp(strs_fn,'1')) strs_fn = '1/1'; end;	syms s;
strs_fn = strsplit(strrep(strs_fn,'s.','s'),'/');
nums_fn{end} = double(coeffs(eval(['s*(' strs_fn{1} ')']),'All'));
dens_fn{end} = double(coeffs(eval(['s*(' strs_fn{2} ')']),'All'));
nums_fn{end} = nums_fn{end}(1:end-1); dens_fn{end} = dens_fn{end}(1:end-1); end
sys_ol = sys_ol.*tf(nums_tf{end},dens_tf{end}); sys_cl = feedback(sys_ol,tf(nums_fn{end},dens_fn{end}));
if(ComputeCloseLoop == false)  system = sys_ol; else   system = sys_cl; end

% input signals
step_input = step{1}.*ones(size(time));  step{4} = max(step{4}, time(2)-time(1));    step_input(time > step{3} + step{4}) = step{2};
step_input(time>=step{3}&time<=step{3}+step{4}) = step{1}+(step{2}-step{1})/step{4}.*(time(time>=step{3}&time<=step{3}+step{4})-step{3});
step_response = lsim(system,step_input,time,step{1});   sinu_input = sin(sinu{2}.*2.*pi.*time+sinu{3}).*sinu{1};

% waveforms plot
figure(figure_handle{1});   hold on;    pzmap(system);  title('Zerp-Ploe Map');   grid on;
figure(figure_handle{2});   hold on;    margin(system); title('Bode Diagram');    grid on;
if(bodelim{1})  set(findall(figure_handle{2},'Type','axes'),'YLim',bodelim{2});	ylim(bodelim{3});   end;    xlim([freq(1) freq(end)]);
figure(figure_handle{3});   subplot(2,1,1); hold on;    title('Step Response');   xlabel('time (s)');   ylabel('amplitude');
plot(time, step_response);  xlim([min(time) max(time)]);    if(DisplayInputs == true)   plot(time, step_input); end;    grid on;
figure(figure_handle{3});   subplot(2,1,2); hold on;    title('Sinusoidal Response');   xlabel('time (s)');   ylabel('amplitude');
plot(time, lsim(system,sinu_input,time,sin(sinu{3}).*sinu{1}));  xlim([min(time) max(time)]);
if(DisplayInputs == true)   plot(time, sinu_input); end;    grid on;
figure(figure_handle{4});   hold on;    setoptions(nyquistplot(system),'ShowFullContour','off');   grid on;
figure(figure_handle{5});   subplot(2,1,1); [mag,phase] = bode(system,freq);    semilogx(freq(1:end-1), squeeze(diff(phase)));
ylabel('Group delay (s)');  title('Group Delay Curve'); grid on;
figure(figure_handle{5});   subplot(2,1,2); semilogx(freq, squeeze(phase));
xlabel('Frequency (rad/s)');    ylabel('Phase (degrees)');  grid on;

% informations display
gcf = figure(figure_handle{6}); diary('text.txt'); fprintf('informations display\n'); display(system);
[numer,denom] = tfdata(system,'v'); [zero,pole,gain] = tf2zp(numer,denom);	[gm,pm,wcg,wcp] = margin(system); [wn, zeta] = damp(system);
fprintf('\nGain:\t%g',gain);   fprintf('\nZero:');  fprintf('\t%g', zero); fprintf('\nPole:');  fprintf('\t%g', pole);
fprintf('\n\nwn:\t\t%g',wn(end));	fprintf('\nZeta:\t%g',zeta(end));    fprintf('\nQ:\t\t%g',1./(2 * zeta(end)));
fprintf('\n\nGm:\t\t%.2f dB',gm);  fprintf('\nPm:\t\t%.2f deg',pm); fprintf('\nWcg:\t%g Hz',wcg/2/pi);  fprintf('\nWcp:\t%g Hz',wcp/2/pi);
fprintf('\n                                                                                                       By Guillxuame');
text = uicontrol('Style', 'text', 'Position', [30 15 gcf.Position(3)-20 gcf.Position(4)-30], 'HorizontalAlignment', 'left', 'FontSize', 10);
diary off;  file = fopen('text.txt','r');   set(text, 'String', fscanf(file,'%c'));  fclose(file); delete('text.txt');

% /* USER CODE END */

计算延时裕度如下 

4.2 基于零极点配置补偿变换器 

        针对输出阻抗所造成的振荡,拉高阻抗尖峰所在的频率值的增益可以有效改善响应

4.2.1 简易参数设计步骤

        1,首先求解出传递函数 H(s) 的参数:穿越频率、相位裕度等

        2,设计补偿器,一般为原点极点与其他零极点对的组合,再带入电路中实现 

        3,分析闭环系统,尤其是其阶跃响应

4.2.2 被控对象传递函数

        根据具体电路的拓扑结构,利用平均模型以及小信号模型求解其传递函数

4.2.3 积分环节消除静态误差

        推导理想运放构成的积分器传函可以得到表示积分环节的简易积分器如下

        其幅频和相频响应是一条直线,此时其开环增益以及增益带宽都非常高 

        但是运放的开环增益与单一增益带宽都不能达到无穷,则实际的运放曲线会有变形,这种影响将主要体现在相频上,如下开环增益有限将提高极低频或说是直流的相位 

         GBW 带宽增益积或者 FU 均一增益带宽将影响高频部分的幅值与相位,幅值和相位均会变小

        对非理想运放的分析可以从本书 附录 4D 开环增益和原点处极点对基于运算放大器的传递函数的影响 中获取 

4.2.4 积分调节器:1 型补偿器

        在 PSIM 中绘制以下图像,此电路的自适应偏置电路

 4.2.5 穿越频率处相位补偿

        由于原点处极点将带来 90° 相位滞后,使用 I 型补偿器将改变系统的相位裕度,系统级联的伯德图表现为直接线性相加

4.2.6 配置极点和零点进行相位补偿 

        在补偿器中设计零点在前用以提升相位,再采用极点在后抵消零点对系统幅值和相位的影响,调整两者的位置可以获取到期望的相位提升值

        其伯德图如下

        设置不同极点得到以下伯德图

        计算相位提升最大值的位置为集合平均数所在

 4.2.7 用一对零/极点实现 90° 相位提升

         将上式带入具体数值

        可根据公式获取想要的相位提升

        固定某点得到相位提升

 4.2.8 用一对零/极点调整中频段增益:2 型补偿器

        采用如下形式的运放电路可以得到符合原点极点 + 一对零极点形式的传函

 

        得到伯德图 

4.2.9 2 型补偿器的设计实例  

         数值计算

         伯德图表现

4.2.10 使用双重零/极点对实现 180° 的相位提升 

         双重零极点实际上只是两个一对零极点的简单叠加,理论推导上并无不同,可以设计两个基于一对零极点建立的补偿器直接代替

4.2.11 使用双重零/极点调整中频段增益:3 型补偿器

        3 型补偿器对应原点极点 + 双零/极点对传函,基于 OPA 的电路图如下

        伯德图见下

4.2.12 3 型补偿器的设计实例 

         计算传函

        验证伯德图

 4.2.13 选择合适的补偿器类型

         无需死抠补偿器的类型,在使用补偿器的时候构造合适的传函以构成期望的闭环响应即可

4.2.14 用于 Buck 的 3 型补偿器

        经典补偿方法:首先选择穿越频率 fc ,保证在谐振频率 f0 处的增益足够;在谐振频率处放一对分散零点提升轻载稳定性;放置极点以抵消 ESR 零点,若零点在高频部分则此极点放置只需使开关频率具有足够低增益的地方;放置第二个极点到高频处,通常在开关频率一半处

        计算的传函如下 

        补偿器伯德图(未考虑反向接法)

        闭环伯德图(未考虑反向接法)

         闭环输出阻抗伯德图如下,仍然有小尖峰,但比 PID 补偿方法波形表现明显更好

        仿真电路参数计算过程如下

        PSIM 仿真图

        电流阶跃响应图如下

        此处还缺 DCM 部分以及分离零点对暂态响应的影响部分

4.3 输出阻抗整形 

        将输出阻抗整形为阻性会使系统的超调变小

4.3.1 使输出阻抗呈阻性

        如下图计算,书中的两个零点值需要反过来

        得到伯德图如下

         计算低频处的近似曲线,其中 a 的值理论为 0

        近似曲线的伯德图如下

        计算基于 OPA 的补偿器参数如下

        仿真电路如下

         伯德图如下

        闭环输出阻抗计算

        伯德图如下

     系统开环传函如下

        电路仿真未做

4.4 结论

        研究电路的传函时需要厘清输入信号的形式,如电流阶跃则需要乘以输出阻抗变为电压量才能作为传函的输入参数,于是电路的输出阻抗也不能忽视。为了补偿输出阻抗带来的振荡,需要在电路的谐振处供给足够的增益,此时经典 PID 理论便满足不了补偿需求,应当使用基于二阶传函的电压控制补偿

附录 4A 利用快速分析技术得到 Buck 电路的输出阻抗

        计算电路阻抗建议使用向量模型,此方法最为简单且快速,计算方式如下

附录 4B 根据伯德图的群延时计算品质因数

        根据传递函数可绘制伯德图,伯德图中的相频响应的导数即为系统在此处频率的延时,而相位中的又与品质因数密切相关,计算过程如下

        至此,之后的二阶系统(注意此公式只适用于二阶系统)都可以通过伯德图上穿越频率处相位的导数来计算 Q 值 

附录 4C 利用仿真或者数学求解器来获得相位

        此部分内容为十分基础的复变函数内容,在此不多赘述。对电路建好模之后,可在 matlab 中可使用 margin 、 bode 、 bodeplot 等函数求解伯德图,使用 bode 函数也能获取相位信息;在 mathcad 中可使用 arg 、atan 、 atan2 等函数获取相位表达式或特定值

附录 4D 开环增益和原点处极点对基于运算放大器的传递函数的影响

        计算带开环增益及低频极点的运放传函如下

        带入积分器语境下并计算极点

        计算带特殊零点的表达形式 

        不使用文中简化操作,直接计算数值 

        带入 matlab 绘制伯德图

        multisim 中表示 

  • 31
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值