极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: yqfans

小白求助~ 按键控制LED,如何按一下松开,亮;按一下松开,闪烁;再按一下松开,灭。

[复制链接]
 楼主| 发表于 2015-2-24 18:00:47 | 显示全部楼层
本帖最后由 yqfans 于 2015-2-24 18:04 编辑
laofuz1024 发表于 2015-2-24 00:09
中断的知识,论坛里有好教程

http://www.geek-workshop.com/thread-1983-1-1.html


——————————————————————————

int ledpin=11;//定义数字11 接口
int inpin=7;//定义数字7 接口
volatile int state = LOW;
int a;

void setup()
{
pinMode(ledpin,OUTPUT);//定义小灯接口为输出接口

attachInterrupt(inpin, stateChange, CHANGE);// 监视中断输入引脚的变化

}
void loop()
{
   
if(a==4)  {
            a=1;
           }

    if ( a==1 ) {
               digitalWrite(ledpin,HIGH);
                }
    if ( a==2 ) {
               digitalWrite(ledpin, HIGH); //点亮小灯
               delay(1000); //延时1 秒
               digitalWrite(ledpin, LOW); //熄灭小灯
               delay(1000); // 延时1 秒
               }
    if ( a==3 ) {
               digitalWrite(ledpin,LOW);
                }
     
}

void stateChange()
{
  state = !state;
  a=a+1;  
}


——————————————————————————————分割线

上面是我看了中断教程后修改的程序,但结果没成功,按下按钮,没反应,我也看不出哪有问题。
我的思路是这样:设置中断引脚为inpin ,当inpin发生电平变化(按下按键),启动中断程序,将变量a赋值(a=a+1;),然后返回住程序,进行判断,执行相应语句;当inpin再次发生变化(再次按下按键),再次进入中断程序,(a=a+1);再次返回判断,执行语句,如此循环。。。
也不知道哪里写错了,求指点,谢谢
中断程序中(state = !state;)这句是的作用是什么,是条件判断?还是执行?不明白
回复 支持 反对

使用道具 举报

发表于 2015-2-24 18:11:48 | 显示全部楼层
loop里是不能有delay的。当a=2时,delay不停地运行。
闪烁部分请参考Arduino实例BlinkWithoutDelay
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-2-25 20:57:40 | 显示全部楼层
本帖最后由 yqfans 于 2015-2-25 21:03 编辑
smching 发表于 2015-2-24 18:11
loop里是不能有delay的。当a=2时,delay不停地运行。
闪烁部分请参考Arduino实例BlinkWithoutDelay


那不用这个语句要怎么闪?我看不懂BlinkWithoutDelay的例子,难道一个简单的闪烁也要那么复杂么?
不过这个确实如你所说,好像Delay在1000上,都是不停的运行。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-2-25 21:05:56 | 显示全部楼层
现在这个程序被卡了好几天了,自己实在是搞不出程序来,有大神帮的修改下我的程序么?或者按要求用你的方式写也行,我对编程基本一窍不通的属于{:soso_e141:}
回复 支持 反对

使用道具 举报

发表于 2015-2-25 22:03:53 | 显示全部楼层
yqfans 发表于 2015-2-25 20:57
那不用这个语句要怎么闪?我看不懂BlinkWithoutDelay的例子,难道一个简单的闪烁也要那么复杂么?
不过 ...

你是参考这个例子吗?
  1.   unsigned long currentMillis = millis();

  2.   if(currentMillis - previousMillis > interval) {
  3.     // save the last time you blinked the LED
  4.     previousMillis = currentMillis;   

  5.     // if the LED is off turn it on and vice-versa:
  6.     if (ledState == LOW)
  7.       ledState = HIGH;
  8.     else
  9.       ledState = LOW;

  10.     // set the LED with the ledState of the variable:
  11.     digitalWrite(ledPin, ledState);
  12.   }
复制代码


