极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 42165|回复: 57

arduino学习笔记3 - 六灯闪烁实验

  [复制链接]
发表于 2011-6-25 21:47:04 | 显示全部楼层 |阅读模式

通过上一节学习,知道了怎样让一个led进行闪烁,下面的实验会对六个led进行控制,先看硬件连接图。

Snap2.jpg

IMGP9891_调整大小.JPG

按照上面的硬件连接方法接好后,咱们来测试两段程序,看看其中的差别。通过这两段程序介绍一下arduino的语言轮廓。
  1. //设置控制Led的数字IO脚
  2. int Led1 = 1;
  3. int Led2 = 2;
  4. int Led3 = 3;
  5. int Led4 = 4;
  6. int Led5 = 5;
  7. int Led6 = 6;
  8. //led灯花样显示样式1子程序
  9. void style_1(void)
  10. {
  11.   unsigned char j;
  12.   for(j=1;j<=6;j++)
  13.   {
  14.     digitalWrite(j,HIGH);
  15.     delay(200);
  16.   }
  17.   for(j=6;j>=1;j--)
  18.   {
  19.     digitalWrite(j,LOW);
  20.     delay(200);
  21.   }
  22. }
  23. void setup()
  24. {
  25.   unsigned char i;
  26.   for(i=1;i<=6;i++)//依次设置1~6个数字引脚为输出模式
  27.     pinMode(i,OUTPUT);//设置第i个引脚为输出模式
  28. }
  29. void loop()
  30. {   
  31.   style_1();//样式1
  32.   
  33. }
复制代码
上面代码的效果视频如下:

  1. //设置控制Led的数字IO脚
  2. int Led1 = 1;
  3. int Led2 = 2;
  4. int Led3 = 3;
  5. int Led4 = 4;
  6. int Led5 = 5;
  7. int Led6 = 6;
  8. //led灯花样显示样式1子程序
  9. void style_1(void)
  10. {
  11.   unsigned char j;
  12.   for(j=1;j<=6;j++)
  13.     digitalWrite(j,HIGH);
  14.     delay(200);

  15.   for(j=6;j>=1;j--)
  16.   {
  17.     digitalWrite(j,LOW);
  18.     delay(200);
  19.   }
  20. }
  21. void setup()
  22. {
  23.   unsigned char i;
  24.   for(i=1;i<=6;i++)//依次设置1~6个数字引脚为输出模式
  25.     pinMode(i,OUTPUT);//设置第i个引脚为输出模式
  26. }
  27. void loop()
  28. {   
  29.   style_1();//样式1
  30.   
  31. }
复制代码
上面代码的效果视频如下:



通过下载测试,发现第一段程序是led 1-6逐个点亮,然后从6-1再逐个熄灭如此循环。
第二段程序是6个灯同时亮,然后再6-1逐个熄灭如此循环。下面对产生不同效果的代码进行分析。
下面这段代码代表的for语句循环的是,是把j点亮,然后再延迟200毫秒,然后再循环。形成的效果就是6个灯相隔200毫秒逐步被点亮。
  1.   for(j=1;j<=6;j++)
  2.   {
  3.     digitalWrite(j,HIGH);
  4.     delay(200);
  5.   }
复制代码
下面这段代码其实是不规范写法,for命令表达要求一定要有{}循环,如果没有标出{},编译时就会自动对下一句加上{}。如果代码量很大,出问题是查找起来会非常辛苦。
  1. //设置控制Led的数字IO脚
  2. int Led1 = 1;
  3. int Led2 = 2;
  4. int Led3 = 3;
  5. int Led4 = 4;
  6. int Led5 = 5;
  7. int Led6 = 6;
  8. //led灯花样显示样式1子程序
  9. void style_1(void)
  10. {
  11.   unsigned char j;
  12.   for(j=1;j<=6;j++)
  13.   {
  14.     digitalWrite(j,HIGH);
  15.     delay(200);
  16.   }
  17.   for(j=6;j>=1;j--)
  18.   {
  19.     digitalWrite(j,LOW);
  20.     delay(200);
  21.   }
  22. }
  23. void setup()
  24. {
  25.   unsigned char i;
  26.   for(i=1;i<=6;i++)//依次设置1~6个数字引脚为输出模式
  27.     pinMode(i,OUTPUT);//设置第i个引脚为输出模式
  28. }
  29. void loop()
  30. {   
  31.   style_1();//样式1
  32.   
  33. }
复制代码
六个灯逐个被点亮,然后再延时200毫秒进入下一句。因为六灯逐个点亮的速度非常快,所以看上去像一起亮的。

void(无类型)在arduino中是数据类型的一种,通常用来代表一个事件。如果控制过程比较简单void一般无需定义,直接使用
  1. void setup()
  2. {
  3.   // ...
  4. }

  5. void loop()
  6. {
  7.   // ...
  8. }
