#include <avr/sleep.h>
#include <avr/power.h>
//#include <avr/wdt.h>
#include <MsTimer2.h>
int pin = 13;
volatile int f_sleepButton = 0;
volatile int f_sleepTimer = 0;
void setup() {
//Serial.begin(9600);
//Serial.print("Welcome to use!\n");
pinMode(pin, OUTPUT);
pinMode(2, INPUT);
MsTimer2::set(2000, sleepTimer); // 中断设置函数,每 2000ms 进入一次中断
MsTimer2::start();
sleepNow();
}
void loop() {
if (digitalRead(2)) {
//sleepNow();
f_sleepButton++;
clearsleepTimer();
delay(50);
}
if (f_sleepButton == 24) { // 长按1.2秒关机
sleepNow();
}
if (f_sleepTimer == 10) { // 延时没有操作关机
sleepNow();
}
}
void sleepTimer() {
f_sleepTimer++;
}
void sleepNow() // here we put the arduino to sleep
{
//detachInterrupt(0);
digitalWrite(pin, HIGH);
//delay(1000);
//return;
//Serial.print("sleep_enable\n");
/* Now is the time to set the sleep mode. In the Atmega8 datasheet
http://www.atmel.com/dyn/resources/prod_documents/doc2486.pdf on page 35
there is a list of sleep modes which explains which clocks and
wake up sources are available in which sleep modus.
In the avr/sleep.h file, the call names of these sleep modus are to be found:
The 5 different modes are:
SLEEP_MODE_IDLE -the least power savings
SLEEP_MODE_ADC
SLEEP_MODE_PWR_SAVE
SLEEP_MODE_STANDBY
SLEEP_MODE_PWR_DOWN -the most power savings
For now, we want as much power savings as possible,
so we choose the according sleep modus: SLEEP_MODE_PWR_DOWN
*/
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable(); // enables the sleep bit in the mcucr register
// so sleep is possible. just a safety pin
/* Now is time to enable a interrupt. we do it here so an
accidentally pushed interrupt button doesn't interrupt
our running program. if you want to be able to run
interrupt code besides the sleep function, place it in
setup() for example.
In the function call attachInterrupt(A, B, C)
A can be either 0 or 1 for interrupts on pin 2 or 3.
B Name of a function you want to execute at interrupt for A.
C Trigger mode of the interrupt pin. can be:
LOW a low level triggers
CHANGE a change in level triggers
RISING a rising edge of a level triggers
FALLING a falling edge of a level triggers
In all but the IDLE sleep modes only LOW can be used.
*/
attachInterrupt(0, wakeUpNow, RISING ); // use interrupt 0 (pin 2) and run function
// wakeUpNow when pin 2 gets LOW
sleep_mode(); // here the device is actually put to sleep!!
//
sleep_disable(); // first thing after waking from sleep:
// disable sleep...
detachInterrupt(0); // disables interrupt 0 on pin 2 so the
// wakeUpNow code will not be executed
// during normal running time.
power_all_enable();/* Re-enable the peripherals. */
delay(100); // wat 2 sec. so humans can notice the
// interrupt.
// LED to show the interrupt is handled
digitalWrite (pin, LOW); // turn off the interrupt LED
}
void wakeUpNow()
{ //Serial.print("wakeUpNow\n");
f_sleepButton = 0;
//digitalWrite(pin, LOW);
//attachInterrupt(0,sleepNow, FALLING ); // 睡眠模式
}
void clearsleepTimer() {
f_sleepTimer = 0;
}