也不是很难,你只需将下面代码编写在前段,然后把上面代码置在if ( a==2 ) {。。。}之间
  1. const int ledPin =  13;      // the number of the LED pin

  2. // Variables will change:
  3. int ledState = LOW;             // ledState used to set the LED
  4. long previousMillis = 0;        // will store last time LED was updated

  5. // the follow variables is a long because the time, measured in miliseconds,
  6. // will quickly become a bigger number than can be stored in an int.
  7. long interval = 1000;           // interval at which to blink (milliseconds)

  8. void setup() {
  9.   // set the digital pin as output:
  10.   pinMode(ledPin, OUTPUT);      
  11. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2015-2-25 22:20:41 | 显示全部楼层
再提醒一次:
如果按键没有嵌入debounce,每次按键一次可能会变成按键几次,A的值将不会顺序1,2,3,1,2,3......而是乱乱跳。
话说回头,你成功后才置入debounce
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-2-25 22:47:54 | 显示全部楼层
smching 发表于 2015-2-25 22:20
再提醒一次:
如果按键没有嵌入debounce,每次按键一次可能会变成按键几次,A的值将不会顺序1,2,3,1,2,3.. ...

恩,做到你说的这步了,就是按键乱跳,不听使唤。那个按键嵌入debounce要怎么写?
回复 支持 反对

使用道具 举报

发表于 2015-2-25 22:52:37 | 显示全部楼层
yqfans 发表于 2015-2-24 18:00
——————————————————————————

int ledpin=11;//定义数字11 接口

我建议中断不要用在按键,而是闪烁LED。所以这里的中断将不是外部中断,而是Timer中断。
请参考这里https://www.pjrc.com/teensy/td_libs_TimerOne.html

if a=1必须添加禁止中断
if a=2只能置入启动Timer中断。 其他代码全部去掉。
if a=3也是禁止中断
回复 支持 反对

使用道具 举报

发表于 2015-2-25 23:16:30 | 显示全部楼层
yqfans 发表于 2015-2-25 22:47
恩,做到你说的这步了,就是按键乱跳,不听使唤。那个按键嵌入debounce要怎么写?

下载这个bouce2程序库,将之解压到Arduino IDE的libraries文件夹里,然后把Bounce2-master更名为Bounce2。之后就是打开例子:
https://github.com/thomasfredericks/Bounce2

多个按键可以使用这个
http://ediy.com.my/index.php/tut ... g-multiple-switches
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-2-26 00:13:57 | 显示全部楼层
smching 发表于 2015-2-25 23:16
下载这个bouce2程序库,将之解压到Arduino IDE的libraries文件夹里,然后把Bounce2-master更名为Bounce2。 ...

[pre lang="arduino" line="2"]#include <Bounce2.h>

int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;   
long interval = 1000;  
Bounce debouncer = Bounce();
int ledpin=11;//定义数字11 接口
int inpin=7;//定义数字7 接口
int val;//定义变量val
int a;

void setup()
{
pinMode(inpin,INPUT_PULLUP);
debouncer.attach(inpin);
debouncer.interval(5); // interval in ms
pinMode(ledpin,OUTPUT);//定义小灯接口为输出接口
pinMode(inpin,INPUT);//定义按键接口为输入接口
}
void loop()
{
  debouncer.update(); // Get the updated value
  int value = debouncer.read();
  // Turn on or off the LED as determined by the state :
  val=digitalRead(inpin);//读取数字7 口电平值赋给val
if(val==HIGH)   {  //检测按键是否按下,按键按下时小灯亮起
                 a=a+1;
                }
   
if(a==4){
            a=1;
           }

    if ( a==1 ) {
               digitalWrite(ledpin,HIGH);
                }
    if ( a==2 ) {
               unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;   

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledpin, ledState);
    }
   }
    if ( a==3 ) {
               digitalWrite(ledpin,LOW);
                }
     
}[/code]

——————————————————————————————分割———
这个就是我加上Bounce2.h的程序,执行了下,没什么大的变化,还是不停使唤,一会亮,一会灭,一会闪的;是因为还没有加上中断吗?那这个Bounce2.h加的对吗?加这个的意思就是防止按键抖动么?精准的按一次,算一次么? 求大神回复。。。
回复 支持 反对

使用道具 举报

发表于 2015-2-26 04:04:01 | 显示全部楼层
本帖最后由 laofuz1024 于 2015-2-26 04:05 编辑
yqfans 发表于 2015-2-26 00:13
#include

