C语言 为什么看门狗在中断模式下仍会导致器械复位?

nszi6y05  于 2023-01-12  发布在  其他
关注(0)|答案(2)|浏览(199)

环境

我使用的是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但也不起作用。

bweufnob

bweufnob1#

我以前遇到过这个问题。我的错误是设置了WDTON保险丝位。我以为它的目的是“打开看门狗”(看门狗定时器打开)。但实际上,它迫使定时器进入中断模式,无论你在WDE和WDIE中使用什么位。为你的芯片使用fuse calculator,并确保禁用WDTON。

编辑:WDTON写入1被禁用0被启用!所以你需要把它写入1
Edit 2:正如AterLux所说,使用reti()时请参考this post

xdnvmnnf

xdnvmnnf2#

根据datasheet
如果设置了WDE,则看门狗定时器处于中断和系统复位模式。看门狗定时器的第一次超时将设置WDIF。执行相应的中断向量将通过硬件自动清除WDIE和WDIF(看门狗进入系统复位模式)。
因此,每次中断后,模式更改为系统复位模式,这就是需要使用WDTCSR |= 1 << WDIE;重新使能的原因。

相关问题