极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 20540|回复: 6

数字骰子——如何实现按一下数字跳动,再按一下停止跳动的效果

[复制链接]
发表于 2012-2-12 10:50:38 | 显示全部楼层 |阅读模式
原数字骰子的实验
http://www.geek-workshop.com/forum.php?mod=viewthread&tid=76
它实现的效果是:按住开关数字停止跳动,不按则继续跳动。
而我想实现的效果是按一下数字停止跳动,再按一下则接着跳动(即每个一定时间换一个数字显示)的效果。
用到了按键实验http://www.geek-workshop.com/forum.php?mod=viewthread&tid=74的后半部分。
这是我改的代码:
int led = 13; //led灯指示数字是否应该停止跳动
int Button = 11;
boolean on = LOW;
long randNumber;
int pin[] = {1,2,4,5,6,7,9,10};  //用到的是1,2,4,5,6,7,9,10端口,与数码管的端口一一对应
int digit[16][8]={   
   {1,1,1,0,1,1,1,0},  //0
   {0,0,1,0,1,0,0,0},  //1
   {1,1,0,0,1,1,0,1},  //2
   {0,1,1,0,1,1,0,1},  //3
   {0,0,1,0,1,0,1,1},  //4
   {0,1,1,0,0,1,1,1},  //5
   {1,1,1,0,0,1,1,1},  //6
   {0,0,1,0,1,1,0,0},  //7
   {1,1,1,0,1,1,1,1},  //8
   {0,1,1,0,1,1,1,1}   //9
};
void setup()
{
   pinMode(Button, INPUT);
   pinMode(led, OUTPUT);
   for(int i = 0; i < 8; i++)
   {
     pinMode(pin, OUTPUT);
   }
}

void rad()   //随机显示0-9的函数
{
   randNumber = random(0,10);
   for(int j = 0; j < 8; j++)
   {
     if(digit[randNumber][j] == 1)
     digitalWrite(pin[j], HIGH);
     else
     digitalWrite(pin[j], LOW);
   }
}
void loop()
{
   if(digitalRead(Button) == LOW)  //第一个if——if_1
   {
      delay(10);  //第一个delay——delay_1
      if(digitalRead(Button) == HIGH)  //第二个if——if_2
      {
        digitalWrite(led, on);
        on = !on;
        delay(10);  //第二个delay——delay_2
        while(digitalRead(Button) == HIGH)
        {
          delay(1);
        }
      }
      if(on == HIGH) //if_3
      {
        rad();
        delay(10);   //第三个delay——delay_3。
      }
   }
}
经测试发现:当delay_3取0或者很小的值时,可以达到效果,但取50及更大时则按键即无论怎么按,数字都不会停止跳动,而且led13也不会亮。

我的分析是这样的:
    当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亮时说明数字停止跳动)。

所以想问问各位同学,有没有办法使delay_3想设多大就设多大。谢谢了。

回复

使用道具 举报

发表于 2012-2-12 12:50:12 | 显示全部楼层
可以尝试使用arduino的中断来进行处理这个问题
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-2-12 22:19:03 | 显示全部楼层
void attachInterrupt  ( uint8_t  interruptNum,  
  void(*)(void)  userFunc,  
  int  mode   
)   
触发方式:
LOW 低电平触发中断
CHANGE 变化时触发中断
RISING 低电平变为高电平触发中断
FALLING 高电平变为低电平触发中断
是指interruptNum端口的变化吗?
外部中断是什么意思?
回复 支持 反对

使用道具 举报

发表于 2012-2-13 11:59:20 | 显示全部楼层
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-2-13 12:49:59 | 显示全部楼层
Ansifa 发表于 2012-2-13 11:59
看看这个http://www.geek-workshop.com/forum.php?mod=viewthread&tid=389

这个也是按住开关停止,我想实现的是按一下停止,按一下继续。
谢了。
回复 支持 反对

使用道具 举报

发表于 2012-2-13 13:26:01 | 显示全部楼层
树·水·风 发表于 2012-2-13 12:49
这个也是按住开关停止,我想实现的是按一下停止,按一下继续。
谢了。

改一下按钮响应就行啦,数码管部分不用变。。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-2-14 18:04:36 | 显示全部楼层
弘毅 发表于 2012-2-12 12:50
可以尝试使用arduino的中断来进行处理这个问题
  1. int led = 13;
  2. volatile int state = LOW;
  3. long randNumber;
  4. int pin[] = {1,2,4,5,6,7,9,10};
  5. int digit[16][8]={
  6.   {1,1,1,0,1,1,1,0},
  7.   {0,0,1,0,1,0,0,0},
  8.   {1,1,0,0,1,1,0,1},
  9.   {0,1,1,0,1,1,0,1},
  10.   {0,0,1,0,1,0,1,1},
  11.   {0,1,1,0,0,1,1,1},
  12.   {1,1,1,0,0,1,1,1},
  13.   {0,0,1,0,1,1,0,0},
  14.   {1,1,1,0,1,1,1,1},
  15.   {0,1,1,0,1,1,1,1}
  16. };

  17. void setup()
  18. {
  19.   pinMode(led, OUTPUT);
  20.   for(int i = 0; i < 8; i++)
  21.   {
  22.     pinMode(pin[i], OUTPUT);
  23.   }
  24.   attachInterrupt(1, blink, RISING);
  25. }

  26. void rad()
  27. {
  28.   randNumber = random(0,10);
  29.   for(int j = 0; j < 8; j++)
  30.   {
  31.     if(digit[randNumber][j] == 1)
  32.     digitalWrite(pin[j], HIGH);
  33.     else
  34.     digitalWrite(pin[j], LOW);
  35.   }
  36. }

  37. void loop()
  38. {
  39.   digitalWrite(led, state);
  40.   if(state)
  41.   {
  42.     rad();
  43.     delay(500);
  44.   }
  45. }

  46. void blink()
  47. {
  48.   state = !state;
  49. }
复制代码
结合了一下中断的代码,已经可以了,谢谢哈。
回复 支持 反对

使用道具 举报

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

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

Archiver|联系我们|极客工坊

GMT+8, 2024-3-29 15:21 , Processed in 0.040685 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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