极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 103748|回复: 32

arduino学习笔记8 - 数字骰子实验

  [复制链接]
发表于 2011-7-14 20:01:02 | 显示全部楼层 |阅读模式

前几次做了数码管实验和按键控制LED的实验,通过实验大家已经学会了两种器件的基本用法。这次使用数码管与按键进行组合,做一个简易数字骰子。
数字筛子的基本原理是数码管快速在1-8之间循环跳动,当按下按键时,数码管定格在当前的数字上,不再跳动。

先看一下接线图




  1. //设置控制各段的数字IO脚
  2. int a=7;
  3. int b=6;
  4. int c=5;
  5. int d=11;
  6. int e=10;
  7. int f=8;
  8. int g=9;
  9. int dp=4;

  10. //显示数字1
  11. void digital_1(void)
  12. {
  13.   unsigned char j;
  14.   digitalWrite(c,LOW);//给数字5引脚低电平,点亮c段
  15.   digitalWrite(b,LOW);//点亮b段
  16.   for(j=7;j<=11;j++)//熄灭其余段
  17.     digitalWrite(j,HIGH);
  18.   digitalWrite(dp,HIGH);//熄灭小数点DP段
  19. }
  20. //显示数字2
  21. void digital_2(void)
  22. {
  23.   unsigned char j;
  24.   digitalWrite(b,LOW);
  25.   digitalWrite(a,LOW);
  26.   for(j=9;j<=11;j++)
  27.     digitalWrite(j,LOW);
  28.   digitalWrite(dp,HIGH);
  29.   digitalWrite(c,HIGH);
  30.   digitalWrite(f,HIGH);
  31. }
  32. //显示数字3
  33. void digital_3(void)
  34. {
  35.   unsigned char j;
  36.   digitalWrite(g,LOW);
  37.   digitalWrite(d,LOW);
  38.   for(j=5;j<=7;j++)
  39.     digitalWrite(j,LOW);
  40.   digitalWrite(dp,HIGH);
  41.   digitalWrite(f,HIGH);
  42.   digitalWrite(e,HIGH);
  43. }
  44. //显示数字4
  45. void digital_4(void)
  46. {
  47.   digitalWrite(c,LOW);
  48.   digitalWrite(b,LOW);
  49.   digitalWrite(f,LOW);
  50.   digitalWrite(g,LOW);
  51.   digitalWrite(dp,HIGH);
  52.   digitalWrite(a,HIGH);
  53.   digitalWrite(e,HIGH);
  54.   digitalWrite(d,HIGH);   
  55. }
  56. //显示数字5
  57. void digital_5(void)
  58. {
  59.   unsigned char j;
  60.   for(j=7;j<=9;j++)
  61.     digitalWrite(j,LOW);
  62.   digitalWrite(c,LOW);
  63.   digitalWrite(d,LOW);
  64.   digitalWrite(dp,HIGH);
  65.   digitalWrite(b,HIGH);
  66.   digitalWrite(e,HIGH);
  67. }
  68. //显示数字6
  69. void digital_6(void)
  70. {
  71.   unsigned char j;
  72.   for(j=7;j<=11;j++)
  73.     digitalWrite(j,LOW);
  74.   digitalWrite(c,LOW);
  75.   digitalWrite(dp,HIGH);
  76.   digitalWrite(b,HIGH);   
  77. }
  78. //显示数字7
  79. void digital_7(void)
  80. {
  81.   unsigned char j;
  82.   for(j=5;j<=7;j++)
  83.     digitalWrite(j,LOW);
  84.   digitalWrite(dp,HIGH);
  85.   for(j=8;j<=11;j++)
  86.     digitalWrite(j,HIGH);
  87. }
  88. //显示数字8
  89. void digital_8(void)
  90. {
  91.   unsigned char j;
  92.   for(j=5;j<=11;j++)
  93.     digitalWrite(j,LOW);
  94.   digitalWrite(dp,HIGH);
  95. }
  96. void setup()
  97. {
  98.     int i;
  99.     for(i=4;i<=11;i++)
  100.     {
  101.     pinMode(i,OUTPUT);//设置4~11口为输出模式
  102.     }
  103. }
  104. void loop()
  105. {  
  106.    while(1)
  107.    {
  108.        digital_1();//显示数字1
  109.        while(analogRead(0)>1000);//如果读到模拟0口的值1000则说明有按键按下
  110.        delay(100);//延时100ms
  111.         digital_2();
  112.         while(analogRead(0)>1000);
  113.        delay(100);
  114.         digital_3();
  115.         while(analogRead(0)>1000);
  116.        delay(100);
  117.         digital_4();
  118.         while(analogRead(0)>1000);
  119.        delay(100);
  120.         digital_5();
  121.         while(analogRead(0)>1000);
  122.        delay(100);
  123.         digital_6();
  124.         while(analogRead(0)>1000);
  125.        delay(100);
  126.         digital_7();
  127.         while(analogRead(0)>1000);
  128.        delay(100);
  129.         digital_8();
  130.         while(analogRead(0)>1000);
  131.        delay(100);
  132.    }
  133. }
