Atmel Mega644: Watchdog Prescaler

Gast #1841039
Lesenswert?

Hallo Wissende,

ich habe eine (gut getestete, elektronische Probleme schließe ich aus) 
Schaltung, in der ein auf 14,7456 MHz getakteter ATMega644 läuft. Nun 
möchte ich den Watchdog nutzen, und zwar mit einem Timeout von 2 
Sekunden. Dazu habe ich nach Studium des Datenblatts folgenden Code 
vorbereitet:
1
void initWatchdog(void) {
2
  uint8_t sregTmp;
3

4
  /* disable interrupts */
5
  sregTmp = SREG;
6
  CLI();
7
  WDR();
8
  
9
  MCUSR = 0x00; // Clear all reset flags previously set.
10
  
11
  //Step 1: Enable the Watchdog Enable Change Bit (WDCE)
12
  WDTCSR |= (1 << WDCE) | (1 << WDE);
13
  //Step 2: Enable Watchdog, set timeout to 2.0s
14
  WDTCSR |= (1 << WDE) | (1 << WDP2) | (1 << WDP1) | (1 << WDP0);
15
  
16
  SREG = sregTmp ; /* restore interrupts */
17
}

Der Watchdog funktioniert auch wunderbar, und ich kann ihn mit 
asm("wdr") zurücksetzen. Leider ignoriert er den Prescaler und resettet 
den µC nach einer sehr kurzen Zeit von wenigen Millisekunden. Andere 
Prescaler-Einstellungen führen zum selben Ergebnis. Was mach ich falsch?

Viele Grüße
Tim
Gast #1841055
Lesenswert?

Hallo,

ich denke das liegt daran, dass das Change Enable Bit nach 4 Taktzyklen 
automatisch wieder zurückgesetzt wird. Die Veroderung der vier Bits im 
Step 2 schaffst du/der Compiler wohl nicht in dieser Zeit.
Probier mal aus im Step 2 das WDTSCR-Register dirkt mit dem Hex-Wert zu 
laden.

Gruß
RealBlazer
Gast #1841061
Lesenswert?

1. Optimierung einschalten, sonst wird der Code zu langsam.
2. Die zweite Zuweisung an WDTCSR ist eine reinrassige Zuweisung und 
kein 'verodernde' Zuweisung. Dauert sonst zu lang.

Die Bitschiebereien rechnet übrigens der Compiler aus, das ist kein 
Laufzeitproblem.
Gast #1841063
Lesenswert?

Hallo,

danke für die schnellen Antworten. Interessante Idee, habe mal 
nachgeschaut, was der Compiler so produziert:
1
 000A           ;       WDTCSR |= (1 << WDCE) | (1 << WDE);
2
 000A 80916000          lds R24,96
3
 000E 8861              ori R24,24
4
 0010 80936000          sts 96,R24
5
 0014                   .dbline 20
6
 0014           ;       //Step 2: Enable Watchdog, set timeout to 8.0s
7
 0014           ;       WDTCSR |= (1 << WDE) | (1 << WDP3); // | (1 << WDP1) | (1 << WDP0);
8
 0014 80916000          lds R24,96
9
 0018 8862              ori R24,40
10
 001A 80936000          sts 96,R24

Das müsste eigentlich gerade noch passen. Werde morgen mal testweise das 
|= durch ein = ersetzen.

Gruß
Tim
Gast #1841066
Lesenswert?

> Das müsste eigentlich gerade noch passen. Werde morgen mal testweise das
> |= durch ein = ersetzen.

..das dürfte nit langen:
1
> 0014           ;       WDTCSR |= (1 << WDE) | (1 << WDP3); // | (1 << WDP1) | (1 << WDP0);
2
> 0014 80916000          lds R24,96
3
> 0018 8862              ori R24,40
4
> 001A 80936000          sts 96,R24

lds   2 Takte
ori   1 Takte
sts   2 Takte

Macht 5, das ist einer zu viel.
Gast #1841274
Lesenswert?

Hallo,

genial - sobald man's richtig macht, klappt es auch. Hab das Beispiel 
aus dem Datenblatt zum Mega644 abgeschrieben, aber bei all der sonstigen 
Bit-Setzerei nicht beachtet, dass man ja direkt schreibt und nicht 
verodert.
Vielen Dank an alle für die schnelle Hilfe!

Gruß
Tim

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren