PWM(脉冲宽度调制)和占空比究竟是啥?

对于很多刚刚接触Arduino的人来说,占空比和PWM 这两个词可能不太容易理解,下面就让我们深度剖析一下这两个概念。
你也可以通过与视频结合的方式学习,PWM的概念与应用,这是个不错的视频;更详细的介绍参看 用Arduino剖析PWM脉宽调制。

PWM(Pulse Width Modulation)

简介

PWM,也就是脉冲宽度调制,用于将一段信号编码为脉冲信号(一般是方波信号)。是在数字电路中 达到 模拟输出效果的一种手段。即:使用数字控制产生占空比不同的方波(一个不停在开与关之间切换的信号)来控制模拟输出。我们要在数字电路中输出模拟信号,就可以使用PWM技术实现。在嵌入式开发中,我们常用PWM来驱动LED的暗亮程度,电机的转速等。

PWM的频率

pwm的频率决定了输出的数字信号on ,1 和 off,0 的切换速度。频率越高,切换就越快。频率的大小就是前面提到的调制周期T的倒数 : f = 1/T。

1秒内,0.5秒开,0.5秒灭,占空比是50%。那么,1毫秒内,0.5毫秒开,0.5毫秒灭,占空比也是50%,对于前者,频率就是1HZ,而后者,是1毫秒,频率就是1KHZ。

一般pwm频率都是因硬件设计而固定的,是由pwm发生器决定的。PWM频率越高,调制出来的输出曲线就更加的smooth,效果越好,完成一个调制周期的时间越短。这个和手机的ppi越高,显示越清晰是一个道理。当然PWM的频率越高,对硬件的要求就也越高。

如何产生PWM?

Arduino有三种方式可以产生PWM。第一种:

用analogWrite(pin, val)命令
其中pin是引脚的编号,只能用3,5,6,9,10,11这几条;val是0~255的整数值,对应电压从0到+5V。
具体的使用可以看下面的示例代码:

int pin = 8; //0~13
void setup()
{
    pinMode(pin, OUTPUT);
}   
void loop()
{
    analogWrite(pin, 128);
    delay(500);
}

这种方式产生的方波周期大概是2ms左右(490Hz),不需要占用额外的cpu命令时间。据说99%的同学看到这里就可以下课了,技术宅请继续看第二种方式:

手动用代码实现PWM

int pin = 38;  //这个可以随意点
void setup()
{
    pinMode(pin, OUTPUT);
} 
void loop()
{
  digitalWrite(pin, HIGH);
  delayMicroseconds(100);
  digitalWrite(pin, LOW);
  delayMicroseconds(1000 - 100);
}

上面这段代码会产生一个PWM=0.1的,周期为1ms的方波(1000Hz),这种方式的优缺点很明显:

1.PWM的比例可以更精确;
2.周期和频率可控制;
3.所有的pin脚都可以输出,不局限于那几个脚;
缺点:CPU干不了其他事情了;
好吧,缺点只有一个,却非常致命,以至于上面这些基本都是废话。但是对于周期比较大的PWM,可以用算法模拟CPU的多任务系统,从而在输出PWM的同时做点兼职。
那么能不能既调节PWM的频率和周期,又不要占用额外的CPU时间呢?请看第三种方式:

使用PWM寄存器(不作要求)

ATmega168有三个时钟,名字分别叫Timer0, Timer1和Timer2。每个时钟都使用了两个寄存器,其中一个是设定值例如128,另一个则从0开始不断递增,到1024之后溢出回到0。那么当两个值相同的时候,Timer就会把某个管脚反相。不同的Timer之间频率是相同的,占空比则根据设置值不同。
占空比有了,那么周期怎么控制呢?有一种叫做时钟控制器的东东,这个控制器可以设置周期为CPU周期的某个倍数,例如1,8,64,256,1024等等,Timer0和Timer1共用一个控制器,Timer2和它们是独立的。

Atmega 168/328的时钟们
ATmega328P有三个时钟,Timer0,Timer1和Timer2。每个时钟都有两个比较寄存器,可以同时支持两路输出。其中比较寄存器用于控制PWM的占空比,具体的原理等会儿会介绍。大多数情况下,每个时钟的两路输出会有相同的频率,但是可以有不同的占空比(取决于那两个比较寄存器的设置)

每个时钟都有一个“预定标器”,它的作用是设置timer的时钟周期,这个周期一般是有Arduino的系统时钟除以一个预设的因子来实现的。这个因子一般是1,8,64,256或1024这样的数值。Arduino的系统时钟周期是16MHz,所以这些Timer的频率就是系统时钟除以这个预设值的标定值。需要注意的是,Timer2的时钟标定值是独立的,而Timer0和Timer1使用的是相同的。

这些时钟都可以有多种不同的运行模式。常见的模式包括“快速PWM”和“相位修正PWM”,这两种PWM的定义也会在后面解释。这些时钟可以从0计数到255,也可以计数到某个指定的值。例如16位的Timer1就可以支持计数到16位(2个字节)。

除了比较寄存器外,还有一些其他的寄存器用来控制时钟。例如TCCRnA和TCCRnB就是用来设置时钟的计数位数。这些寄存器包含了很多位(bit),它们分别的作用如下:
脉冲生成模式控制位(WGM):用来设置时钟的模式
时钟选择位(CS):设置时钟的预定标器
输出模式控制位(COMnA和COMnB):使能/禁用/反相 输出A和输出B
输出比较器(OCRnA和OCRnB):当计数器等于这两个值时,输出值根据不同的模式进行变化

不同时钟的这些设置位稍有不同,所以使用的时候需要查一下资料。其中Timer1是一个16位的时钟,Timer2可以使用不同的预定标器。

占空比(duty cycle)

有了前面的知识,相信你已经对占空比理解了,其实很好理解 ,所谓占空比就是调整led通过电流和不通过电流的时间比来控制的,由于人眼有视觉暂留特性,所以只要频率比较高是看不出来闪烁的。有关这部分介绍在PWM的概念与应用这个视频里有直观的说明。

当然通过电流比不通过电流的时间比例越大,led做的功就越多,这样也就越亮,需要注意的是led芯片的温升和最大电流值不要超标,不然会影响其寿命。

下面给出占空比的公式

占空比计算公式

D: 占空比
PW: 脉冲宽度(调制周期中脉冲持续时间)
T: 一个调制周期

所以我们可以很自然的得出结论:

  • 低占空比意味着输出的能量低,因为在一个周期内大部分时间信号处于关闭状态,如果pwm控制的负载为led,则具体表现例如led灯很暗。
  • 高占空比意味着输出的能量高,在一个周期内,大部分时间信号处于on状态,具体表现为LED比较亮。
  • 当占空比为100%时,表示 fully on,也就是在一个周期内,信号都处于on状态,具体表现为led亮度到达100%。
  • 当占空比为0%时则表示 totally off,在一个周期内,一直处于off状态,具体表现为led熄灭。

现在一切都明了了:脉冲宽度调制,这个宽,不是物体的宽度,而是高电平(有效电平)信号在一个调制周期中持续时间长短,它可以用占空比去衡量,占空比越大,脉冲宽度越宽。

你可能感兴趣的:(PWM(脉冲宽度调制)和占空比究竟是啥?)