复制代码
实验的效果如下

本帖子中包含更多资源

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

x
回复

使用道具 举报

发表于 2011-12-23 16:30:09 | 显示全部楼层
  1. int button=0; //定义按钮

  2. byte seven_seg_digits[10][8] = {    //设置每个数字所对应的开关数组

  3.   { 1,0,0,0,0,1,0,0 },  // = 0

  4.   { 1,0,0,1,1,1,1,1 },  // = 1

  5.   { 1,1,0,0,1,0,0,0 },  // = 2

  6.   { 1,0,0,0,1,0,1,0 },  // = 3

  7.   { 1,0,0,1,0,0,1,1 },  // = 4

  8.   { 1,0,1,0,0,0,1,0 },  // = 5

  9.   { 1,0,1,0,0,0,0,0 },  // = 6

  10.   { 1,0,0,0,1,1,1,1 },  // = 7

  11.   { 1,0,0,0,0,0,0,0 },  // = 8

  12.   { 1,0,0,0,0,0,1,0 }   // = 9

  13.   };


  14. void setup() {                //4-11号端口设定为输出模式
  15.   int i;//定义变量
  16.   for(i=4;i<=11;i++)
  17.     pinMode(i,OUTPUT);//设置4~11引脚为输出模式
  18. }

  19.    

  20. void sevenSegWrite(byte digit) {  //设置通过数组控制引脚开关,顺序为4-11号端口

  21.   byte pin = 4;

  22.   for (byte segCount = 0; segCount < 8; ++segCount) {

  23.     digitalWrite(pin, seven_seg_digits[digit][segCount]);

  24.     ++pin;

  25.   }

  26. }


  27. void loop() {   //设置显示效果为从9开始倒数

  28.   for (byte count = 10; count > 0; --count) {

  29.    delay(100);

  30.    sevenSegWrite(count - 1);
  31.    while(analogRead(button)>1000); //如果按键则暂停

  32.   }

  33.   delay(100);

  34. }
复制代码

评分

参与人数 1 +30 收起 理由
Ansifa + 30 嘿嘿

查看全部评分

回复 支持 反对

使用道具 举报

发表于 2012-1-16 23:19:20 | 显示全部楼层
107行:  delay(100);//延时200ms

应该是100ms吧???
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-1-16 23:34:44 | 显示全部楼层
Jacky 发表于 2012-1-16 23:19
107行:  delay(100);//延时200ms

应该是100ms吧???

是100ms,现在改正过来了
回复 支持 反对

使用道具 举报

发表于 2012-2-10 16:41:32 | 显示全部楼层
上面是按住开关数字停止,有没有可能按一下开关数字停止,再按一下数字接着跳动,我自己试了很多次,可还是不会。下面是我的代码:
  1. void loop()
  2. {
  3.   rad();  //随机显示数字
  4. while(analogRead(5)>1000) //当开关按下时
  5. {
  6.     onoff = !onoff;  //停止标志,true时停止,false时跳动
  7.    if(on)  //若on 为true
  8.     {
  9.      while(analogRead(5) < 1000) ; //当读取值小于1000时,保持停止状态,一旦读取值>1000则跳出while循环
  10.    }
  11.     break;  //跳出外层while循环,更新数字
  12.   }
  13.   delay(1000);  //延迟1s
  14. }
复制代码
下载到板上结果不对。
恳请lz帮帮忙。

我的想法是需要两个线程,一个实时检测开关是否按下,一个控制数字不断跳动,可不知道怎么做到。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-2-10 16:55:55 | 显示全部楼层
这个按键实验中,有按一下开始,按一下停止的代码,你把里面的这个代码和数码管的结合一下,就ok了

http://www.geek-workshop.com/forum.php?mod=viewthread&tid=74
回复 支持 反对

使用道具 举报

发表于 2012-2-10 20:49:03 | 显示全部楼层
弘毅 发表于 2012-2-10 16:55
这个按键实验中,有按一下开始,按一下停止的代码,你把里面的这个代码和数码管的结合一下,就ok了

http ...


