弘毅 发表于 2014-4-24 19:38:27

OCROBOT入门教程004--PWM控制LED(呼吸灯)

本帖最后由 董董soul 于 2016-10-27 10:50 编辑

PWM(Pulse-width modulation)脉宽调制

PWM是使用数字手段来控制模拟输出的一种手段。使用数字控制产生占空比不同的方波(一个不停在开与关之间切换的信号)来控制模拟输出。
以OCROBOT MANGO来看,端口的输入电压只有两个0V与5V。如我我想要3V的输出电压怎么办。。。有同学说用电阻分压,对滴,这个方法是正确滴。但是如果我想1V,3V,3.5V等等之间来回变动怎么办呢?不可能不停地切换电阻吧。这种情况下。。。就需要使用PWM了。他是怎么控制的呢,对于OCROBOT的数字端口电压输出只有LOW与HIGH两个开关,对应的就是0V与5V的电压输出,我们把LOW定义为0,HIGH定义为1.一秒内让控制板输出500个0或者1的信号。如果这500个全部为1,那就是完整的5V,如果全部为0,那就是0V。如果010101010101这样输出,刚好一半一半,输出端口就感觉是2.5V的电压输出了。这个和放映电影是一个道理,我们所看的电影并不是完全连续的,它其实是每秒输出25张图片,在这种情况下人的肉眼是分辨不出来的,看上去就是连续的了。PWM也是同样的道理,如果想要不同的电压,就控制0与1的输出比例控制就ok~当然。。。这和真实的连续输出还是有差别的,单位时间内输出的0,1信号越多,控制的就越精确。

在PWM的使用中我们使用到的最关键函数为analogWrite(),我们先来介绍一下这个函数。
analogWrite()
从一个引脚输出模拟值(PWM)。可用于让LED以不同的亮度点亮或驱动电机以不同的速度旋转。analogWrite()输出结束后,该引脚将产生一个稳定的特殊占空比方波,直到下次调用analogWrite()(或在同一引脚调用digitalRead()或digitalWrite())。PWM信号的频率大约是490赫兹。
在OCROBOT MANGO、NANO控制板上(328P核心),只有引脚3,5,6,9,10和11可以实现该功能。在OCROBOT MEGA2560上,引脚2到13可以实现该功能。在使用analogWrite()前,你不需要调用pinMode()来设置引脚为输出引脚。
analogWrite函数与模拟引脚、analogRead函数没有直接关系。
语法
analogWrite(pin,value)
参数
pin:用于输入数值的引脚。
value:占空比:0(完全关闭)到255(完全打开)之间。

在下图中,绿线之间代表一个周期,其值也是PWM频率的倒数。换句话说,如果PWM的频率是500Hz,那么两绿线之间的周期就是2毫秒。 analogWrite() 命令中可以操控的范围为0-255, analogWrite(255)表示100%占空比(常开), analogWrite(127)占空比大约为50%(一半的时间)。



在OCROBOT MANGO的数字引脚中,只有加了#号的才是带硬件PWM输出的引脚,我们这次就用D9引脚接一颗LED。电路连接方式如下图:



我们把代码复制进入IDE,然后编译下载。

int led=9;//定义一个变量led,赋值为9


void setup() {
    pinMode(led, OUTPUT);//设置led为输出模式
}

void loop() {
    for (int brightness = 0; brightness < 255; brightness++) { //定义变量brightness,从0开始增加,大于等于255时跳出循环。
      analogWrite(led, brightness); //在led变量定义的引脚输出PWM方波,值为brightness。
      delay(10);//延时10毫秒
    }
    for (int brightness = 255; brightness >= 0; brightness--) { //定义变量brightness,从255开始减少,小于等于0时跳出循环。
      analogWrite(led, brightness); //在led变量定义的引脚输出PWM方波,值为brightness。
      delay(10); //延时10毫秒
    }
    delay(100); //延时100毫秒

}


http://player.youku.com/player.php/sid/XNzEyNzIwMTY4/v.swf

课后练习:
我们尝试的修改delay()的时间,尝试加快或者减慢呼吸灯的呼吸的速度,创造多种不同的效果。

476956860 发表于 2014-7-15 23:35:38

int led=9;//定义一个变量led,赋值为9


void setup() {
    pinMode(led, OUTPUT);//设置led为输出模式
}

void loop() {
    for (int brightness = 0; brightness < 255; brightness++) { //定义变量brightness,从0开始增加,大于等于255时跳出循环。
      analogWrite(led, brightness); //在led变量定义的引脚输出PWM方波,值为brightness。
      delay(10);//延时10毫秒
    }
    for (int brightness = 255; brightness >= 0; brightness--) { //定义变量brightness,从255开始减少,小于等于0时跳出循环。
      analogWrite(led, brightness); //在led变量定义的引脚输出PWM方波,值为brightness。
      delay(10); //延时10毫秒
    }
    delay(100); //延时100毫秒

}

476956860 发表于 2014-7-15 23:37:24


int led=9;//定义一个变量led,赋值为9


void setup() {
    pinMode(led, OUTPUT);//设置led为输出模式
}

void loop() {
    for (int brightness = 0; brightness < 255; brightness++) { //定义变量brightness,从0开始增加,大于等于255时跳出循环。
      analogWrite(led, brightness); //在led变量定义的引脚输出PWM方波,值为brightness。
      delay(10);//延时10毫秒
    }
    for (int brightness = 255; brightness >= 0; brightness--) { //定义变量brightness,从255开始减少,小于等于0时跳出循环。
      analogWrite(led, brightness); //在led变量定义的引脚输出PWM方波,值为brightness。
      delay(10); //延时10毫秒
    }
    delay(100); //延时100毫秒

}

红色为错误地方,我不懂程序 研究了很久才发现的

迷你强 发表于 2014-7-16 15:12:35

被活捉bug

弘毅 发表于 2014-7-16 15:31:07

原来是少了个/。。。。。已经修改

正点原子 发表于 2015-7-9 17:06:33

为什么开头要用int led=9;//定义一个变量led,赋值为9


void setup() {
    pinMode(led, OUTPUT);//设置led为输出模式
}



而不直接用
void setup(){
pinMode(9,OUTPUT);
}

mlyl 发表于 2017-2-8 08:49:01

:):):):):):):):):):):)
页: [1]
查看完整版本: OCROBOT入门教程004--PWM控制LED(呼吸灯)