Atmega328P Watch Dog Timer - Verzögerungsproblem

Ich versuche, eine Verzögerung von 0,5 Sekunden auf Pin 13 des Arduino mit Watch Dog Timer Interrupt zu geben, der Code entspricht und funktioniert gut, aber die LED blinkt so schnell, dass es so aussieht, als würde sie mit einer Verzögerung von 50 ms nicht mit einer Verzögerung blinken von 0,5 Sekunden. Bitte helfen Sie. Vielen Dank im Voraus.

#define F_CPU 16000000UL
#include<avr/io.h>
#include<avr/interrupt.h>
#include<avr/wdt.h>

int main(void)
{
  cli();
  wdt_reset();

  WDTCSR |=(1<<WDP2) | (1<<WDP0);

  WDTCSR |= (1<<WDIE);
  WDTCSR |= (1<<WDE);

  sei();

  DDRB |= 0b00100000;

  PORTB |= 0b00000000;

  while(1)
  {

  }
}

ISR(WDT_vect) {

 PORTB ^= 0b00100000;

}
Versuchen Sie, WDE auf 0 statt 1 zu setzen - das sollte Ihnen einen 500-ms-Interrupt ohne System-Reset geben - mit diesem Code würde ich erwarten, dass das System alle 500 ms sofort nach Eingabe der ISR zurückgesetzt wird, und da Sie das Interrupt-Flag nicht löschen, Sie geben diese ISR sofort ein, wenn Sie WDIE nach dem Zurücksetzen einstellen - den Pin umschalten.
Versucht, das Problem ist immer noch das gleiche. es blinkt so schnell.
Sind Sie sicher, dass Sie den Interrupt in der ISR nicht löschen müssen?
Das Datenblatt sagt "Änderungen am Watchdog-Setup müssen zeitgesteuerten Sequenzen folgen" bzgl. des "Watchdog Change Enable Bit (WDCE)" und enthält auch Beispielcode. Warum benutzt du das nicht?

Antworten (1)

Wenn ich das Datenblatt (S.54-55) richtig gelesen habe, muss man das WDCEBit setzen WDTCSRum den Prescaler ändern zu können. Die Standardeinstellung für die Prescaler-Bits beträgt 000oder etwa 16 ms Verzögerung.

Wenn Sie sowohl WDEals auch setzen WDIE, arbeitet der Watchdog im "Interrupt- und System-Reset-Modus", in dem das erste WD-Timeout den Interrupt auslöst und ein zweites das Gerät zurücksetzt, es sei denn, das WDIEBit wird nach dem Interrupt erneut gesetzt. Oder wenn Sie nur den Interrupt wollen, nicht den Reset, lassen Sie ihn einfach WDEungesetzt.

Um den Beispielcode zu paraphrasieren, denke ich, dass Sie so etwas wollen:

cli();
WDTCSR |= (1<<WDCE);  /* enable change */
WDTCSR = (1<<WDIE) | (1<<WDP2) | (1<<WDP0);  /* enable interrupt and set prescaler */
sei();