用STM32做数字开关电源
novakon2015/11/22电气电工 IP:江西
用数字方法实现反馈环路好处很多,比如可以通过串口控制,可以实现自定义的伏安特性曲线……简而言之,可以在不修改硬件的情况下改变电源的特性。
为了降低难度,我选择从最简单的Buck拓扑开始。


20151121_215436.jpg


电压与电流信号由运放送往MCU内置ADC,采集后经过PID算法生成一定占空比的PWM信号,通过场效应管驱动器驱动输出场效应管。


因为这个电源的功率比较大,同时可能经常要工作在恒流模式,所以我没有使用电压模式控制,而是选择用电流模式控制,也就是通过调节占空比控制电感电流,通过调节电流实现控制输出电压,而不是通过调节占空比直接试图控制输出电压。这样我们就可以使用很大的输出电容,可以使用低ESR的输出电容,而不必费尽心思设计补偿网络。


这里电感电流的采集非常关键,直接影响恒流精度。因为工作在连续电流模式的电感的电流波形是有直流偏置的三角波,我用一个带有直流偏置的三角波电压源模拟采样电阻上的压降信号。设采样到纹波信号0.02V,放大21倍,开关频率为50kHz;


QQ截图20151121223344.jpg


QQ截图20151121223550.jpg


红线代表原始的电流信号。要想直接采集一个周期内的平均电流(而不使用低通滤波器),就要在电流波形上升段或者下降段的中点采样。如果采样的时机不对,采集到的电流就有偏差:比如采样时刻比较靠近波形最大值的时刻,那么采集到的电流就比平均电流偏大。而这个偏大的部分,不总是线性或者时间稳定的。


仿真的结果并不太好。因为LM358的带宽较低,同相放大21倍之后的电流波形比原波形滞后了大约45度。由于这个滞后,如果我们在三角波上升段或者下降段中点采样,采集到的并不是平均电流。怎么办呢?一个办法是,在三角波上升沿和下降沿的中点各采样一次,然后求平均。这是个好办法,但是要先看看在STM32上面怎么实现。


QQ截图20151122010019.jpg


上图:ADC可以由其他定时器产生的TRGx信号触发开始采集,支持在信号的上升沿和/或下降沿触发。
下图:对应的框图。


QQ截图20151121223749.jpg


下图:TIM1定时器可以将输出比较信号(本例中的PWM信号),或者定时器的计数器更新/换向事件(UPDATE事件)信号,用于产生TRGO信号。


QQ截图20151122005851.jpg   

下图:在中心对称模式(双向计数产生对称三角波,进一步通过寄存器比较产生PWM的模式)下,每个PWM周期可以产生两次UPDATE事件。


QQ截图20151122021239.jpg

总结就是:每个PWM周期采集两次这一要求,如果用单向计数(产生锯齿波,比较产生PWM)模式,可以用50%占空比的一路PWM输出的上升沿及下降沿作为ADC的触发信号;如果用中心对称模式,可以用UPDATE事件作为ADC触发信号。


未完待续。
来自:电气工程 / 电气电工
21
 
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
novakon 作者
9年1个月前 IP:江西
798195
补充:我用的是STM32F0系列,附Reference Manual PDF。


attachment icon stm32f030 ref man.pdf 13.48MB PDF 295次下载 预览
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
novakon作者
9年1个月前 IP:江西
798255
让我们进一步分析电流波形的采样。



当电流原始波形不是对称三角波(即占空比不为0.5)的时候,经过运放放大的波形也不是对称的。这样即便每个周期等间隔采样两次,获得的平均电流仍然与实际值有误差。


QQ截图20151122140815.jpg


