极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 19604|回复: 6

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

[复制链接]
发表于 2014-4-24 19:38:27 | 显示全部楼层 |阅读模式
本帖最后由 董董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,然后编译下载。

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


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

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

  15. }
复制代码




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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 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毫秒

}
回复 支持 反对

使用道具 举报

发表于 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);
}
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-20 02:35 , Processed in 0.048764 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表