使用Arduino UNO的看门狗:
介绍:看门狗定时器用避免电子设备出现故障造成死机,例如死循环。为此,看门狗作为一个物理定时器,在程序运行时不断的增加,并驱动一个中断, 如果达到某一个设定的值,就会复位微处理器。在正常操作下,定时器在程序流程中的定期设置为0, 但如果代码进入死循环,定时器复位不会发生,看门狗触发中断并重新启动。
使用看门狗防止死机:Arduino为用户提供了方便操作的函数和宏,可以直接引入库:
#include <avr/wdt.h>
这个函数库提供了三个API函数供我们使用:
wdt_enable(timeout) //看门狗使能并设置超时时间 wdt_disable() //关闭 wdt_reset() //复位
timeout可以使用wdt.h文件中定义的宏常量,也可以自定义时间;
通常情况下,需要在setup()函数中使能看门狗定时器,并在loop()中不断的喂狗防止溢出,官方给出的示例代码如下:
#include <avr/wdt.h> void setup() { pinMode(13,OUTPUT); wdt_enable(WDTO_2S); //开启看门狗,并设置溢出时间为两秒 } void loop() { digitalWrite(13,HIGH); delay(100); digitalWrite(13,LOW); delay(100); wdt_reset(); //喂狗操作,使看门狗定时器复位 }
注:看门狗也可以唤醒省电模式下的 Arduino, 详细说明可查阅官方文档,特别指出的是,如果使用POWER_MODE_IDLE模式(UART、SPI、timer等处于工作状态),需在进入休眠状态前关闭看门狗功能,休眠结束之后再次启动,否则几秒之后看门狗会强制重启Aruino, 休眠失败。示例代码:
/* Sleep Demo Serial * ----------------- * Example code to demonstrate the sleep functions in a Arduino. Arduino will wake up * when new data is received in the serial port USART * Based on Sleep Demo Serial from http://www.arduino.cc/playground/Learning/ArduinoSleepCode * * Copyright © 2006 MacSimski 2006-12-30 * Copyright © 2007 D. Cuartielles 2007-07-08 - Mexico DF * * With modifications from Ruben Laguna 2008-10-15 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ #include <avr/power.h> #include <avr/sleep.h> int sleepStatus = 0; // variable to store a request for sleep int count = 0; // counter void setup() { Serial.begin(9600); } void sleepNow() { /* 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 * * the power reduction management <avr/power.h> is described in * http://www.nongnu.org/avr-libc/user-manual/group_avr_power.html */ set_sleep_mode(SLEEP_MODE_IDLE); // sleep mode is set here sleep_enable(); // enables the sleep bit in the mcucr register // so sleep is possible. just a safety pin power_adc_disable(); power_spi_disable(); power_timer0_disable(); power_timer1_disable(); power_timer2_disable(); power_twi_disable(); wdt_disable(); //close wdt before Arduino enter sleep mode sleep_mode(); // here the device is actually put to sleep!! // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP sleep_disable(); // first thing after waking from sleep: // disable sleep... wdt_enable(timeout); //open wdt after wakine from sleep power_all_enable(); } void loop() { // display information about the counter Serial.print("Awake for "); Serial.print(count); Serial.println("sec"); count++; delay(1000); // waits for a second // compute the serial input if (Serial.available()) { int val = Serial.read(); if (val 'S') { Serial.println("Serial: Entering Sleep mode"); delay(100); // this delay is needed, the sleep //function will provoke a Serial error otherwise!! count = 0; sleepNow(); // sleep function called here } if (val 'A') { Serial.println("Hola Caracola"); // classic dummy message } } // check if it should go asleep because of time if (count >= 10) { Serial.println("Timer: Entering Sleep mode"); delay(100); // this delay is needed, the sleep //function will provoke a Serial error otherwise!! count = 0; sleepNow(); // sleep function called here } }