从信号频谱和采样理论的角度来分析:
经过运放放大的电流波形,是原来电流波形经过一阶低通滤波器之后的样子(运放GBP=1MHz)。原波形为接近锯齿波的三角波,包含直流偏置、基频(50k)二倍频(100k)以及三倍频(150k)等整数倍频分量。
通过运放后,直流偏置不变。
基频50k虽然有一点点相移,但是由于我们用100k频率等间隔采样,因此对50k基频采样结果的平均值将保持为0(不管相移有多少)。也就是我们消除了50k基频分量,消除了50k纹波对平均电流采样的影响。


但是对整数倍频来说,事情就没那么简单了。
先看奇数倍频,用100k采样率对三倍频和五倍频(150k、250k)频率的信号进行采样,得到的平均结果仍然为0:
QQ截图20151122143230.jpg

图中绿色线为三倍频(150k)信号,灰色线表示相位为0度时的两个采样点,橙色线表示相位为90度时的两个采样点,显然这两组采样的平均值总是为0,与相位无关。
这就是为什么占空比接近0.5时的对称三角波可以使用两次采样平均的方法消除纹波误差:因为对称三角波只有奇数次倍频分量。


再看偶数倍频,以100k为例:
QQ截图20151122143735.jpg

显然,两次电流采样的平均值与相位相关,只有在相移为0的时候,平均值才是0,当相移为90度的时候,平均值为正。因为例子中使用了低速运放,从信号的产生到采集相移较大,导致这个误差很难消除。


因此可以得到结论:如果要消除偶次谐波对平均电流采样精度的影响,有两个办法,一个是将偶次谐波的相移减小到接近0,也就是使用高速的运放:


QQ截图20151122135455.jpg



缺点也是明显的,TL072(或者NE5532)需要一个负的电源以产生接近地的输出(以利用ADC全部精度),而能够实现轨到轨输出的高速运放通常较贵;从图上来看,对于比较低的占空比(接近锯齿波的电流波形),只有在较平缓的一侧采样才能降低误差的,在较陡峭的一侧采样会产生较大误差(因为再快的运放,也无法把延迟降到0,而陡峭侧的上升时间非常短,很难准确采集到中点)。通过设计程序,实现在较平缓一侧采样的数字电源设计方面的论文有很多。


第二个办法是,利用滤波电路滤除偶次谐波。最简单的方法是用低通滤波器滤除高于50k的所有频率分量。
于是我设计了一个三阶低通:

QQ截图20151122154240.jpg


从bode图上来看,我在100kHz附近实现了-21dB的衰减(直流信号是26dB放大)。换言之,设纹波形状接近锯齿波,电流峰峰值为1安,对检测到的平均电流的影响大概为1/pi*0.5*(-47dB)安左右。总之这是一个非常小的数值,懒得算,1毫安左右吧。
计算公式可以参考XXXXXXXXXXXXXXXXXXXXXXX/dlll/Dianlu/ZhangJieXueXi/xxnr/XXXXXm
QQ截图20151122162621.jpg



下图显示,这个滤波器将会使得电流信号滞后大约1.2个周期,也就是在电流反馈环稳定后,增益为0(相位为180度)的频率大概在10k(4.8周期)附近。


QQ截图20151122154111.jpg



因此,如果需要较快的电流环响应,可以将滤波器的截止频率设高一些,代价是采集到的电流值受纹波干扰较大,也就是电流精度不高。当然对于开关电源来说,这是可以接受的,取决于用户的需求。面对较低的电流环响应速度,可以通过增加输出电容的容量实现更好的电压瞬态响应,或者增加电感的感量实现更好的电流瞬态响应。


当然聪明的人已经想到了第三个办法:把采样率提高到200k,每4次采样求平均,不就可以滤除100k干扰了?而且这样环路带宽也可以增加很多。主要的困难是实现上的问题,等待4次采样到来之后只剩下5us时间计算反馈环路(64M主频下大概300指令周期),除非用DMA托管采集工作,而这又需要操作DMA,增加了代码的复杂度。

