-
Plus connu en patoi sous le nom de "Watchdog".
- Horloge indépendante de 128Khz dans la puce.
- Fondamentalement c’est un minuteur hors CPU :
-
programmable de 16ms à 8s ;
- pouvant générer une interruption prioritaire ;
- pouvant réinitialiser le CPU ;
- ou faire les deux en séquence.
- Possibilité de mettre en surveillance obligatoire.
- Controlé par le registre éponyme WDTCSR.
- Exemple typique pour contourner les plantages :
#include <avr/io.h>
void wdt_signaler(void){
asm volatile ("wdr"); // Réinitialisation du minuteur
}
void wdt_activer(unsigned char prescaler){
cli();
wdt_signaler();
WDTCSR |= (1<<WDCE) | (1<<WDE); // Demande d'une modification du minuteur
WDTCSR = (1<<WDE) | (0<<WDEI) | prescaler; // Multiplicateur de 0x00 à 0x09
// Génération d'une réinitialisation du CPU
sei();
}
void wdt_desactiver(void){
cli();
wdt_signaler();
__disable_interrupt();
MCUSR &= ~(1<<WDRF); // Désactivation d'un déclenchement du minuteur
WDTCSR |= (1<<WDCE) | (1<<WDE); // Demande d'une modification du minuteur
WDTCSR = 0x00; // Désactivation complète du minuteur
sei();
}
int main(void){
wdt_activer((0<<WDP3)|(1<<WDP2)|(1<<WPD1)|(1<<WPD0)); // Minuteur à environ 2s
while(1){
// faire quelque chose en quelques ms
wdt_signaler();
}
}
- Plus utile pour économiser de l’énergie (en utilisant avrlibc) :
#include <avr/wdt.h>
#include <avr/sleep.h>
int main(void){
wdt_disable(); // Désactivation du minuteur au réveil
... // Code pour faire ce qu'il y a faire
wdt_enable(WDTO_2S); // Réveil prévu dans environ 2 secondes
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Mode sommeil profond
sleep_mode(); // Zoup au dodo
}
- La mise en sommeil s’effectue via le registre de sommeil SMCR :
#include <avr/wdt.h>
#include <avr/sleep.h>
int main(void){
wdt_disable(); // Désactivation du minuteur au réveil
... // Code pour faire ce qu'il y a faire
wdt_enable(WDTO_2S); // Réveil prévu dans environ 2 secondes
SMCR &= ~(1<<SM2);
SMCR |= (1<<SM1);
SMCR &= ~(1<<SM0);
SMCR |= (1<<SE);
asm volatile("sleep");
SMCR &= ~(1<<SE);
}