mikrocontroller.net

Forum: Compiler & IDEs Watchdog mega48


Autor: Uwe M. (lifthrasil)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Uwe M. (lifthrasil)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Juergen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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>

Autor: Uwe M. (lifthrasil)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Uwe M. (lifthrasil)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.