以前一直用mega2560,好不容易解决了watchdog的问题,看门狗正常工作。
新项目中boss要求mega328p也能够支持看门狗,想想应该是比较容易的,毕竟avr官方文档中有对watchdog的说明。这个坑就这样埋下了。 写一个看门狗测试程序:
#include <avr/wdt.h>
const int ledPin = 13; // the number of the LED pin
void setup() {
wdt_disable();
Serial.begin(9600);
Serial.println("System Init OK!");
pinMode(ledPin, OUTPUT);
Serial.println("Wait 5 Sec..");
delay(5000);
wdt_enable(WDTO_8S);
/*
WDTO_15MS
WDTO_30MS
WDTO_60MS
WDTO_120MS
WDTO_250MS
WDTO_500MS
WDTO_1S
WDTO_2S
WDTO_4S
WDTO_8S
*/
Serial.println("Watchdog enabled!");
}
uint8_t timer = 0;
void loop() {
if (!(millis() % 1000)) {
Serial.print(millis());
Serial.print("--");
timer++;
Serial.println(timer);
digitalWrite(ledPin, digitalRead(ledPin) == 1 ? 0 : 1); delay(1);
}
// wdt_reset();
}
第一次运转正常,成功复位,小case,随便就搞定了。However.....
复位之后居然就一直复位了...一直无限循环复位,像下面这样.... System Init OK!
Wait 5 Sec..
Watchdog enabled!
5000--1
6000--2
7000--3
8000--4
9000--5
10000--6
11000--7
12000--8
13000--9
System Init OK!
我去,这怎么回事。猜测可能是bootloader的问题,搞个optiboot来看看,听说对watchdog支持十分良好。 烧录上之后,依然这个问题。 这里的说明: Note that for newer devices (ATmega88 and newer, effectively any AVR that has the option to also generate interrupts), the watchdog timer remains active even after a system reset (except a power-on condition), using the fastest prescaler value (approximately 15 ms). It is therefore required to turn off the watchdog early during program startup, the datasheet recommends a sequence like the following: 对于atmega88以及新型号的单片机(自带产生中断的),看门狗可能会在系统复位之后,依然运行(除掉电复位外)。因此,需要在程序启动早期,关闭看门狗。datasheet中推荐插入一段这样的程序:
#include <stdint.h>
#include <avr/wdt.h>
uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
void get_mcusr(void) \
__attribute__((naked)) \
__attribute__((section(".init3")));
void get_mcusr(void)
{
mcusr_mirror = MCUSR;
MCUSR = 0;
wdt_disable();
}
然后,问题解决,正常复位.. 还是的多看datasheet..哎
|