Watchdog Time-out Interrupt mit Attiny
Verwendete Register:
- Status Register: SREG
- MCU Status Register: MCUSR
- Watchdog Timer Control Register: WDTCR
Vorgangsweise:
- Alle Interrupts sperren
- Watchdog Reset ausführen (Rücksetzen des Watchdog Timer)
- Watchdog System Reset Flag rücksetzen
- Freigabe zur Änderung des Prescaler (Vorteiler) setzen
- Prescaler setzen
- Watchdog Time-out Interrupt freigeben
- Alle Interrupts freigeben
- 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)
{
............
}