1.PWM概述
脉冲宽度调制(Pulse Width Modulation)简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。
脉冲宽度调制(PWM)是一种对模拟信号电平进行数字编码的方法,由于计算机不能输出模拟电压,而只能输出0V或5V的数字电压值(0V为0,5V为1),所以通过高分辨率计数器,利用方波的占空比被调制的方法对一个具体模拟信号的电平进行编码。
但PWM信号仍然是数字的,因为在给定的任意时刻,直流供电要么是5V(数字值为1),要么是0V(数字值为0)。电压或电流源以一种通(ON)、断(OFF)的重复脉冲序列加到模拟负载上,只要带宽足够,任何模拟值都可以使用PWM进行编码。
输出的电压值是通过通和断的时间进行计算的,计算公式为:
输出电压=(接通时间/脉冲时间)*最大电压值
PWM的3个基本参数如下。
(1)脉冲宽度变化幅度(最小值/最大值)。
(2)脉冲周期(1s内脉冲频率个数的倒数)。
(3)电压高度(如0~5V)。
Arduino控制器上有6个PWM接口,分别是数字接口3、5、6、9、10、11。
2.试验原理
PWM是使用数字手段来控制模拟输出的一种手段。使用数字控制产生占空比不同的方波(一个不停地在开与关之间切换的信号)来控制模拟输出。占空比越高,端口得到的实际电压越接近5V,灯的亮度越亮。
请看图2-25。
Arduino端口的输入电压只有两个,即0V与5V。如果想要3V的输出电压怎么办,也许你会说串联电阻?行,这个方法是正确的。但是如果想在1V、3V、3.5V等之间来回变动怎么办呢?不可能不停地切换电阻吧。在这种情况下,就需要使用PWM了。它是怎么控制的呢,对于Arduino的数字端口电压输出只有LOW与HIGH两个开关,对应的就是0V与5V的电压输出,我们把LOW定义为0,HIGH定义为1,1s内让Arduino输出500个0或者1的信号。如果这500个全部为1,那就是完整的5V,如果全部为0,那就是0V。如果010101010101这样输出,刚好一半一半,这样输出端口实际的输出电压是2.5V。这个类似于放映电影,我们所看的电影并不是完全连续的,它其实是每秒输出25张图片,在这种情况下人的肉眼是分辨不出来的,看上去就是连续的了。PWM也是同样的道理,如果想要不同的电压,则控制0与1的输出比例就可以。当然,这和真实的连续输出还是有差别的,单位时间内输出的0、1信号越多,控制就越精确。
图2-25 占空比调整
在图2-25中,竖线之间代表一个周期,其值也是 PWM 频率的倒数。换句话说,如果arduinoPWM的频率是500Hz,那么两绿线之间的周期就是2ms。analogWrite()命令中可以操控的范围为0~255,analogWrite(255)表示100%占空比(常开),analogWrite(127)占空比大约为50%(一半时间)。
在Arduino语法中,使用函数“analogWrite()”。
analogWrite()的作用是给端口写入一个模拟值(PWM波),可以用来控制LED灯的亮度变化,或者以不同的速度驱动电动机。当执行analogWrite()命令后,端口会输出一个稳定的占空比方波,除非有下一命令来改变它。PWM信号的频率大约为490Hz。
在使用ATmega168、ATmega328与UNO的arduino控制板上,其工作在3、5、6、9、10、11端口。ArduinoMega 2560控制板可以工作于2~13号端口。在更古老的基于ATmega8的arduino控制板上,analogWrite()命令只能工作于9、10、11号端口。在使用analogWrite()命令前,可以不使用 pinMode()命令把端口定义为输出端口,当然如果定义了更好,这样有利于程序语言的规范。
语法:
analogWrite(pin,value)
参数:
Pin:写入的端口。
Value:占空比,在0~255之间。
注释与已知问题:
当PWM输出于5、6号端口的时候,会产生比预期更高的占空比。原因是PWM输出所使用的内部时钟,millis()与 delay()两函数也在使用,所以要注意使用5、6号端口时,占空比要设置得稍微低一些,或者会使5、6号端口无法输出完全关闭的信号。
3.硬件连接
本次试验需要如下硬件。
(1)LED灯:1个。
(2)220Ω的电阻:1个。
(3)多彩面包板试验跳线:若干。
将控制板、面包板连接好,然后按照图示将发光二极管通过220Ω电阻连接到数字的第9引脚,从而完成了试验的连线部分,如图2-26所示。
图2-26 实际接线图
4.程序代码
程序代码如下。
int brightness=0;//定义整数型变量brightness与其初始值,此变量用来表示LED的亮度
int fadeAmount=5;//定义整数型变量,此变量用来做亮度变化的增减量
void setup(){
pinmode(9,OUTPUT);//设置9号口为输出端口
}
Void loop(){
analogWrite(9,brightness);//把brightness的值写入9号端口
brightness=brightness+fadeAmount;//改变brightness的值,使亮度在下一次循环时发生改变
if (brightness==0||brightness==255){
fadeAmount=fadeAmount;//在亮度最高与最低时进行翻转
}
delay(30);//延时30ms
}
5.下载程序
参照前面所讲的方法将程序下载到开发板中。
6.试验结果
将程序下载到试验板后可以观察到,通过PWM来控制一盏LED灯,让它慢慢变亮再慢慢变暗,如此循环。