复制代码
代表事件的开始与事件的循环。

如果控制过程比较复杂,一般就要设置多个子事件,把复杂的过程进行分解,每一个子事件定义为一个void数据。

把以下代码上传上去,看看led灯是如何工作的。
  1. //设置控制Led的数字IO脚
  2. int Led1 = 1;
  3. int Led2 = 2;
  4. int Led3 = 3;
  5. int Led4 = 4;
  6. int Led5 = 5;
  7. int Led6 = 6;
  8. //led灯花样显示样式1子程序
  9. void style_1(void)
  10. {
  11.   unsigned char j;
  12.   for(j=1;j<=6;j++)//每隔200ms依次点亮1~6引脚相连的led灯
  13.   {
  14.     digitalWrite(j,HIGH);//点亮j引脚相连的led灯
  15.     delay(200);//延时200ms
  16.   }
  17.   for(j=6;j>=1;j--)//每隔200ms依次熄灭6~1引脚相连的led灯
  18.   {
  19.     digitalWrite(j,LOW);//熄灭j引脚相连的led灯
  20.     delay(200);//延时200ms
  21.   }
  22. }
  23. //灯闪烁子程序
  24. void flash(void)
  25. {   
  26.   unsigned char j,k;
  27.   for(k=0;k<=1;k++)//闪烁两次
  28.   {
  29.     for(j=1;j<=6;j++)//点亮1~6引脚相连的led灯
  30.       digitalWrite(j,HIGH);//点亮与j引脚相连的led灯
  31.     delay(200);//延时200ms
  32.     for(j=1;j<=6;j++)//熄灭1~6引脚相连的led灯
  33.       digitalWrite(j,LOW);//熄灭与j引脚相连的led灯
  34.     delay(200);//延时200ms
  35.   }
  36. }
  37. //led灯花样显示样式2子程序
  38. void style_2(void)
  39. {
  40.   unsigned char j,k;
  41.   k=1;//设置k的初值为1
  42.   for(j=3;j>=1;j--)
  43.   {   
  44.     digitalWrite(j,HIGH);//点亮灯
  45.     digitalWrite(j+k,HIGH);//点亮灯
  46.     delay(400);//延时400ms
  47.     k +=2;//k值加2
  48.   }
  49.   k=5;//设置k值为5
  50.   for(j=1;j<=3;j++)
  51.   {
  52.     digitalWrite(j,LOW);//熄灭灯
  53.     digitalWrite(j+k,LOW);//熄灭灯
  54.     delay(400);//延时400ms
  55.     k -=2;//k值减2
  56.   }
  57. }
  58. //led灯花样显示样式3子程序
  59. void style_3(void)
  60. {
  61.   unsigned char j,k;//led灯花样显示样式3子程序
  62.   k=5;//设置k值为5
  63.   for(j=1;j<=3;j++)
  64.   {
  65.     digitalWrite(j,HIGH);//点亮灯
  66.     digitalWrite(j+k,HIGH);//点亮灯
  67.     delay(400);//延时400ms
  68.     digitalWrite(j,LOW);//熄灭灯
  69.     digitalWrite(j+k,LOW);//熄灭灯
  70.     k -=2;//k值减2
  71.   }
  72.   k=3;//设置k值为3
  73.   for(j=2;j>=1;j--)
  74.   {   
  75.     digitalWrite(j,HIGH);//点亮灯
  76.     digitalWrite(j+k,HIGH);//点亮灯
  77.     delay(400);//延时400ms
  78.     digitalWrite(j,LOW);//熄灭灯
  79.     digitalWrite(j+k,LOW);//熄灭灯
  80.     k +=2;//k值加2
  81.   }
  82. }
  83. void setup()
  84. {
  85.   unsigned char i;
  86.   for(i=1;i<=6;i++)//依次设置1~6个数字引脚为输出模式
  87.     pinMode(i,OUTPUT);//设置第i个引脚为输出模式
  88. }
  89. void loop()
  90. {   
  91.   style_1();//样式1
  92.   flash();//闪烁
  93.   style_2();//样式2
  94.   flash();//闪烁
  95.   style_3();//样式3
  96.   flash();//闪烁
  97. }
复制代码
上面这段代码的效果视频如下:


上面的代码分为4个子事件,样式1,样式2,样式3和闪烁。

闪烁:1-6号灯亮,延时200ms,1-6号灯熄灭,延时200ms。效果视频如下:




样式1:1-6号灯逐个点亮,然后6-1逐个熄灭。效果视频如下:



样式2:3,4号灯先亮,然后2,5号再亮,最后1,6号两。接着1,6号灯熄灭,再2,5号熄灭,最后3,4号熄灭。效果视频如下:



样式三:3,4号灯亮,然后3,4号熄灭2,5号亮,然后2,5号熄灭1,6号亮,再1,6号熄灭2,5号亮,最后2,5号熄灭3,4号亮。效果视频如下:



通过以上4种事件的组合,就可以做出来各种效果。
回复

使用道具 举报

 楼主| 发表于 2011-7-1 14:47:40 | 显示全部楼层
偶是谁 发表于 2011-7-1 13:11
//灯闪烁子程序

void flash(void)
  1. //灯闪烁子程序
  2. void flash(void)
  3. {   
  4.   unsigned char j,k;
  5.   for(k=0;k<=1;k++)//闪烁两次
  6.   {
  7.     for(j=1;j<=6;j++)//点亮1~6引脚相连的led灯
  8.       digitalWrite(j,HIGH);//点亮与j引脚相连的led灯
  9.     delay(200);//延时200ms
  10.     for(j=1;j<=6;j++)//熄灭1~6引脚相连的led灯
  11.       digitalWrite(j,LOW);//熄灭与j引脚相连的led灯
  12.     delay(200);//延时200ms
  13.   }
  14. }
复制代码
unsigned char j,k;//这一句对j与k进行了定义,代表了j与k是无符号字符,两者完全独立,无关系。

for(k=0;k<=1;k++)//闪烁两次,这一for语句设置了循环2次。

for(j=1;j<=6;j++)//点亮1~6引脚相连的led灯  问:为什么这里不是每隔
200ms依次点亮1~6引脚相连的led灯。答:如果设置每隔200ms依次点亮,就无法达到闪烁的效果。200ms肉眼是可以分辨的,那样肉眼看到的效果就是1-6号灯逐个点亮。
回复 支持 1 反对 0

使用道具 举报

发表于 2011-6-29 17:49:18 | 显示全部楼层
unsigned char j,k;不懂,求解
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-6-29 18:27:05 | 显示全部楼层
偶是谁 发表于 2011-6-29 17:49
unsigned char j,k;不懂,求解

unsigned char是数据类型的一种,表示无符号字符。
unsigned char j,k;就是对j和k进行数据类型的定义。
回复 支持 反对

使用道具 举报

