树·水·风 发表于 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={   
   {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 == 1)
   digitalWrite(pin, HIGH);
   else
   digitalWrite(pin, 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_tinterruptNum,
void(*)(void)userFunc,
intmode   
)   
触发方式:
LOW 低电平触发中断
CHANGE 变化时触发中断
RISING 低电平变为高电平触发中断
FALLING 高电平变为低电平触发中断
是指interruptNum端口的变化吗?
外部中断是什么意思?

Ansifa 发表于 2012-2-13 11:59:20

看看这个http://www.geek-workshop.com/forum.php?mod=viewthread&tid=389

树·水·风 发表于 2012-2-13 12:49:59

Ansifa 发表于 2012-2-13 11:59 static/image/common/back.gif
看看这个http://www.geek-workshop.com/forum.php?mod=viewthread&tid=389

这个也是按住开关停止,我想实现的是按一下停止,按一下继续。
谢了。

Ansifa 发表于 2012-2-13 13:26:01

树·水·风 发表于 2012-2-13 12:49 static/image/common/back.gif
这个也是按住开关停止,我想实现的是按一下停止,按一下继续。
谢了。

改一下按钮响应就行啦,数码管部分不用变。。

树·水·风 发表于 2012-2-14 18:04:36

弘毅 发表于 2012-2-12 12:50 static/image/common/back.gif
可以尝试使用arduino的中断来进行处理这个问题

int led = 13;
volatile int state = LOW;
long randNumber;
int pin[] = {1,2,4,5,6,7,9,10};
int digit={
{1,1,1,0,1,1,1,0},
{0,0,1,0,1,0,0,0},
{1,1,0,0,1,1,0,1},
{0,1,1,0,1,1,0,1},
{0,0,1,0,1,0,1,1},
{0,1,1,0,0,1,1,1},
{1,1,1,0,0,1,1,1},
{0,0,1,0,1,1,0,0},
{1,1,1,0,1,1,1,1},
{0,1,1,0,1,1,1,1}
};

void setup()
{
pinMode(led, OUTPUT);
for(int i = 0; i < 8; i++)
{
    pinMode(pin, OUTPUT);
}
attachInterrupt(1, blink, RISING);
}

void rad()
{
randNumber = random(0,10);
for(int j = 0; j < 8; j++)
{
    if(digit == 1)
    digitalWrite(pin, HIGH);
    else
    digitalWrite(pin, LOW);
}
}

void loop()
{
digitalWrite(led, state);
if(state)
{
    rad();
    delay(500);
}
}

void blink()
{
state = !state;
}
结合了一下中断的代码,已经可以了,谢谢哈。
页: [1]
查看完整版本: 数字骰子——如何实现按一下数字跳动,再按一下停止跳动的效果