Arduino产生PWM的3种方法!

                                              Arduino产生PWM的3种方法!

PWM是个啥?
有人翻译成:脉冲宽度调制
PWM 是用占空比不同的方波,来模拟“模拟输出”的一种方式。简而言之就是电脑只会输出 0 和 1,那么想输出 0.5 怎么办呢?于是输出 01010101….,平均之后的效果就是 0.5 了。

PWM有什么作用?
1.通过简单的滤波电路,就可以生成真正的模拟输出量;
2.控制灯光亮度,调节电机转速;请注意这和 1 不是重复的,因为不需要滤波就可以实现
3.控制舵机角度,这个请参考 Arduino 开发板实验三:舵机控制
4.输出信号,例如接喇叭的时候可以发声

第一种:用analogWrite(pin, val) 
pin引脚的编号,传说中只能用 3,5,6,9,10,11 这几条;
val 是 0~255 的整数值,对应电压从 0 到+5V。
注意,那几个脚的编号,指的是 ATmega168 的 pin 编号,Arduino 的板子会用
这几个管脚支持更多路的 PWM 输出,例如我的 Arduino Mega168 就支持 0-13 共 14 个PWM输出。
示例代码:
int pin = 8; //0-13
void setup()
{
pinMode(pin, OUTPUT);
}
void loop()
{
analogWrite(pin, 128);
delay(500);
}
特点:这种方式产生的方波周期大概是 20ms 左右(50Hz),不需要占用额外的 cpu 命令时间。


第二种:手动用代码实现 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 脚都可以输出,不局限于那几个脚;
4、缺点:CPU 干不了其他事情了;
好吧,缺点只有一个,却非常致命,以至于上面这些基本都是废话。但是对于周期比较大的
PWM,可以用算法模拟 CPU 的多任务系统,从而在输出 PWM 的同时做点兼职。


第三种:使用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 可以使用不同的预定标器。

你可能感兴趣的:(Arduino)