yqfans 发表于 2015-2-24 18:00:47

本帖最后由 yqfans 于 2015-2-24 18:04 编辑

laofuz1024 发表于 2015-2-24 00:09 static/image/common/back.gif
中断的知识,论坛里有好教程

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;)这句是的作用是什么,是条件判断?还是执行?不明白

smching 发表于 2015-2-24 18:11:48

loop里是不能有delay的。当a=2时,delay不停地运行。
闪烁部分请参考Arduino实例BlinkWithoutDelay

yqfans 发表于 2015-2-25 20:57:40

本帖最后由 yqfans 于 2015-2-25 21:03 编辑

smching 发表于 2015-2-24 18:11 static/image/common/back.gif
loop里是不能有delay的。当a=2时,delay不停地运行。
闪烁部分请参考Arduino实例BlinkWithoutDelay

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

yqfans 发表于 2015-2-25 21:05:56

现在这个程序被卡了好几天了,自己实在是搞不出程序来,有大神帮的修改下我的程序么?或者按要求用你的方式写也行,我对编程基本一窍不通的属于{:soso_e141:}

smching 发表于 2015-2-25 22:03:53

yqfans 发表于 2015-2-25 20:57 static/image/common/back.gif
那不用这个语句要怎么闪?我看不懂BlinkWithoutDelay的例子,难道一个简单的闪烁也要那么复杂么?
不过 ...

你是参考这个例子吗?
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==2 ) {。。。}之间
const int ledPin =13;      // the number of the LED pin

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

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

void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);      
}

smching 发表于 2015-2-25 22:20:41

再提醒一次:
如果按键没有嵌入debounce,每次按键一次可能会变成按键几次,A的值将不会顺序1,2,3,1,2,3......而是乱乱跳。
话说回头,你成功后才置入debounce

yqfans 发表于 2015-2-25 22:47:54

smching 发表于 2015-2-25 22:20 static/image/common/back.gif
再提醒一次:
如果按键没有嵌入debounce,每次按键一次可能会变成按键几次,A的值将不会顺序1,2,3,1,2,3.. ...

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

smching 发表于 2015-2-25 22:52:37

yqfans 发表于 2015-2-24 18:00 static/image/common/back.gif
——————————————————————————

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也是禁止中断

smching 发表于 2015-2-25 23:16:30

yqfans 发表于 2015-2-25 22:47 static/image/common/back.gif
恩,做到你说的这步了,就是按键乱跳,不听使唤。那个按键嵌入debounce要怎么写?

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

多个按键可以使用这个
http://ediy.com.my/index.php/tutorials/item/96-debouncing-multiple-switches

yqfans 发表于 2015-2-26 00:13:57

smching 发表于 2015-2-25 23:16 static/image/common/back.gif
下载这个bouce2程序库,将之解压到Arduino IDE的libraries文件夹里,然后把Bounce2-master更名为Bounce2。 ...

#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);
                }
   
}

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

laofuz1024 发表于 2015-2-26 04:04:01

本帖最后由 laofuz1024 于 2015-2-26 04:05 编辑

yqfans 发表于 2015-2-26 00:13 static/image/common/back.gif
#include

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

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

void loop()                     
{
    //根据状态指示数字来控制灯的状态
    if(sum==1){
      digitalWrite(led, HIGH);
    }
    if(sum==2){
      digitalWrite(led, HIGH);
      delay(200);
      digitalWrite(led, LOW);
      delay(200);
    }
    if(sum==3){
      digitalWrite(led, LOW);
    }
    delay(10);
}
/**
    按键按下弹起时做的处理
*/
void button_Click()
{
unsigned long nowMillis=millis();
if(nowMillis-Millis>100){    //防按键乱跳的
    sum++;//改变指示状态的数字
    Millis=millis();
}
if(sum>=4) sum=1;   //如果灭的状态,要转到亮的状态
}这些是我自己写的,试过,能用了!没有闪动

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

smching 发表于 2015-2-26 12:14:09

yqfans 发表于 2015-2-26 00:13 static/image/common/back.gif
#include

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


请删除第26行 val=digitalRead(inpin);
第27行 if(val==HIGH) 更换成 if(value==HIGH)

smching 发表于 2015-2-26 12:30:43

laofuz1024 发表于 2015-2-26 04:04 static/image/common/back.gif
这些是我自己写的,试过,能用了!没有闪动

不过你要注意,设置 中断的引脚,如果是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)

如果可以不使用中断,尽量别用中断。

laofuz1024 发表于 2015-2-26 13:30:31

smching 发表于 2015-2-26 12:30 static/image/common/back.gif
UNO只有三个Timer用来完成中断,其中为
Timer0 (8bits): delay(), millis() and micros(), PWM5 & PWM6
...

这个是什么意思呢?

smching 发表于 2015-2-26 14:24:09

laofuz1024 发表于 2015-2-26 13:30 static/image/common/back.gif
这个是什么意思呢?

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功能)等等
页: 1 [2] 3 4
查看完整版本: 小白求助~ 按键控制LED,如何按一下松开,亮;按一下松开,闪烁;再按一下松开,灭。