## PWM(脉冲宽度调制)原理、应用以及实现
### 1. PWM的原理
PWM(Pulse Width Modulation)全称脉冲宽度调制,它通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形(含形状和幅值)。
#### 面积等效原理
面积等效原理是PWM控制技术的重要理论基础。
原理内容:冲量相等而形状不同的窄脉冲加在具有惯性的环节上时,其效果基本相同。
* 冲量即指窄脉冲的面积。
* 效果基本相同,是指环节的输出响应波形基本相同。
* 如果把各输出波形用傅里叶变换分析,则其低频段非常接近,仅在高频 段略有差异。
* 将图1a、b、c、d所示的脉冲作为输入,加在图2a所示的R-L电路 上,设其电流i(t)为电路的输出,图2b给出了不同窄脉冲时i(t)的响应波形。
#### PWM信号参数
{{::pwm6.jpg|}}
周期:信号变化的过程中,某段波形重复出现,其某一次开始至结束的这段时间就称为“周期“。\\
脉宽:在一个周期内正脉冲的持续时间。\\
占空比:是在一串理想的脉冲系列中,脉宽与周期的比值。例如在上图中t为正脉冲的持续时间,T为脉冲周期,占空比为t/T。\\
----
### 2. PWM的应用
* 使用PWM制作呼吸灯
* 使用PWM对LED调光
* 使用PWM制作电子琴
* 使用PWM驱动舵机
* 使用PWM驱动步进电机
* 使用PWM驱动直流减速电机
* 使用PWM实现DAC的功能
* 使用PWM实现直流稳压
### 3. PWM的实现方式
简而言之,PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。\\
PWM信号仍然是数字信号,而且幅值相等,在任意时刻,输出的信号就只有1(ON)或者0(OFF)两个状态,具体是0还是1,则由控制器来控制,也由控制器的精度决定。\\
只要带宽足够,任何模拟值都可以使用PWM进行编码。 \\
既然PWM是数字信号,那么任何具有高低电平可控输出功能的数字芯片都可以生成PWM,比如最常用有微控制器(MCU),可编程逻辑FPGA,或是LED驱动控制芯片如PCA9685,以及各种电源用的控制芯片,以上都可以产生PWM波形,所以说PWM应用实在是太广了。
[[sigma_delta_modulator|Sigma Delta调制]]
#### 模拟器件搭建PWM电路
{{:pwm发生电路.png|}}
* 参考西安交大杨振国教授《新概念模拟电路V》
* https://www.engineersgarage.com/circuit_design/diy-circuit-design-pulse-width-modulation-pwm/
#### 3.1 单片机(MCU)生成PWM
使用MCU生成PWM是最简单的方式,PWM发生功能和定时器功能是一起的,一种方法是使用软件设置定时器的定时时间,定时时间到翻转IO的高低电平,由于是软件来翻转电平,因此精度不能做到非常精确;另一种是直接使用定时器中的PWM功能,在定时器模块中已经集成了专用的PWM发生电路,用户只需要配置一下该模块的寄存器,在寄存器中配置好PWM的频率和占空比,软件使能该功能后,就可以输出精准的PWM波形。
{{drawio>mcu_pwm_awg.png}} 微控制器通过定时器输出PWM,再经过模拟低通滤波器得到模拟信号
{{ :contenteetimes-images-edn-design-ideas-make-dac-microcontroller-pwm-timer-figure2.png |}}每一路可以产生不同的信号
{{ :contenteetimes-images-edn-design-ideas-make-dac-microcontroller-pwm-timer-figure4.png |}}微控制器的软件流程
更多与微控制器定时器生成PWM信号的信息参见技术文章:[[https://www.edn.com/make-a-dac-with-a-microcontrollers-pwm-timer/|使用微控制器的PWM定时器作为DAC]]
#### 3.2 用Verilog生成PWM
参见文章:[[pwm_verilog|PWM的应用及相应的Verilog代码]]
#### 3.3 双PWM扩展转换频率和分辨率
{{ :daul_pwm_schem_sm.jpg |}}采用多PWM输出扩展工作频率和分辨率的图示
为方便测试和验证,特用KiCad设计了一块测试板,电路原理图和PCB的3D效果图如下,图中的阻、容参数可以根据实际使用的位数以及转换频率、要生成的波形的频率进行调整。在此电路中的值为16位DAC设置。
{{ :dualpwmsch.jpg |}} 双PWM的原理图,用KiCad绘制
{{ :dualpwmlpf.jpg |}} 双PWM的PCB 3D,用KiCad绘制
下面是用树莓派RP2040微控制器,通过MicroPython混合汇编语言编程生成正弦波形的参考代码:
import time, _thread, sys
from machine import Pin, PWM
import math
import uarray
pwmA = PWM(Pin(1, Pin.OUT)) # upper 4 bits
pwmB = PWM(Pin(0, Pin.OUT)) # low 4 bits
# Set the PWM frequency.
pwmFreq= int(125_000_000/16) # 4 bit
pwmA.freq(pwmFreq)
pwmB.freq(pwmFreq)
pwmA.duty_u16(31<<10) # upper
pwmB.duty_u16(0<<10)
sineBufLen= 500 #for 1kHz and 500kHz update frequ
sineBuf=uarray.array("H",range(0,sineBufLen))
def setAmpl(amp):
global sineBuf
for x in range(0,sineBufLen):
xr= x/sineBufLen*2*math.pi
sineBuf[x]= 127 +int(amp*math.sin(xr)) # 8 bit resolution
#print(sineBuf[x])
ddsCtrl = uarray.array('i',[
0x40050000 + 0x0c, # 0 cc7, Counter compare values, Channel 7
sineBufLen, # 4
0x40054000 + 0x28, # 8 TIMERAWL Register 1 MHz S. 553, Raw read from bits 31:0 of time (no side effects)
int((1<<16)*1.0) # 12 Index Step <>0 run, step in half words
])
@micropython.asm_thumb
def dds(r0, r1): # Buffer, ctrl-array
mov(r2,r0) # Buffer Start Address
ldr(r5, [r1,4]) # buffer length
ldr(r4, [r1,0]) # pwm counter compare register
mov(r3,0) # Buffer Index fine
label(nextVal)
label(waitLoop)
ldr(r6, [r1,8]) # Timer address
ldr(r6, [r6,0]) # 1Mhz Timer
lsr(r6,r6,1) # 500kHz
cmp(r6,r7)
beq(waitLoop)
mov(r7,r6) # store time slice
lsr(r0,r3,16) # index coarse
lsl(r0,r0,1) # index coarse half words
add(r0,r0,r2)
ldrh(r0,[r0,0]) # read buffer regPoke(0x40050000 + 0x98, ((a>>6)<<16) + (a&63))
lsl(r6,r0,28) # get the lowest 4 bits
lsr(r0,r0,4) # shift bits right (upper)
lsl(r0,r0,16)
lsr(r6,r6,28) # lower 4 bits
add(r0,r0,r6)
str(r0,[r4,0])
#b(retu)
ldr(r6, [r1,12]) # reload step index repeat?
cmp(r6,0)
beq(retu)
add(r3,r3,r6) # next buffer index fine
lsr(r0,r3,16)
cmp(r5,r0) # end not yet reached
bhi(nextVal)
lsl(r0,r5,16)
sub(r3,r3,r0)
mov(r0,r3)
b(nextVal)
label(retu)
def setF(f):
ddsCtrl[3]=int(f/1000*(1<<16))
def ddsWrap(sineBuf, ddsCtrl):
dds(sineBuf, ddsCtrl)
_thread.exit()
_thread.start_new_thread(ddsWrap,(sineBuf, ddsCtrl))
setAmpl(127)
setF(20000)
{{ :prpwm_5khz.jpg |}} 生成的5KHz的正弦波信号
{{ :prpwm_20khz.jpg |}} 生成的20KHz的正弦波信号
{{ :prpwm_50khz.jpg |}} 生成的50KHz的正弦波信号,低通滤波器截至频率太低
### 4. 示例
使用PWM制作呼吸灯
{{::pulse.gif|}}
### 5. 参考文章
* [[http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/index.html|双PWM电路]]
* [[http://www.openmusiclabs.com/learning/digital/pwm-dac/pwm-distortion-analysis/|PWM DAC失真度分析]]
* [[https://www.edn.com/combine-two-8-bit-outputs-to-make-one-16-bit-dac/|用2个8位输出制作一个16位的DAC]]
* [[https://www.edn.com/fast-settling-synchronous-pwm-dac-filter-has-almost-no-ripple/|几乎没有纹波的快速建立同步PWM-DAC滤波器]]
* [[https://www.edn.com/a-faster-pwm-based-dac/|A faster PWM-based DAC]]
* [[https://www.edn.com/cancel-pwm-dac-ripple-with-analog-subtraction/|Cancel PWM DAC ripple with analog subtraction]]
* [[https://www.edn.com/hybrid-pwm-r2r-dac-improves-on-both/|使用R2R和PWM混合以提升转化的性能]]
* [[https://www.edn.com/swapping-bits-improves-performance-of-fpga-pwm-counter/|在用FPGA产生PWM通过交换数据位提升性能]]
* [[https://www.edn.com/double-%c2%b5cs-pwm-frequency-resolution/|Double µC’s PWM frequency & resolution]]
以下为更多参考技术文章,有待整理。
### PWM(1)- 独臂神通
**当你缺少DAC时**
即使在这个高度集成混合信号集成电路的时代,遇到不包含数模转换器的微控制器也并不罕见。可编程逻辑在这方面甚至更成问题;我从来没有听说过FPGA或CPLD有DAC模块。即使微控制器有DAC,也可能只有一个或两个通道——与集成ADC外设形成对比的是,集成ADC外设通常包含一个多路复用器,允许一个ADC模块转换连接到几个甚至几十个端口引脚的模拟信号。那么,当你发现一个微控制器在各个方面都非常适合你的应用,除了它没有集成DAC时,你应该怎么做呢?最明显的选择是使用外部DAC。一个快速的Digi-Key搜索表明,您至少有一千种选择,其中一些价格不到一美元,而且是小型SC70、MSOP、SOT或DFN包。但有时候你真的不想在设计中添加另一个芯片。也许你的微控制器没有三个未使用的引脚,你将需要SPI通信;也许你赶时间,不想付隔夜运费;也许你需要六个独立的DAC输出,但是没有足够的电路板空间来容纳六个通道的设备。在任何情况下,如果外部DAC是完全不可能的,那么您有一个替代方案。
**PWM、电阻器、电容器**
这里的最小值是一个电阻器,一个电容,和一些脉冲宽度调制功能。如果您使用的是FPGA或CPLD,当然不会缺少PWM功能。对于处理器,我认为我曾经使用过的每一个微控制器都包含PWM硬件,但我认为一定有一些部分不包含PWM硬件。所以这是首先要检查的事情——如果你的微控制器没有PWM,你就运气不好了(除非你想要设置一些二进制的PWM程序,但说真的,如果你在船上,只需要使用外部DAC)。接下来,您需要一种方法来低通滤波PWM信号。一个基本的单极RC滤波器可以很好,如果你不介意一些涟波的输出,所以如果所有你可以适合你的板或预算是一个电阻和电容,PWM DAC仍然是一个可行的选择。然而,一个更好的滤波器意味着一个更好的DAC,它可能值得你带一个电感或运放,这样你就可以有两个极点而不是一个。
一个典型的数字时钟信号是一个周期序列,其中逻辑高电压的持续时间等于逻辑低电压的持续时间。相反,PWM信号是一个周期序列,其中逻辑高(或逻辑低)电压的持续时间根据外部条件而变化,这些变化可以用来传输信息。如果你对无线电电路很熟悉,你就会知道,信息是通过正弦信号的方式传输的,而正弦信号是通过某种调制方式进行传输的。这种情况类似于PWM的功能——不是幅度或频率调制,而是脉宽调制。你会发现它有助于思考这个概念相似:我们都知道,一个模拟音频信号可以从汽车收音机的天线传播首先调制载波,然后处理接收到的信号的方式消除了载体和恢复原来的音频信息。同样,我们可以通过脉宽调制数字载波来产生可编程模拟电压,然后将调制后的信号“传送”到低通滤波器。
在上图中,逻辑高被标识为“ON”或活动状态,逻辑低被标识为“OFF”或非活动状态。在第一个时间段内,激活状态的持续时间与不激活状态的持续时间相等。然后,在接下来的两个时段,活动状态持续时间增加一个网格宽度;这意味着无功状态持续时间必须减少一个栅格宽度,因为PWM载波频率(因此PWM周期)是恒定的。在我们的PWM DAC的背景下,我们真的不需要知道绝对的有源和非有源持续时间;重要的是持续时间之间的比率,我们根据PWM占空比来讨论:
从占空比到模拟电压
在低通滤波器输出处观察到的标称DAC电压仅由两个参数决定,即占空比和PWM信号的逻辑高电压;在图中,这个逻辑高电压用A表示“振幅”。占空比、幅值和DAC电压之间的关系是相当直观的:在频域,低通滤波器抑制输入信号的高频成分。时域等效的效果是平滑,或平均——因此,通过低通滤波PWM信号,我们提取其平均值。让我们假设占空比为50%(即活动持续时间等于不活动持续时间),我们使用3.3 V逻辑。你大概可以猜到DAC的标称电压是多少:1.65 V,因为信号在3.3 V和0 V时的时间各占一半,因此平滑后的版本将在正中间结束。我们可以归纳如下:
分辨率?
在选择DAC时,首先要考虑的规范之一是“分辨率”,这是一个有点模糊的术语,用有点模糊的“位”单位表示。我们所说的“分辨率”真正的意思是“DAC可以产生多少不同的输出电压(或电流)?”“位”是指控制数字到模拟电路的数据寄存器,这样一个10位DAC可以产生210 = 1024个不同的输出电压。如果您充分理解了这一点,您将看到我们可以很容易地识别PWM DAC的等效分辨率。
让我们假设图中显示的PWM信号被限制为脉冲宽度是一个网格的倍数。这意味着占空比可以假设8个不同的值:0%、~14%、~29%、~43%、~57%、~71%、~86%和100%。每个占空比对应一个特定的输出电压,所以我们这里有一个3位DAC,因为23 = 8。
要确定现实生活中的PWM DAC的分辨率,只需应用相同的分析:可以生成多少不同的占空比?这个问题通常不难回答,因为标准PWM硬件块的中心元件是一个控制脉冲宽度的n位计数器,这意味着等效DAC分辨率是2N。例如,Atmel公司的SAM4S微控制器系列的数据表包括其PWM控制器的以下特性:
16位计数器意味着16位分辨率,或216 = 65536不同的电压从0 V VDDIO(可在1.62 V至3.6 V)。另一个例子,硅实验室的EFM8UB1微控制器特性变量PWM分辨率,因此参考手册是显式的关于分辨率规格:
在这一点上,当您可以从pwm + rc过滤器实现获得16位分辨率时,常规DAC似乎几乎没有任何用处。当然,这并不是全部——DAC不仅仅是解决方案。在下一篇文章中,我们将使用仿真更深入地探索与PWM数模转换相关的概念、电路和性能限制。
* [[https://www.allaboutcircuits.com/technical-articles/low-pass-filter-a-pwm-signal-into-an-analog-voltage/|Low-Pass Filter a PWM Signal into an Analog Voltage]]
* [[https://www.allaboutcircuits.com/technical-articles/low-pass-filter-tutorial-basics-passive-RC-filter/|What Is a Low Pass Filter? A Tutorial on the Basics of Passive RC Filters]]
PWM可以算是数字电路中的“独臂”神通,“独臂” - 只需一根线;“神通” - 在很多关键的应用中起到栋梁的作用。PWM(脉宽调制 Pulse Width Modulation)从字面意思上讲它是一种“调制”方式,调制就意味着在某些载波信号上携带了某些的信息,通过解调的过程就可以得到其携带的信息,这些信息的属性由PWM的产生端定义,总之在这一根仅仅发生0、1交替变化的信号线上可以做出很多文章。
今天我们就看看如何通过PWM的方式实现数字到模拟变换的功能,也就是通过改变一根管脚的输出脉冲,得到模拟世界的某种波形。
首先PWM是由一串连续行走在某输出管脚上的0、1交替出现的信号组成,我们称高电平1为ON,低电平0为OFF,ON+OFF为一个周期T,ON的持续时间除以周期T就为占空比 - Duty Cycle,看下面的两个图。
{{drawio>pwm_on_off.png}} PWM波形, 高电平1为ON,低电平0为OFF, 占空比(Duty Cycle)为高电平持续时间除以周期
如果发送端用脉冲的占空比来传递“电压值”,也就是将某个数字的电压值对脉冲的占空比进行调制,就可以在接收端通过RC低通滤波器(也就是解调器)从调制脉宽的数据流中得到需要的模拟电压值,从而达到DAC的目的。看下面的动图 - 假设脉冲的占空比为0的时候(整个周期全部为OFF - 低电平)代表电压值为0,占空比为100%的时候(整个周期全部为ON - 高电平)代表电压值为最高电压,比如3.3V,则40%的占空比就是40%*3.3V。占空比改变-每个周期的脉宽改变,也就意味着输出的电压值在改变。
{{ :pwm_1.gif |}}
{{ :pwm_2.gif |}}
用脉宽的改变携带电压值的变化信息
{{ :spectrum-of-PWM-signal.jpg |}}用一个电阻和电容组成的低通滤波就可以将PWM中携带的电压信息“解调”成模拟的电压值
{{ ::ON-OFF-PWM-Duty-Cycle.png |}}用一个电阻和电容组成的低通滤波就可以将PWM中携带的电压信息“解调”成模拟的电压值
{{ ::Distributed-PWM-Cycle.png |}}用一个电阻和电容组成的低通滤波就可以将PWM中携带的电压信息“解调”成模拟的电压值
{{ ::waveform-representation-of-delta-modulation.jpg |}}
{{ ::waveform-representation-of-PWM-signal-detection.jpg |}}
{{ ::waveform-representation-of-PWM-signal-generation.jpg |}}
{{ ::pwm_table_med.jpg |}}
{{ ::contenteetimes-images-01mdunn-di-di5541f1.gif |}}
{{ ::block-diagram-for-delta-modulation-receiver-1.jpg |}}
{{ ::block-diagram-for-delta-modulation-transmitter-1.jpg |}}
{{ ::Block-diagram-for-detection-of-PWM-signal.jpg |}}
{{ ::Block-diagram-for-generation-of-PWM-signal.jpg |}}
前面讲过DAC的两个关键指标 - 转换率和转换精度,在PWM里是如何对应的这两个指标么?
看一下下面的波形:
* PWM-DAC的转换频率相当于脉冲的重复频率
* PWM-DAC的分辨率相当于脉冲宽度相对于整个周期的精度,举例如果一个最小的脉冲ON的时间为5ns(可以用100MHz的时钟计数产生),PWM脉冲的周期为5ns x 256 = 1.28us,则这个PWM-DAC相当于是8位的DAC。
{{ :pwm_parameter.jpg |}}用时钟计数生成PWM波形,周期/占空比与主时钟的关系示意
也就是说如果你用100MHz的时钟来通过PWM的方式做一个8位的DAC,最高的转换频率也只能到1/1.28us ~ 781KHz分辨率高则转换率降低,因此用PWM做的DAC一般用于生成相对比较低频的信号乃至直流信号。
下面的图为经过一个最简单的由一个电阻R和一个电容C构成的低通滤波以后得到的模拟信号,可以看到在输出的模拟信号上还是有很高频率的纹波。
{{ :pwm_dac_implementation.png |}}用一个电阻和电容组成的低通滤波就可以将PWM中携带的电压信息“解调”成模拟的电压值
如果要进一步平滑输出模拟信号上的波纹,可以通过加入电感或着用运算放大器构成的有源低通滤波器来对纹波实现更强的抑制。
是不是很简单?只需一个R和一个C就能得到你想生成的模拟信号,做一个简单的任意波形发生器很简单啊。
很多MCU都有内置的ADC,但未必有DAC,如果你选用的MCU/单片机没有内置的DAC,只需要一根管脚和俩器件(R、C)就能实现DAC的功能还是很有用的,即便拟选用的MCU内部有DAC,如果你的系统中需要多个DAC的功能,且你也不想或者没有足够的管脚外挂一个单独的DAC器件(需要I2C或SPI总线连接),PWM方式是个非常不错的选择哦。
如果你用的是FPGA或CPLD,里面根本没有DAC,而你又需要一个,拿出一个管脚来产生PWM就会非常666。
理解用PWM生成DAC的机制、局限,在关键的时候也许就能起到意料不到的结果。
### PWM(2)- DAC的滤波器设计
昨天的文章写了如何通过PWM实现数字到模拟量的转换,得到很多朋友们的反馈,大家都比较感兴趣的如何选用电阻和电容的值才能得到一个满意的模拟值(低纹波)?
首先我们看一下脉冲信号的频谱,根据傅立叶变换,周期为T的脉冲信号可以分解为多个单频率的信号的叠加,最小的频率分量为1/T,有兴趣的同学可以通过Matlab自己做一下分析。
图片
比如,我们对幅度为3.3V、周期为10uS(频率100KHz)、占空比为50%的脉冲信号(此时为方波)进行FFT变换,可以得到1.65V的直流分量、100KHz、300KHz(3次谐波)、500KHz(5次谐波)。。。等频率分量,最小的交流频率为100KHz。
图片
占空比为50%的脉冲信号的波形
图片
占空比为50%的脉冲信号的频谱分量
改变占空比呢?来看看占空比为10%和90%的脉冲波形经过FFT之后的交流频率分量
图片
占空比为10%的脉冲的频率分量
图片
占空比为90%的脉冲的频率分量,只是直流分量不同,交流部分与10%的相同
从以上简单的分析可以看出,无论占空比是多少,脉冲波形除了直流分量以外,交流部分的最低频率都为脉冲的重复频率100KHz上,在DC和脉冲重复频率100KHz之间一马平川,光秃秃的。
因此,如果要得到直流分量,只需要去掉100KHz以上的频谱能量就可以了。最简单的方法就是通过由一个电阻R和一个电容C构成的一阶低通滤波器,其截止频率为fc=1/2*Pi*R*C,我们要得到的是直流分量,滤除的是100KHz以上的频率,因此只要截止频率在100KHz以内,并且能对100KHz以上的所有频谱都有较好的抑制,就能够得到比较好的DC输出。
图片
LPF电路构成和频率响应
图片
RC电路的时域响应
可以想象,截止频率越高,越是接近要滤除的频率(比如50KHz之于100KHz),该滤波器对100KHz的滤波效果就较差,就会有一定量的残余能量出现在滤波器的输出端,如下图,也就是输出的波形纹波比较高。
图片
对脉冲频率为100KHz的信号进行截止频率为50KHz的低通滤波得到的输出信号,纹波比较高
如果降低截止频率,越是接近直流,从而距离要滤除的频率越远,比如针对100KHz的脉冲频率选择1KHz作为LPF的截止频率,则在100KHz处可以达到非常高的抑制度,100KHz的残留就非常小,也就是在输出的直流信号上的纹波可以变得很小,见下图。
图片
截止频率为1KHz的低通滤波器的建立时间很长 ~ 1ms
但却出现了另外一个问题 - 需要花费很久的时间(学名叫建立时间 setting time)才能达到应该达到的DAC的直流值。原因就是fc低,意味着RC更高,也就是充电的时间常数变得很长 - R增大意味着对C进行充电的电流变小,要对C冲电到一定的值花费的时间也就更久。,
因此这就出现了一个让人纠结的选择:
选择较低的截止频率 - 较低的纹波,较长的建立时间
选择较高的截止频率 - 较大的纹波,较快的建立时间
你会说一阶不够,要不多用几阶滤波器,加上电感或者有源的运放来进行低通滤波,这确实能改善滤波的效果,但 -- 电路的复杂度增加、元器件成本增加了,且改善有限。
那不增加电路的复杂程度,还是只用这一个R和一个C是否能够改善性能呢?
答案是肯定的,其实也很简单 - 把交流分量的频率踢的远远的,在保持较低的时间常数(建立时间短)的情况下,将LPF的截止频率fc和要滤除的脉冲重复频率之间的间隔尽可能的拉开,比如将100KHz的重复频率给踢到10MHz(出去100倍),占空比不变,如果用原来的50KHz的滤波器,到了10MHz的地方怎么也把10MHz以上的频率给消灭的只剩下一点渣了。看下图,直流建立时间大约为15µs, 纹波变得只有25mV左右了。
图片
用截止频率为50KHz的RC得到的建立时间大约为15µs
图片
用截止频率为50KHz的RC对10MHz的脉冲信号进行LPF得到的纹波
是不是很神奇?其实理论依据很简单,自己把低通滤波器的频响曲线画一下就很容易理解了。
到这里我们就应该知道如何设计自己的PWM系统的各项参数来构造一个简单好用的DAC。
### PWM(3) - 用PWM点亮LED
今天LED满眼都是,几乎每个电路板上都要至少装一个用做状态指示(其实发光数码管也是多个LED组成)、各种显示器的背光、已经深入我们生活各个角落的LED台灯、路灯,几乎所有城市的夜景都是用各种颜色的LED灯来装点的。
图片
把LED点亮太简单了,只要让其流过一定的电流就可以亮了,电流越大亮度越大,电流小则亮度小。那这些灯都是如何调光(控制亮度)的呢?
大家最容易想到的,也是在很多电路板上状态指示灯最常用的一种方式就是通过串联一个电阻,改变电阻的值就可以改变LED的亮度,这种调光方式被称为模拟调光。一般来讲只需要LED灯点亮就可以,至于亮度的大小,也就是串联电阻值的大小关系并不大。当然不同颜色的LED灯其前向导通电压也不同,即便达到同样的亮度,在同样的供电电压下串联的电阻值也可能不同,因此一般都不用纠结,装一个330还是510还是1k其实都可以,觉得太暗就把电阻值弄小点,觉得太亮就把电阻值弄大点。
图片
通过串联不同值的电阻可以调节电流而实现对LED亮度的调节
模拟调光存在很大的缺点就是电阻上会消耗功率变成热量,LED对电流的响应是非常非线性的,LED灯的亮度调节范围也比较低。
因此在很多需要调光的场合都采用PWM的方式(又被称为“数字调光”),也就是在固定流经LED的电流大小的情况下,通过占空比可调节的PWM脉冲来反复控制LED的导通和关断 - 导通的时候LED按照设定好的电流值发出相应亮度的光,关断的时候LED不亮,如果PWM脉冲的重复周期高于我们人眼视觉暂留需要的频率,尤其是达到50Hz以上后,我们一般人就觉察不出LED的闪烁了,从而认为LED没有闪烁,改变PWM脉冲的占空比就能够改变LED的亮度,如下面的图。
图片
PWM调光的电路
图片
不同的占空比产生不同的亮度:50%中等亮度、10%很暗、90%很亮
图片
改变PWM脉冲的占空比就可以改变LED的发光亮度
PWM调光的优点是简单、效率高、其亮度随PWM占空比变化可以做到非常高的线性度,更符合人们对于LED调光精度、效率以及效果的要求。PWM调光可以产生3000:1甚至更高的调光比(在100Hz的频率时),而不会有任何明显的精度损失,并且LED颜色没有变化。
那么用于调光的PWM的工作频率和分辨率应该如何设定呢?
PWM的工作频率如果低于50Hz,一般的人看着LED就会感受到闪烁,当然不同的人眼可能感受不同,有的人即便频率低于10Hz也感受不到差别,厉害的人即便到了100Hz依然能够看出闪烁,光源移动的时候以及LED的亮度比较低的时候人眼对强度的变化更敏感,因此需要更高的PWM频率。所以最好其频率高于50Hz,是不是越高越好呢?一旦脉冲持续时间接近导通时间,LED就不会真正完全导通,控制亮度的线性度就会变差,甚至在频率更高/更短的脉冲的情况下LED会变暗淡甚至不亮。开关频率增大到一定程度,带来的开关损耗也会变大。比较合适的频率在50Hz到几百KHz的范围。
PWM分辨率指的是可以控制PWM脉冲占空比的精度,PWM分辨率越高,LED可以显示的“亮度”级别就越高,它可以使“关闭”与LED的最低亮度之间的差异更小,PWM分辨率决定了我们可以在完全关闭(0%)和完全开启(100%)之间支持的亮度“级别”。分辨率越高,所需的定时精度和处理开销就越多。
通过RGB三色灯配色
我们知道颜色构成中有R、G、B三基色,其它任何颜色都可以通过这三种基色以不同的比例混合的到。在显示的时候也是通过调节空间上非常靠近的三种颜色的LED灯的亮度来达到“合成色”的目的,从距离这三个“单色像素”较远的地方就可以看到混合生成的新的颜色
图片
三基色按照一定的比例混合可以的到各种不同的颜色
下图为靠近的三个不同颜色R、G、B LED灯。
图片
通过调节每个颜色的LED的控制PWM的占空比从而以不同的亮度比例进行颜色混合,从而得到你需要的合成颜色。
图片
三种单色LED等分别控制其亮度,混合后得到的颜色
图片
小脚丫FPGA板上在FPGA芯片下方有两颗3色LED灯让工程师体验PWM调光的魅力
在小脚丫FPGA通过PWM调整颜色
我们工程师经常使用MCU的PWM功能来产生相应的信号,要认真阅读该MCU的数据手册以及PWM相关的寄存器的设置,以产生你期望的PWM频率和分辨率。
有些MCU内部没有专门的PWM产生电路,可以通过指令控制GPIO管脚的交替变化实现PWM的功能,当然这会影响MCU执行其它的任务。
### PWM(4) - 驱动伺服电机
今天我们用一些图片来看看PWM在驱动伺服电机中的应用。
图片
几种常用的马达
很多工程师和高校的学生对于伺服电机已经非常熟悉了,它一般由马达、变速器、传感器组成,经常用于遥控设备来进行转向、调整角度等。
通用的伺服电机一般都是在180度范围内转动,但可以非常精准地通过控制脉冲来转到某个精准的位置。
图片
伺服电机的结构组成(1)
图片
伺服电机的结构组成(2)
图片
不同类型的伺服电机
对于小型的遥控伺服电机,控制脉冲的重复频率都是20ms(50Hz),每个脉冲的正电压持续时间被解读为控制马达的位置命令,典型的持续时间为1ms到2ms,对应于伺服电机旋转的角度-90度到+90度。
图片
伺服电机的转动角度取决于接收到的控制脉冲高电平的持续时间
也有一些电机的转动范围不是这么严格对应,拿到新的电机的时候需要进行一下校正,方法是设定一个LUT(角度和脉冲长度的查找表),然后根据需要的角度来设定对应的脉冲正电平的持续时间。
一个伺服电机一般通过三根线进行连接:
GND - 地,同系统的地连接,一般为棕色或黑色的的线
Vcc - 供电电压,一般为+5V,也有+6V的,经常会将4个1.2V的电池串联在一起做为供电电压,导线的颜色为红色
PWM - 控制信号线,橘黄色
图片
伺服电机的连接导线和控制用的PWM信号
控制伺服电机可以有多种方式:
图片
Arduino通过GPIO来控制伺服电机
图片
FPGA通过算法控制电机的精准定位
下面是伺服电机的一些应用。
图片
### PWM(5) - 开关稳压器的调压控制
在前面的文章中我们简单讲述了PWM的工作原理并蜻蜓点水地讲了其在DAC、LED调光、驱动马达方面的应用,最后我们再来看看其在开关电源方面的应用。
我们知道开关电源在现在的电子产品中大行其道,主要的原因就是其支持的输入电压动态范围宽、在很宽的输入电压范围内都可以做到较高的转换效率,也就是说能量浪费相对较少,从而也避免了电路板的过热和器件/焊盘等的迅速老化导致寿命大幅缩短。同线性稳压器三极管工作在线性状态不同的是,开关稳压器中的三极管(在这里我们包括MOS管)工作在开关状态,这也是“开关稳压”名字的来历。如下图所示:
图片
开关稳压器的工作原理示意图
开关稳压器主要由工作于开关状态的三极管+储能的电感+电容构成:
工作于开关模式的三极管:On的时候对电感充电,充电足够的时候开关关闭,电感线圈将能量以电流的方式往负载供电,输出电容同电感一起保证电压的稳定。理论上当三极管处于On的时候其没有压降,处于Off的时候没有电流通过,所以可以达到比较高的转换效率。但实际上其还是有压降和电流通过的,并且还有其它器件上的损耗;
电感:电流流入的时候通过磁场存储能量,它不喜欢电流的变化,会尽力保持电流为常数而达到平滑电流的作用;
电容:可以看作为电压滤波器,它不喜欢电压的变化,用其存储的能量来保持电压为常数。
用于控制三极管开、关从而调整输出电压的信号主要采用的就是PWM信号,有的器件则根据负载的情况灵活使用PWM和PFM(脉冲频率调制 - 固定占空比,改变脉冲的重复频率)。控制三极管开、关的PWM信号哪里来的呢?看下面的图 - 输出端(供给负载)的直流电压进行分压以后与器件内置的参考电压(一般称为Bandgap Reference)相比较,如果输出电压分压后的电压与参考电压有误差,则比较电路输出相应的误差信号控制PWM产生电路产生用于控制三极管开、关的控制信号,PWM的占空比与误差电压的大小成一定的比例,这样就构成了一个稳定收敛的反馈环路,最后达到输出电压的分压与参考电压相等,从而误差最小。
图片
PWM信号的产生机制
由于工作在开关模式,储能的电感和平滑电容的反应都需要时间,因此输出电压上一定会存在着波动,也就是误差电压也会在很小范围内波动,PWM的占空比也在抖动,但在一定的范围内,这些波动都不会影响到环路的稳定工作。
输出电压上的波动 - 也就是高频开关噪声,与PWM的开关过程相关,不同的开关稳压器件其PWM的开关频率也会不同,进而也会影响到储能电感和平滑电容的选择,具体的选择规则我们会在电源电路中进行讲解。
开关稳压器的优点:
效率比较高,相对比常规的线性稳压器,一般来讲其效率是比较高的,但也会有一些由于器件的非理想化带来一些损耗,在一个实际的系统中开关稳压器效率是否一定高于LDO(输入输出压差较低的一种线性稳压器),需要根据实际的电压、电流情况来分析、选用;
输入电压范围较宽 - 全球跑到任何地方都能用的笔记本电源适配器、刮胡刀、手机充电器等等都是用开关稳压的方式实现的,线性稳压器在这种需求下无能为力的;
同等功率下,尤其是大功率,开关稳压器的体积可以做的较小,这得益于开关工作频率的提高,有的高达几MHz,器件体积可以变得很小。
开关稳压器的缺点:
相对于三件套的线性稳压器,开关稳压器需要的元器件比较多,有的器件相对还比较大,比如线圈、电容;
高频的开关噪声比较大,元器件的布局比较关键,实现系统需要的低噪声是非常具有挑战的;
元器件的选用也非常关键,比如MOS管、储能电感、平滑电容等
开关稳压器也有不同的类型,根据输入电压和输出电压的关系分:
Buck型 - 降压
Boost型 - 升压
Buck+Boost - 既可以升压也可以降压