Arduino的详细介绍(基于Mega2560)(分文)——PWM的analogWrite()

Arduino的PWM是我写Arduino系列博文的根本原因,因而肯定会更加详细地介绍。


一:PWM的介绍:

PWM是一种调制方式,那么为什么会有这种方式存在?大家可能知道Arduino有模拟输入引脚,这些引脚是通过A/D转换操作的,而一般的数字引脚却只能输入HIGH或LOW电平,那么中间电平可否输出呢?比如2v的电平如何输出?于是PWM应运而生。PWM的高明之处在于:它输出的仍然是HIGH或者LOW电平,但可以间歇性周期性输出,则利用取平均值的方法,可以达到满意的输出效果。一个简单的例子:在0~5s内输出5v的电平,那么0~5s的平均电压就是5v,而倘若我在0~2.5s输出5v,在2.5~5s输出0v(占空比50%),那么这5s内平均电平就是2.5v,显然可以达到我们想要的效果。但仍有问题:倘若你的周期很长,就像上面例子所说,周期5s,点亮一个LED灯(LOW亮,HIGH灭),那么LED灯显然是前2.5s灭,后2.5s亮,显然达不到调灯暗亮的效果。但当周期被缩小之后比如20ms,这时候亮与灭只是很短时间内的事,肉眼根本看不到亮灭的变化,因而LED灯表现的就是亮度变暗。于是我们知道:PWM调制的周期一般比较短。PWM只是用数字输出替代模拟量输出,因此单方面还是不行的,这就要求我们的设备还要支持PWM的调制。(比如舵机等)。因而PWM的周期也不能任意短,还需要满足我们设备的调制要求。

我这里只是非常通俗的理解,如果还有疑问请查阅相关资料。


二:analogWrite()

功能:

analogWrite()实现对引脚设置PWM的要求。可以被用来控制LED等,电机转动,舵机等。使用此函数后,引脚会产生稳定的方波,直到下一次对引脚做其他操作。大多数引脚的PWM频率大约为490Hz。在Uno以及相似的板子上,pin5和pin6有大约980Hz的频率。Leonardo板子的pin3和pin11也有980Hz的频率。

在大多数的Arduino板子上(用ATmega168或者ATmega328的板子),在引脚3,5,6,9,10和11有PWM功能;在Arduino Mega板子上,在2~13和44~46引脚有PWM功能。使用ATmega8的老板子只在9,10和11引脚支持analogWrite()。

Arduino Due板子在2到13引脚和DAC0,DAC1引脚支持analogWrite()。但是ADC0和DAC1是采用D/A转换的方式输出,它们确实输出的是模拟量而不是由PWM调制输出的。

另外,使用analogWrite()不需要再用pinMode()设置引脚为输出。

形式:

analogWrite(pin,value)

参数:

pin:写入的引脚;

value:占空比,在0~255之间。(0时候为关,即LOW;255为开,即HIGH)

返回值:none

注:5pin和6pin产生的PWM输出会比设置的占空比高,这是因为millis()和delay()函数与它们使用相同的内部时钟。

示例:

int ledPin = 9;      // LED connected to digital pin 9

int analogPin = 3;   // potentiometer connected to analog pin 3

int val = 0;         // variable to store the read value



void setup()

{

  pinMode(ledPin, OUTPUT);   // sets the pin as output

}



void loop()

{

  val = analogRead(analogPin);   // read the input pin

  analogWrite(ledPin, val / 4);  // analogRead values go from 0 to 1023, analogWrite values from 0 to 255

}

现在我们来看看为何Servo库detach时候要连9或10pin。首先舵机需要20ms的控制周期,可见9,10脚在使用Servo库的时候其引脚PWM频率应该大概为1/0.02=50Hz,也就是这两引脚的PWM周期恰好满足了舵机的控制要求。我们来看看Servo库相关资料:

The Servo library supports up to 12 motors on most Arduino boards and 48 on the Arduino Mega. On boards other than the Mega, use of the library disables analogWrite() (PWM) functionality on pins 9 and 10, whether or not there is a Servo on those pins. On the Mega, up to 12 servos can be used without interfering with PWM functionality; use of 12 to 23 motors will disable PWM on pins 11 and 12.

可见,Servo使用时候会disable PWM,说明Servo的控制原理并不是利用Arduino本来的PWM输出,而是自己重新模拟了PWM。并且,现在的Arduino最多可支持48路motors,说明attach只限定于9,10口肯定是不合理的。我们再接着看,到attach()函数的说明页:

Attach the Servo variable to a pin. Note that in Arduino 0016 and earlier, the Servo library supports only servos on only two pins: 9 and 10.

于是真相大白了:Arduino 0016版本的Servo library编写时候只支持9,10pin,这里的0016当然不是Arduino的硬件版本,而是Arduino IDE的软件版本!那么,自己的软件版本到底是多少呢?不用想了,现在肯定不止0016版本了!你可以打开Arduino IDE安装目录,找到revisions.txt文本文件打开看看(可以从后往前找,这是版本我更新史啊!),可以看到:ARDUINO 0016 - 2009.05.30。09年时候发行的才是0016版本!所以现在就放心使用Servo library吧。

另外提醒下:使用多个舵机时候最好使用额外电源供电。



©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页