另外其实还有第四个办法:将电流信号的两个版本,未经过滤波直接放大的低延迟/大误差版本和经过滤波再放大的高延迟/小误差版本,分别接到单片机的两个AD端口,以100kHz频率采样(每次连续采集两个通道)。PID反馈环路中,低延迟版本负责控制P,低误差版本负责控制I,这样既兼顾了瞬态响应,又解决了稳态误差问题。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
novakon作者
9年1个月前 IP:广东
798644
现在已经实现了利用定时器UPDATE信号触发ADC连续采样3个通道,并通过轮询依次读出。
20151126_020113.jpg



QQ截图20151125210316.jpg



经过了解,F0系列使用M0内核,比M3内核(STM32F1系列)同频率慢40%,除了32x32乘法以外,性能与八位机无异。。。
所谓一个除法难倒英雄汉。
而且,F030芯片不支持很多高端大气上档次的调试技术,例如没有SWO,导致在IAR里面连变量曲线图都画不出来(当然我认为这是IAR的锅,既然能Live Watch,凭什么不能绘图)。。。
当然,性能的事情,最终都可以解决的,无非就是加几十块钱变M4内核的事情。


倒是最困难的问题没有解决。
板子不是我LAYOUT的,是同学做的,兼有电源线太细、退耦电容太远等若干问题。
20151126_020027(1).jpg


总之AD采样一直抖,达不到12bit精度要求,只有9-10bit。这样水平的设计,是做不了电源的。
原因除了上述,还可能是稳压器负载调节率太高。需要更多的实验。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
novakon作者
9年1个月前 IP:广东
798751
引用 灬小猫:
我觉得可以设计成这样,比如恒流设定1A,电流采样到超过1.01A的时候开关管截止,降到0.99A的时候开关管再次开启,这样就省去平均计算的麻烦了。。。
那种属于滞环控制。它有几个优点,比如电流响应快。甚至不需要用ADC采样电流,用DAC输出电流信号然后用比较器产生波形就ok了。特别是有些型号的MCU自带运放和比较器的,更是如此。随后会分析这种工作方式的可行性。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
novakon作者
9年1个月前 IP:广东
798761
引用 Earthman:
st的adc用VCC作参考,不抖才怪,一般也就10bit可用,要不抖,你得带vref的用外置基准。说到底还是用STM32F3XX算了,贵不了多少的
f334系列有高分辨率定时器,12bit DAC,和高速比较器,如果用于滞环控制是很好的。但是考虑到其AD只有12bit,应用高分辨率PWM的意义不大。由于我这次环路设计是基于PWM的,所以用F0 F3差别不大。F3 的好处是计算速度快很多,可以跟上比较高速的环路。


stm32的ADC是8pF输入电容采样保持,理论上AVDD(内部连接VREF)做好退耦(做得跟独立VREF电源一样好)也是可以的,这次这个板子设计不行,下次我会再测试,看看是不是不用独立VREF数字就一定跳。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
novakon作者
9年1个月前 IP:广东
800178
引用 huangqi412:
这个是逐周比较  F0有这个功能   比较输出直接禁止PWM输出 硬件级别的
是的,可以作为安全限流,但不便用于控制环,除非做的就是恒流源。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
novakon作者
9年1个月前 IP:广东
800288
引用 huangqi412:
导致在IAR里面连变量曲线图都画不出来(当然我认为这是IAR的锅,既然能Live Watch,凭什么不能绘图)。。。

串口曲线总没问题吧,USB转串口,波特率上M。定时器刷基本不占用CPU.
没问题,就是要另开窗,而且对执行有影响,说不占用至少也要一两微秒。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
novakon作者
9年0个月前 IP:广东
801900
引用 whzing:
哈哈,楼主的想法和我异曲同工。我今年电子设计国赛作品就是用STM32F334做的数控电源。侥幸得了电源题的全国第一。
居然专门为了回帖注册,我已经被感动了。
还不赶快把作品贴上来。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
novakon
学者 机友 笔友
文章
1256
回复
8386
学术分
16
2008/03/29注册,2年10个月前活动

已走,勿送

主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}