发表于 2011-7-1 13:11:03 | 显示全部楼层
  1. //灯闪烁子程序

  2. void flash(void)

  3. {   

  4.   unsigned char j,k;

  5.   for(k=0;k<=1;k++)//闪烁两次   问:k是什么,为什么不用定义,
  6. j ,k是什么关系,单片机是怎么认定闪烁两次

  7.   {

  8.     for(j=1;j<=6;j++)//点亮1~6引脚相连的led灯  问:为什么这里不是每隔
  9. 200ms依次点亮1~6引脚相连的led灯

  10.       digitalWrite(j,HIGH);//点亮与j引脚相连的led灯

  11.     delay(200);//延时200ms

  12.     for(j=1;j<=6;j++)//熄灭1~6引脚相连的led灯

  13.       digitalWrite(j,LOW);//熄灭与j引脚相连的led灯

  14.     delay(200);//延时200ms

  15.   }

  16. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2011-7-1 19:18:10 | 显示全部楼层
定义K的目的是执行下面程序 ,执行两次吗
好像懂了一点,主要是没看清大括号
问:像流水灯程序二三例, 执行过程中,如何实现端口置低,
例如实现34,2516灯亮后,全熄灭,延时200ms,再34,25,16灯亮,可以任意端口置低吗
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-7-1 20:27:10 | 显示全部楼层
偶是谁 发表于 2011-7-1 19:18
定义K的目的是执行下面程序 ,执行两次吗
好像懂了一点,主要是没看清大括号
问:像流水灯程序二三例, 执 ...

是的,定义k的目的就是为了做计数,起执行2次的计数作用。
如何实现,34,25,16灯亮后,全熄灭,延时200ms,再34,25,16灯亮。
这个效果的代码看下面,一起熄灭是通过for(j=1;j<=6;j++)这个语句来选择端口.
  1. //led灯花样显示样式2子程序
  2. void style_2(void)
  3. {
  4.   unsigned char j,k;
  5.   k=1;//设置k的初值为1
  6.   for(j=3;j>=1;j--)
  7.   {   
  8.     digitalWrite(j,HIGH);//点亮灯
  9.     digitalWrite(j+k,HIGH);//点亮灯
  10.     delay(400);//延时400ms
  11.     k +=2;//k值加2
  12.   }
  13.   
  14.   for(j=1;j<=6;j++)  {
  15.     digitalWrite(j,LOW);//熄灭1~6引脚相连的led灯,因为不设置延时,虽然是逐个熄灭,但是肉眼所见基本是同时熄灭。
  16.   }
  17.     delay(200);
  18. }

  19. void setup()
  20. {
  21.   unsigned char i;
  22.   for(i=1;i<=6;i++)//依次设置1~6个数字引脚为输出模式
  23.     pinMode(i,OUTPUT);//设置第i个引脚为输出模式
  24. }
  25. void loop()
  26. {   
  27.     style_2();//样式

  28. }
复制代码
可以任意端口LOW,和上面的代码效果一样,你看看下面的写法。这样子就很明白怎样任意端口LOW了。
  1. //led灯花样显示样式2子程序
  2. void style_2(void)
  3. {
  4.   unsigned char j,k,;
  5.   k=1;//设置k的初值为1
  6.   for(j=3;j>=1;j--)
  7.   {   
  8.     digitalWrite(j,HIGH);//点亮灯
  9.     digitalWrite(j+k,HIGH);//点亮灯
  10.     delay(400);//延时400ms
  11.     k +=2;//k值加2
  12.   }
  13.     digitalWrite(1,LOW);//熄灭1号引脚相连的led灯,下面5个端口同理
  14.     digitalWrite(2,LOW);
  15.     digitalWrite(3,LOW);
  16.     digitalWrite(4,LOW);
  17.     digitalWrite(5,LOW);
  18.     digitalWrite(6,LOW);
  19.     delay(200);
  20. }

  21. void setup()
  22. {
  23.   unsigned char i;
  24.   for(i=1;i<=6;i++)//依次设置1~6个数字引脚为输出模式
  25.     pinMode(i,OUTPUT);//设置第i个引脚为输出模式
  26. }
  27. void loop()
  28. {   
  29.     style_2();//样式

  30. }
复制代码
下面的代码作用是熄灭1-6号灯

  1.     digitalWrite(1,LOW);//熄灭1号引脚相连的led灯,下面5个端口同理
  2.     digitalWrite(2,LOW);
  3.     digitalWrite(3,LOW);
  4.     digitalWrite(4,LOW);
  5.     digitalWrite(5,LOW);
  6.     digitalWrite(6,LOW);
复制代码
这样子的代码也可以直接操作各个灯的开关的,只不过这种方法是土办法。。。一个个来,而不是通过精密的数学算法来进行开关。

可以使用数学算法的地方,尽量使用数学算法,这样锻炼下来,编程的质量会提高很快。
回复 支持 反对

使用道具 举报

发表于 2011-7-3 19:00:07 | 显示全部楼层
可不可以加入开关控制流水灯的程序
例如:1  按一下按钮实现单个LED  1-6位移
      2   按一下按钮实现1,2,3,程序流水灯转换
      3  3个按钮分别控制3个流水灯工作程序转换
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-7-3 19:02:24 | 显示全部楼层
偶是谁 发表于 2011-7-3 19:00
可不可以加入开关控制流水灯的程序
例如:1  按一下按钮实现单个LED  1-6位移
      2   按一下按钮实现1 ...


都可以实现,第五节我就会写开关控制的教程~~~~^_^估计周二就能写出来。
回复 支持 反对

使用道具 举报

发表于 2011-7-6 18:02:15 | 显示全部楼层
强烈期待老师课程
回复 支持 反对

使用道具 举报

发表于 2011-10-23 20:46:46 | 显示全部楼层
板子上不是有3.3v的端口么,那头作输入电压,0-5的pin设置为LOW就不行了咩,还省下6个电阻!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-10-24 10:30:39 | 显示全部楼层
niudwd 发表于 2011-10-23 20:46
板子上不是有3.3v的端口么,那头作输入电压,0-5的pin设置为LOW就不行了咩,还省下6个电阻!


不仅仅是电压。。。。主要是电流问题,没有限流电阻,电流就会过载。
回复 支持 反对

使用道具 举报

发表于 2011-12-25 10:44:13 | 显示全部楼层
void setup()
void loop()
请问楼主,arduino的代码中是怎么个执行过程?
是先执行setup里的设置吗?loop是主程序函数吗?
不用main吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-12-25 11:44:04 | 显示全部楼层
jkiu003 发表于 2011-12-25 10:44
void setup()
void loop()
请问楼主,arduino的代码中是怎么个执行过程?


setup()是执行完#define等进行执行的,排行第二。

loop()是循环,在setup()之后,排行第三。

loop()是主程序函数~

arduino中里面没用使用main~~~
回复 支持 反对

使用道具 举报

发表于 2012-2-5 03:42:37 | 显示全部楼层
led的连接最好是正极接5v,负极接IO口,毕竟328的IO口提供的电流有限
不然的话当LED个数过多会导致arduino重启的。。
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊 ( 浙ICP备09023225号 )

GMT+8, 2020-1-21 00:06 , Processed in 0.063258 second(s), 33 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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