FISHENDER 发表于 2014-2-15 18:31:23

单片机的程序语言编译有bug吗?为什么会这样

我想实现按四下按钮后灯才会亮,结果第一下就亮了,这个程序有问题吗,请大家明鉴!



int num=0;
void setup ()
{
pinMode(4,INPUT);               //将4号数字口设置为输入状态,13号数字口设置为输出状态
pinMode(13,OUTPUT);
}

void loop()
{
int n =digitalRead(4);                   //创建一个变量n,将4号数字口的状态采集出来赋值给他。
if (n==HIGH)                           //判断n是否为高电平,如果是执行下面的语句,不是则跳过。
{
    num++;
    num=0;                     
    if(num>5)
    for(int i=0;i<num;i++)
    {
    delay(1000);
    digitalWrite(13,HIGH);
    delay(50);
    digitalWrite(13,LOW);
    }
}
}

zoologist 发表于 2014-2-15 18:45:02

num++;
    num=0;   //重新赋值为0了,那下面的代码能跑到么?               
    if(num>5)
    for(int i=0;i<num;i++)
    {
    delay(1000);
    digitalWrite(13,HIGH);
    delay(50);
    digitalWrite(13,LOW);
    }

FISHENDER 发表于 2014-2-15 18:55:19

本帖最后由 FISHENDER 于 2014-2-15 18:56 编辑

不是不是,这个是后来加的,我试了下面的也不行,也是第一下就亮了,而且亮了6下,怎么可能第一下就自增到6了呢

我想实现按四下按钮后灯才会亮,结果第一下就亮了,这个程序有问题吗,请大家明鉴!



int num=0;
void setup ()
{
pinMode(4,INPUT);               //将4号数字口设置为输入状态,13号数字口设置为输出状态
pinMode(13,OUTPUT);
}

void loop()
{
int n =digitalRead(4);                   //创建一个变量n,将4号数字口的状态采集出来赋值给他。
if (n==HIGH)                           //判断n是否为高电平,如果是执行下面的语句,不是则跳过。
{
    num++;
    if(num>5)
    for(int i=0;i<num;i++)
    {
    delay(1000);
    digitalWrite(13,HIGH);
    delay(50);
    digitalWrite(13,LOW);
    }
}
}

zoologist 发表于 2014-2-15 19:15:38

你看,比如我按了一下,读取n=high (你确定按下是high么?)
很快执行一次,马上加一,然后又出来发现还是high(速度快啊)
所以会看到你的现象。

FISHENDER 发表于 2014-2-15 19:21:37

本帖最后由 FISHENDER 于 2014-2-15 21:11 编辑

zoologist 发表于 2014-2-15 19:15 static/image/common/back.gif
你看,比如我按了一下,读取n=high (你确定按下是high么?)
很快执行一次,马上加一,然后又出来发现还是h ...

哇塞,大师我明白了

zjhyhky 发表于 2014-2-15 19:51:15

检测到按下后要延时1秒,不然在你按下期间早就检测到好多次了

FISHENDER 发表于 2014-2-15 20:55:27

本帖最后由 FISHENDER 于 2014-2-15 21:08 编辑

zjhyhky 发表于 2014-2-15 19:51 static/image/common/back.gif
检测到按下后要延时1秒,不然在你按下期间早就检测到好多次了

我的解决方案是这样的

int num=0;
int a=0;
int b=0;
void setup ()
{
pinMode(4,INPUT);               //将4号数字口设置为输入状态,13号数字口设置为输出状态
pinMode(13,OUTPUT);
}

void loop()
{
int n =digitalRead(4);   //创建一个变量n,将4号数字口的状态采集出来赋值给他。


if(n==HIGH) a++;         //创建按下状态记录变量
if(n==LOW)b++;         //创建弹起状态记录变量
if (a*b!=0)                           //判断按键是否为按下后又弹起,如果是执行下面的语句,不是则跳过。
{
   
    num++;



   
   
      delay(140);
      
   
   
    if(num>10)
    {
   
    for(int i=0;;i++)
    {
    delay(50);
    digitalWrite(13,HIGH);
    delay(50);
    digitalWrite(13,LOW);
    }
   
    num=0;

    }
   

    a=0;
    b=0;
}
}


这样过后,的确可以比较准确的做到我预想的事,但是同时,如果你按键过慢,按不到规定的次数(比如5、6),就会提前点亮,但是按得快一点就按照规定的次数点亮,不知道为什么。

shihaipeng04 发表于 2014-2-15 22:24:51

好像4楼已经说明白了。就是按下的瞬间,程序已经循环了不知道多少次了。所以就亮了。
程序的思路是

检测按键状态,
记录按键状态,//中间适当加delay,因为按键触点接触刹那的游离状态可能会被检测为多次
直到按键放开,
计数1次,
循环,
直到计数到要多次数再 do

FISHENDER 发表于 2014-2-16 10:05:44

shihaipeng04 发表于 2014-2-15 22:24 static/image/common/back.gif
好像4楼已经说明白了。就是按下的瞬间,程序已经循环了不知道多少次了。所以就亮了。
程序的思路是



游离状态啊,原来如此,我发现我按键麻利点就会很准确。

shihaipeng04 发表于 2014-2-16 10:48:58

FISHENDER 发表于 2014-2-16 10:05
游离状态啊,原来如此,我发现我按键麻利点就会很准确。

其实和手动汽车的离合器一样,从断开到完全接触有一个过程,虽然非常非常短。

eddiewwm 发表于 2014-2-16 17:27:15

這個問題可參考Arduino範例 Examples>Digital>StateChangeDeTection 。
页: [1]
查看完整版本: 单片机的程序语言编译有bug吗?为什么会这样