极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 13264|回复: 10

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

[复制链接]
发表于 2014-2-15 18:31:23 | 显示全部楼层 |阅读模式
我想实现按四下按钮后灯才会亮,结果第一下就亮了,这个程序有问题吗,请大家明鉴!



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);
    }
}
}
回复

使用道具 举报

发表于 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);
    }
回复 支持 反对

使用道具 举报

 楼主| 发表于 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);
    }
}
}
回复 支持 反对

使用道具 举报

发表于 2014-2-15 19:15:38 | 显示全部楼层
你看,比如我按了一下,读取n=high (你确定按下是high么?)
很快执行一次,马上加一,然后又出来发现还是high(速度快啊)
所以会看到你的现象。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-2-15 19:21:37 | 显示全部楼层
本帖最后由 FISHENDER 于 2014-2-15 21:11 编辑
zoologist 发表于 2014-2-15 19:15
你看,比如我按了一下,读取n=high (你确定按下是high么?)
很快执行一次,马上加一,然后又出来发现还是h ...


哇塞,大师我明白了
回复 支持 反对

使用道具 举报

发表于 2014-2-15 19:51:15 | 显示全部楼层
检测到按下后要延时1秒,不然在你按下期间早就检测到好多次了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-2-15 20:55:27 | 显示全部楼层
本帖最后由 FISHENDER 于 2014-2-15 21:08 编辑
zjhyhky 发表于 2014-2-15 19:51
检测到按下后要延时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),就会提前点亮,但是按得快一点就按照规定的次数点亮,不知道为什么。
回复 支持 反对

使用道具 举报

发表于 2014-2-15 22:24:51 | 显示全部楼层
好像4楼已经说明白了。就是按下的瞬间,程序已经循环了不知道多少次了。所以就亮了。
程序的思路是

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

使用道具 举报

 楼主| 发表于 2014-2-16 10:05:44 | 显示全部楼层
shihaipeng04 发表于 2014-2-15 22:24
好像4楼已经说明白了。就是按下的瞬间,程序已经循环了不知道多少次了。所以就亮了。
程序的思路是

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

使用道具 举报

发表于 2014-2-16 10:48:58 来自手机 | 显示全部楼层
FISHENDER 发表于 2014-2-16 10:05
游离状态啊,原来如此,我发现我按键麻利点就会很准确。

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

使用道具 举报

发表于 2014-2-16 17:27:15 | 显示全部楼层
這個問題可參考Arduino範例 Examples>Digital>StateChangeDeTection 。
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-10 01:50 , Processed in 0.048341 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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