这是后来写的:
  1. int led = 13;
  2. int Button = 11;
  3. boolean on = LOW;
  4. long randNumber;
  5. int pin[] = {1,2,4,5,6,7,9,10};
  6. int digit[16][8]={
  7.   {1,1,1,0,1,1,1,0},
  8.   {0,0,1,0,1,0,0,0},
  9.   {1,1,0,0,1,1,0,1},
  10.   {0,1,1,0,1,1,0,1},
  11.   {0,0,1,0,1,0,1,1},
  12.   {0,1,1,0,0,1,1,1},
  13.   {1,1,1,0,0,1,1,1},
  14.   {0,0,1,0,1,1,0,0},
  15.   {1,1,1,0,1,1,1,1},
  16.   {0,1,1,0,1,1,1,1}
  17. };
  18. void setup()
  19. {
  20.   pinMode(Button, INPUT);
  21.   pinMode(led, OUTPUT);
  22.   for(int i = 0; i < 8; i++)
  23.   {
  24.     pinMode(pin[i], OUTPUT);
  25.   }
  26. }

  27. void rad()   //随机产生0-9
  28. {
  29.   randNumber = random(0,10);
  30.   for(int j = 0; j < 8; j++)
  31.   {
  32.     if(digit[randNumber][j] == 1)
  33.     digitalWrite(pin[j], HIGH);
  34.     else
  35.     digitalWrite(pin[j], LOW);
  36.   }
  37. }
  38. void loop()
  39. {
  40.   if(digitalRead(Button) == LOW)  //第一个if——if_1
  41.   {
  42.      delay(10);  //第一个delay——delay_1
  43.      if(digitalRead(Button) == HIGH)  //第二个if——if_2
  44.      {
  45.        digitalWrite(led, on);
  46.        on = !on;
  47.        delay(10);  //第二个delay——delay_2
  48.        while(digitalRead(Button) == HIGH)
  49.        {
  50.          delay(1);
  51.        }
  52.      }
  53.      if(on == HIGH) //if_3
  54.      {
  55.        rad();
  56.        delay(10);   //第三个delay——delay_3。当delay_3取0或者很小的值时,反应正常,但取50及更大时则按键没效果即无论怎么按,数字都不会停止跳动,而且led13也不会亮。
  57.      }
  58.   }
  59. }
复制代码
我的分析是这样的:
当delay_3=0时,数码管急速地变化,即整个loop执行地很快,由delay_1知道每隔10ms就检查一次有没有上升沿;而当delay_3取50或者更大的值时,delay_3这段时间的比重就占得很大,倘若在这段时间按下开关,就不能检查到有上升沿事件,进而跳过if_2继续执行if_3。
我在做实验时发现,当delay_3越小,按键灵敏度越高。当delay_3取50时,偶尔还能改变一下on的值,即使数字停止跳动,当取500时,按键就完全没反应了,数字始终按照510ms的频率跳动,led始终灭(led亮时说明数字停止跳动)。

所以想问问lz和各位高手,有没有办法使delay_3想设多大就设多大。
回复 支持 反对

使用道具 举报

发表于 2012-4-14 17:04:34 | 显示全部楼层
不错,小白学习了~
回复 支持 反对

使用道具 举报

发表于 2012-5-9 00:29:14 | 显示全部楼层
请问不能像51那样用一个P1或P2口这样给一个16进制的数去定义吗,版主一个个设,很麻烦
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-5-9 07:53:26 | 显示全部楼层
自由创客 发表于 2012-5-9 00:29
请问不能像51那样用一个P1或P2口这样给一个16进制的数去定义吗,版主一个个设,很麻烦

可以滴。。。可以参照这个帖子
http://www.geek-workshop.com/forum.php?mod=viewthread&tid=389
回复 支持 反对

使用道具 举报

发表于 2012-11-22 03:44:33 | 显示全部楼层
我是个初学者这个代码在arduino uno板卡上用吗?还是说我没有设置好 怎么数码管没反应呀?求教  急!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-11-22 09:43:07 | 显示全部楼层
colonne 发表于 2012-11-22 03:44
我是个初学者这个代码在arduino uno板卡上用吗?还是说我没有设置好 怎么数码管没反应呀?求教  急!


uno可用,数码管分共阴和共阳,不知道你的和帖子里使用的是不是一个型号的。
回复 支持 反对

使用道具 举报

发表于 2013-2-15 16:00:47 | 显示全部楼层
按键不用消抖么?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-2-17 16:00:15 | 显示全部楼层
低调、人生 发表于 2013-2-15 16:00
按键不用消抖么?

如果使用起来有抖动还是需要消抖的。。。如果使用起来没异常,不用消抖也没事。
回复 支持 反对

使用道具 举报

发表于 2013-2-17 21:04:48 | 显示全部楼层
弘毅 发表于 2013-2-17 16:00
如果使用起来有抖动还是需要消抖的。。。如果使用起来没异常,不用消抖也没事。

但目前为止,我用的按键都需要消抖的啊
回复 支持 反对

使用道具 举报

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

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

Archiver|联系我们|极客工坊

GMT+8, 2024-4-25 16:17 , Processed in 0.067299 second(s), 30 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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