Watchdog Time-out Interrupt mit Attiny

Verwendete Register:

  • Status Register: SREG
  • MCU Status Register: MCUSR
  • Watchdog Timer Control Register: WDTCR


Vorgangsweise:

  1. Alle Interrupts sperren
  2. Watchdog Reset ausführen (Rücksetzen des Watchdog Timer)
  3. Watchdog System Reset Flag rücksetzen
  4. Freigabe zur Änderung des Prescaler (Vorteiler) setzen
  5. Prescaler setzen
  6. Watchdog Time-out Interrupt freigeben
  7. Alle Interrupts freigeben
  8. Interrupt-Serviceroutine erstellen


1. Alle Interrupts sperren

Durch die Anweisung "cli();" oder durch Löschen des Global Interrupt Enable Bits (I) im Status Register (SREG) werden alle Interrupts gesperrt. Während der Manipulation des Watchdog Timer Control Register soll kein Interrupt ausgelöst werden können.

cli(); //oder SREG &= 0x7;


2. Watchdog Reset ausführen (Rücksetzen des Watchdog Timer)

Vor der Änderung der Prescaler Bits sollte der Watchdog Timer mit der Funktion wdt_reset() zurückgesetzt werden. Dazu ist die Library wdt.h vorher einzubinden. Die Library ist Bestandteil der Arduino-IDE und muss daher nicht installiert werden.

#include <avr/wdt.h>

wdt_reset(); // Reset Watchdog Timer


3. Watchdog System Reset rücksetzen

Das Watchdog System Reset Flag (WDRF) des MCU Status Register (MCUSR) wird gesetzt, wenn ein Watchdog System Reset auftritt. Es wird durch ein Power-on Reset oder durch Beschreiben mit '0' zurückgesetzt. Um Watchdog Reset System Enable (WDE) löschen zu können, muss zuerst das WDRF Bit gelöscht werden.

MCUSR &= ~(1 << WDRF);


4. Freigabe zur Änderung des Prescaler (Vorteiler) setzen

Das Setzen des Watchdog Change Enable Bit (WDCE) des Watchdog Timer Control Register (WDTCR) ist Voraussetzung, dass die Bits zur Vorgabe des Prescalers verändert werden können. Ist das Bit gesetzt, wird es hardwaremäßig nach 4 Taktzyklen wieder rückgesetzt. Das bedeutet, dass das Setzen der Prescaler-Bits unmittelbar nach dem Setzen des WDCE-Bit erfolgen muss!

WDTCR = (1 << WDCE) | (1 << WDE); //Watchdog Change Enable


5. Prescaler setzen

Der Watchdog Timer beim Arduino/Attiny beruht auf einem separaten "On-Chip" Oszillator mit einer Taktfrequenz von 128 KHz. Mittels der Watchdog Timer Prescaler Bits WDP3 - WDP0 des Watchdog Timer Control Register (WDTCR) kann diese Taktfrequenz so geteilt werden, dass nachfolgende Time-outs, also Zeiten zwischen 16 ms und 8 s, eingestellt werden können

WDTCR = (1 << WDP3) | (1 << WDP0); //Time-out = 8 s


6. Watchdog Time-out Interrupt freigeben

Durch Setzen der Bits Watchdog Interrupt Enable (WDIE) und Watchdog System Reset Enable (WDE) des Watchdog Timer Control Register (WDTCR) kann das Verhalten des Watchdog nach dem Time-out, entsprechend nachfolgender Tabelle, bestimmt werden.

WDTCSR |= (1 << WDIE); //Watchdog  Mode = Interrupt Mode


7. Alle Interrupts freigeben

Durch die Anweisung "sei();" oder durch  Setzen des Global Interrupt Enable Bits (I) im Status Register (SREG) werden alle Interrupts freigegeben.

sei();  //oder SREG |= 0x80;


8. Erstellen der Interrupt-Serviceroutine

Wird ein Watchdog Time-out Interrupt ausgelöst, verzweigt das Programm in eine zu erstellende Serviceroutine ISR(WDT_vect).

Die Namen der Interrupt-Serviceroutine ist vom System fix vorgegeben und darf nicht verändert werden!

ISR(WDT_vect)
{
  ............
}


Programmbeispiel

siehe: Attiny im Schlafmodus