环境
我使用的是Arduino Mega 2560,这里是源代码:
#ifndef F_CPU
#define F_CPU 16000000L
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
void start_system_timer(void)
{
cli();
// Avoid eternal loop of time-out resets by clearing WDRF
MCUSR &= ~(1<<WDRF);
// Reset watchdog timer
wdt_reset();
// Enable WD timer configuration mode
WDTCSR |= 1 << WDCE | 1 << WDE;
// Reset WD timer
WDTCSR = 0;
// Configure period
wdt_enable(WDTO_1S);
// Use WD timer in interrupt mode
WDTCSR |= 1 << WDIE;
sei();
}
int main(void)
{
// Define digital pin PORTB7 as an output and turn on the led
DDRB |= (1<<PB7);
PORTB |= (1<<PB7);
start_system_timer();
sei();
while (1)
{
}
}
ISR (WDT_vect, ISR_NAKED)
{
// Turn off LED
PORTB &= ~(1<<PB7);
// Re-enable watchdog timer interrupt to avoid reset
WDTCSR |= 1 << WDIE;
reti();
}
问题
如果我将看门狗定时器设置为在中断模式下工作,并且不重置中断处理程序内的定时器,则它会重置电路板。
根据数据手册,如果处于复位模式,则不应进入系统复位模式。
还尝试在使用WDTCSR &= ~(1<<WDIE);
设置中断模式后清除WDIE
位,以防设置为1但也不起作用。
2条答案
按热度按时间bweufnob1#
我以前遇到过这个问题。我的错误是设置了WDTON保险丝位。我以为它的目的是“打开看门狗”(看门狗定时器打开)。但实际上,它迫使定时器进入中断模式,无论你在WDE和WDIE中使用什么位。为你的芯片使用fuse calculator,并确保禁用WDTON。
编辑:WDTON写入1被禁用0被启用!所以你需要把它写入1
Edit 2:正如AterLux所说,使用reti()时请参考this post。
xdnvmnnf2#
根据datasheet:
如果设置了WDE,则看门狗定时器处于中断和系统复位模式。看门狗定时器的第一次超时将设置WDIF。执行相应的中断向量将通过硬件自动清除WDIE和WDIF(看门狗进入系统复位模式)。
因此,每次中断后,模式更改为系统复位模式,这就是需要使用
WDTCSR |= 1 << WDIE;
重新使能的原因。