Forum: Compiler & IDEs Watchdog mega48


von Uwe M. (lifthrasil)


Lesenswert?

Hallo,

der WDT des mega48 lässt sich auf 4 unterschiedliche Weisen
initialisieren (Stopped, Interrupt Mode, System Reset Mode und
Interrupt and System Restet Mode (vgl. DS s.52)). avr-gcc 3.4.3 stellt
Makros zum Ein- bzw. Abschalten und zum Reset des WDT bereit. Der WDT
wird dann immer im System Reset Mode initialisiert. Mich interessiert
allerdings der Interrupt Mode und ich habe Versucht meine eigene
Initfunktion dafür zu schreiben:

void WDTInitIntMode(UINT8_T byTimeout){
   cli();
   wdt_reset();
   // MCUSR &= ~(1<<WDRF);      // ??
   WDTCSR = 0x10;               // bit zum Ändern der WDT Settings
   WDTCSR = 0x50 | byTimeout;   // WDIE + gewünschter Timeout
   sei();
}

allerdings funktioniert das nicht. Zwar wird wie gewünscht WDIE gesetzt
aber der Timeout nicht. Auch meine ISR wird nie angesprungen (sei() ist
gemacht):

ISR(WDT_vect){
   byTimer++;
}

Mein Debugger ist der JTAG mkII AVRStudio (V. 412 SP1). Beim debuggen
damit sieht es so aus als würde trotz WDEN = 0. Ein Reset ausgelöst
(Breakpoint vor Endlosschleife wird angesprungen) ... allerdings sieht
es auf der Hardware so aus als würde das nie passieren?? Also ...

1.) Warum funktioniert das setzten von WDIE aber nicht WDP2..0?
2.) Was ist an meiner ISR falsch?
3.) Warum wird beim debuggen so komisch in der Gegend
"rumgesprungen"?

so long ... Uwe

von Uwe M. (lifthrasil)


Lesenswert?

Ich hab noch was vergessen beim compilieren bekomm ich die Warnings:

../../src/main.c:8: warning: return type defaults to `int'
../../src/main.c: In function `ISR':
../../src/main.c:10: warning: control reaches end of non-void function

woher kommt das?

von Juergen (Gast)


Lesenswert?

In deiner Zeile
WDTCSR = 0x10;
wird nur ein Bit gesetzt. Um die Einstellungen zu ändern müssen aber
WDCE und WDE im gleichen Schritt auf 1 gesetzt werden. Danach kanst du
im nächsten Schritt die neuen Werte setzen, dabei muss WDCE aber 0 sein

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> ../../src/main.c:8: warning: return type defaults to `int'
> ../../src/main.c: In function `ISR':
> ../../src/main.c:10: warning: control reaches end of non-void
function

#include <avr/interrupt.h>

von Uwe M. (lifthrasil)


Lesenswert?

Hallo Jörg und Jürgen,

danke für die prompte Antwort ... ich hab das ganze jetzt hingekriegt
allerdings nur so:

#include <avr/interrupt.h>
#include <avr/signal.h>

void WDTInitIntMode(UINT8_T byTimeout){
   cli();
   wdt_reset();
   WDTCSR = 0x18;
   WDTCSR = 0x50 | byTimeout;
   sei();
}

SIGNAL(SIG_WATCHDOG_TIMEOUT){
   byTimer++;
}

ab welcher avr-gcc Version gibts den ISR(..) (meine 3.4.3)? Hab gelesen
das SIGNAL bzw. INTERRUPT eigentlich nicht mehr verwendet werden
sollten? Und wie kann ich mein avr-gcc updaten? Hab mal das neue WinAVR
(20060125) versucht allerdings hatte ich damit ziemliche Probleme?

Gruß Uwe

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> ab welcher avr-gcc Version gibts den ISR(..) (meine 3.4.3)?

avr-libc 1.4

> Hab mal das neue WinAVR (20060125) versucht allerdings hatte ich
> damit ziemliche Probleme?

Das wäre für Windows-Nutzer aber vermutlich der praktikabelste Weg.

Wenn du damit Probleme hast, solltest du diese in einem separaten
Thread thematisieren, damit dir geholfen werden kann.

von Uwe M. (lifthrasil)


Lesenswert?

Ok ich hab das ganze jetzt doch upgedatet gekriegt ... allerdings läufts
jetzt wieder nicht mehr ... lol.

void WDTInitIntMode(UINT8_T byTimeout){
   cli();
   wdt_reset();
   WDTCSR = 0x18;
   WDTCSR = 0x42;   // zur vereinfachung mal ohne byTimeout
   sei();
}

Dissasembly:

@000000B3: WDTInitIntMode
54:       void WDTInitIntMode(UINT8_T byTimeout){
+000000B3:   94F8        CLI                      Global Interrupt
Disable
56:          wdt_reset();
+000000B4:   95A8        WDR                      Watchdog reset
57:          WDTCSR = 0x18;
+000000B5:   E188        LDI     R24,0x18         Load immediate
+000000B6:   93800060    STS     0x0060,R24       Store direct to data
space
58:          WDTCSR = 0x42;
+000000B8:   E482        LDI     R24,0x42         Load immediate
+000000B9:   93800060    STS     0x0060,R24       Store direct to data
space
59:          sei();
+000000BB:   9478        SEI                      Global Interrupt
Enable
+000000BC:   9508        RET                      Subroutine return

sieht ja alles so weit ganz gut aus allerdings steht WDTCSR danach
immer auf 0x4A statt 0x42?? Mit der alten Version von WinAVR hats
funktioniert (jetzt gcc 3.5.4 avr-libc 1.4.3)! Irgendwelche Tipps?

Gruß Uwe

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.