AVR外部中断代码被阻止

时间:2017-09-15 11:59:19

标签: arduino sleep interrupt arduino-uno

我正在研究Arduino睡眠和外部中断。我从here获得了示例代码,效果很好。我在代码中做了一些更改和添加,在AVR唤醒时我正在检查按钮状态,等待按钮被按下。单击按钮会将闹钟关闭几秒钟,然后Arduino进入睡眠模式。按下INT0按钮唤醒Arduino,检查按钮,进入睡眠状态。

我的问题是这段代码工作一次,如果我们按下第二次唤醒,它会检查按下按钮并进入睡眠状态,但是按下按钮它不会唤醒。

请告诉我代码中的问题。

#include <avr/sleep.h>
const int LED = 13;
const int LEDT = 11;
const unsigned long KEEP_RUNNING = 10000; //milliseconds
const byte overflowPin = 6;
const byte buzzer1 = 8;
const byte buzzer2 = 9;

void setup(void) {
  //to minimize power consumption while sleeping, output pins must not source
  //or sink any current. input pins must have a defined level; a good way to
  //ensure this is to enable the internal pullup resistors.
  for (byte i = 0; i < 20; i++) {
    //make all pins inputs with pullups enabled
    pinMode(i, INPUT_PULLUP);
  }
  pinMode(LED, OUTPUT); //make the led pin an output
  pinMode(LEDT, OUTPUT); //make the led pin an output
  digitalWrite(LED, LOW); //drive it low so it doesn't source current
  digitalWrite(LEDT, LOW); //drive it low so it doesn't source current
  pinMode (overflowPin, INPUT_PULLUP);
  pinMode(buzzer1, OUTPUT);
  pinMode(buzzer2, OUTPUT);
  Serial.begin(9600);
}

void loop(void) {
  Serial.println("Wake up!");
  Serial.println("Flashed 5 Times");
  for (byte i = 0; i < 5; i++) {
    //flash the LED
    digitalWrite(LED, HIGH);
    delay(100);
    digitalWrite(LED, LOW);
    delay(100);
  }
  Serial.println("Reading" );
  while (digitalRead(overflowPin) == HIGH) {
    calibrate();
  }
  Serial.println ("Hey....");
  Serial.println("Alarm!!!" );
  for (byte i = 0; i < 5; i++) {
    //Flash the Alarm 5 Times
    alarmSound();
  }
  Serial.println("Go Sleep in 10 Sec...." );
  digitalWrite(LED, HIGH); //one blink before sleeping
  delay(100);
  digitalWrite(LED, LOW);
  goToSleep();
}

void alarmSound(void) {
  // Toggle the buzzer at various speeds
  for (byte x = 250 ; x > 70 ; x--) {
    for (byte y = 0 ; y < 3 ; y++) {
      digitalWrite(buzzer2, HIGH);
      digitalWrite(buzzer1, LOW);
      delayMicroseconds(x);
      //microDelay(x);
      digitalWrite(buzzer2, LOW);
      digitalWrite(buzzer1, HIGH);
      delayMicroseconds(x);
    }
  }
}

void calibrate(void) {
  Serial.println ("Listening....");
  for (byte i = 0; i < 5; i++) {
    //flash the LED
    digitalWrite(LEDT, HIGH);
    delay(100);
    digitalWrite(LEDT, LOW);
    delay(100);
  }
}

void goToSleep(void) {
  byte adcsra = ADCSRA; //save the ADC Control and Status Register A
  ADCSRA = 0; //disable the ADC
  EICRA = _BV(ISC01); //configure INT0 to trigger on falling edge
  EIMSK = _BV(INT0); //enable INT0
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  cli();
  //stop interrupts to ensure the BOD timed sequence executes as required
  sleep_enable();
  //disable brown-out detection while sleeping (20-25µA)
  uint8_t mcucr1 = MCUCR | _BV(BODS) | _BV(BODSE);
  uint8_t mcucr2 = mcucr1 & ~_BV(BODSE);
  MCUCR = mcucr1;
  MCUCR = mcucr2;
  sleep_bod_disable();
  //for AVR-GCC 4.3.3 and later, this is equivalent to the previous 4 lines of code
  sei();
  //ensure interrupts enabled so we can wake up again
  sleep_cpu(); //go to sleep
  sleep_disable(); //wake up here
  ADCSRA = adcsra; //restore ADCSRA
}

//external interrupt 0 wakes the MCU
ISR(INT0_vect) {
  EIMSK = 0; //disable external interrupts (only need one to wake up)
}

0 个答案:

没有答案