int ledState = LOW;             // ledState used to set the LED
  1. int button = 0;     // 定义中断引脚为0,也就是D2引脚
  2. int led = 13;   // 定义输出指示灯引脚
  3. int sum=0;       //用于记录按键的次数控制灯的状态
  4. unsigned long Millis=millis();  //记录按下按键的时间,用于防按键乱跳

  5. void setup()
  6. {               
  7.   pinMode(led, OUTPUT);
  8.   attachInterrupt(button, button_Click, RISING);  //设置中断引脚从高到低变化调用的函数,设置成按键弹起时调用
  9. }

  10. void loop()                     
  11. {
  12.     //根据状态指示数字来控制灯的状态
  13.     if(sum==1){
  14.       digitalWrite(led, HIGH);
  15.     }
  16.     if(sum==2){
  17.       digitalWrite(led, HIGH);
  18.       delay(200);
  19.       digitalWrite(led, LOW);
  20.       delay(200);
  21.     }
  22.     if(sum==3){
  23.       digitalWrite(led, LOW);
  24.     }
  25.     delay(10);
  26. }
  27. /**
  28.     按键按下弹起时做的处理
  29. */
  30. void button_Click()  
  31. {
  32.   unsigned long nowMillis=millis();
  33.   if(nowMillis-Millis>100){    //防按键乱跳的
  34.     sum++;  //改变指示状态的数字
  35.     Millis=millis();
  36.   }
  37.   if(sum>=4) sum=1;   //如果灭的状态,要转到亮的状态
  38. }
复制代码
这些是我自己写的,试过,能用了!没有闪动

不过你要注意,设置 中断的引脚,如果是UNO板,只有 引脚 2和3  ,开关只能接上这两个之一
回复 支持 反对

使用道具 举报

发表于 2015-2-26 12:14:09 | 显示全部楼层
yqfans 发表于 2015-2-26 00:13
#include

int ledState = LOW;             // ledState used to set the LED

请删除第26行 val=digitalRead(inpin);
第27行 if(val==HIGH) 更换成 if(value==HIGH)
回复 支持 反对

使用道具 举报

发表于 2015-2-26 12:30:43 | 显示全部楼层
laofuz1024 发表于 2015-2-26 04:04
这些是我自己写的,试过,能用了!没有闪动

不过你要注意,设置 中断的引脚,如果是UNO板,只有 引脚 2和 ...

UNO只有三个Timer用来完成中断,其中为
Timer0 (8bits): delay(), millis() and micros(), PWM5 & PWM6
Timer1 (16bits): Servo library, PWM9 & PWM10
Timer2 (8bits): tone() , PWM11& PWM3, SPI(MOSI)

如果可以不使用中断,尽量别用中断。
回复 支持 反对

使用道具 举报

发表于 2015-2-26 13:30:31 | 显示全部楼层
smching 发表于 2015-2-26 12:30
UNO只有三个Timer用来完成中断,其中为
Timer0 (8bits): delay(), millis() and micros(), PWM5 & PWM6
...

这个是什么意思呢?
回复 支持 反对

使用道具 举报

发表于 2015-2-26 14:24:09 | 显示全部楼层
laofuz1024 发表于 2015-2-26 13:30
这个是什么意思呢?

AtMega328(Arduino UNO)外部触发中断只有两个,就是D2和D3。
这里列出不同的Arduino使用不同的引脚触发中断
http://arduino.cc/en/Reference/AttachInterrupt

它提到:
Generally, an ISR should be as short and fast as possible. If your sketch uses multiple ISRs, only one can run at a time, other interrupts will be ignored (turned off) until the current one is finished. as delay() and millis() both rely on interrupts, they will not work while an ISR is running. delayMicroseconds(), which does not rely on interrupts, will work as expected.
意思是:
delay()与millis()都依靠中断,如果启动了AttachInterrupt,这两个功能也许会出现错误,但delayMicroseconds()就没有这问题。

另外Timer触发中断有三个:Timer0, Timer1, Timer2。
当这些中断操作时,相对的工能就不能使用了。

例:
Timer0 (8bits): delay(), millis() and micros(), PWM5 & PWM6
Timer1 (16bits): Servo library, PWM9 & PWM10
Timer2 (8bits): tone() , PWM11& PWM3, SPI(MOSI)
如果Timer0置成中断,那么就不能用delay()、millis() 、 PWM5、PWM6等等
如果Timer2置成中断,那么就不能用tone()、PWM11(指D11的PWM功能)、PWM3(指D3的PWM功能)等等
回复 支持 反对

使用道具 举报

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

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

Archiver|联系我们|极客工坊

GMT+8, 2024-4-18 09:48 , Processed in 0.042369 second(s), 17 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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