**这是本文档旧的修订版!**
PWM(脉冲宽度调制)原理、应用以及实现
1. PWM的原理
PWM(Pulse Width Modulation)全称脉冲宽度调制,它通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形(含形状和幅值)。
面积等效原理
面积等效原理是PWM控制技术的重要理论基础。 原理内容:冲量相等而形状不同的窄脉冲加在具有惯性的环节上时,其效果基本相同。
- 冲量即指窄脉冲的面积。
- 效果基本相同,是指环节的输出响应波形基本相同。
- 如果把各输出波形用傅里叶变换分析,则其低频段非常接近,仅在高频 段略有差异。
- 将图1a、b、c、d所示的脉冲作为输入,加在图2a所示的R-L电路 上,设其电流i(t)为电路的输出,图2b给出了不同窄脉冲时i(t)的响应波形。
图1:形状不同而冲量相同的各种窄脉冲 | 图2:冲量相同的各种窄脉冲的响应波形 |
---|
用PWM波代替正弦半波
将正弦半波看成是由N个彼此相连的脉冲宽度为π/N,但幅值顶部是曲线且大小按正弦规律变化的脉冲序列组成的。
把上述脉冲序列利用相同数量的等幅而不等宽的矩形脉冲代替,使矩形脉冲的中点和相应正弦波部分的中点重合,
且使矩形脉冲和相应的正弦波部 分面积(冲量)相等,这就是PWM波形。
对于正弦波的负半周,也可以用同样的方法得到PWM波形。
脉冲的宽度按正弦规律变化而和正弦波等效的PWM波形,也称SPWM(Sinusoidal PWM)波形。
基于等效面积原理,PWM波形还可以等效成其他所需要的波形,如等效所需要的非正弦交流波形等。
PWM波形可分为等幅PWM波和不等幅PWM波两种,由直流电源产生的PWM波通常是等幅PWM波。
图3:用PWM波代替正弦半波 |
---|
调制法生成PWM波形
把希望输出的波形作为调制信号,把接受调制的信号作为载波,通过信号波的调制得到所期望的PWM波形。
最简单可以产生一个脉冲宽度调制信号的方式是交集性方法(intersective method),
这个方法只需要使用锯齿波或三角波以及一个比较器。
当参考的信号值(红色波)比锯齿波(蓝色波) 大,则脉冲调制后的结果会在高状态,反之,则在低状态。
红色:调制信号;蓝色:载波信号;紫色:已调制信号
PWM信号参数
周期:信号变化的过程中,某段波形重复出现,其某一次开始至结束的这段时间就称为“周期“。
脉宽:在一个周期内正脉冲的持续时间。
占空比:是在一串理想的脉冲系列中,脉宽与周期的比值。例如在上图中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应用实在是太广了。
模拟器件搭建PWM电路
- 参考西安交大杨振国教授《新概念模拟电路V》
3.1 单片机(MCU)生成PWM
使用MCU生成PWM是最简单的方式,PWM发生功能和定时器功能是一起的,一种方法是使用软件设置定时器的定时时间,定时时间到翻转IO的高低电平,由于是软件来翻转电平,因此精度不能做到非常精确;另一种是直接使用定时器中的PWM功能,在定时器模块中已经集成了专用的PWM发生电路,用户只需要配置一下该模块的寄存器,在寄存器中配置好PWM的频率和占空比,软件使能该功能后,就可以输出精准的PWM波形。
微控制器通过定时器输出PWM,再经过模拟低通滤波器得到模拟信号
每一路可以产生不同的信号
微控制器的软件流程
更多与微控制器定时器生成PWM信号的信息参见技术文章:使用微控制器的PWM定时器作为DAC
3.2 用Verilog生成PWM
参见文章:PWM的应用及相应的Verilog代码
3.3 双PWM扩展转换频率和分辨率
采用多PWM输出扩展工作频率和分辨率的图示
为方便测试和验证,特用KiCad设计了一块测试板,电路原理图和PCB的3D效果图如下,图中的阻、容参数可以根据实际使用的位数以及转换频率、要生成的波形的频率进行调整。在此电路中的值为16位DAC设置。
双PWM的原理图,用KiCad绘制
双PWM的PCB 3D,用KiCad绘制
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)
生成的5KHz的正弦波信号
生成的20KHz的正弦波信号
生成的50KHz的正弦波信号,低通滤波器截至频率太低