Watchdog reset

Gast #346237
Lesenswert?
• ▲
▼
Hallo nochmal,

So in der Art sollte das Einstellen des Watchdogs doch funktionieren
oder?
Übergabewerte:
- watchdog_presc -> Wertebereich 0x0 - 0x9 -> entspricht 2k-1024k
  clock cycles
- watchdog_mode -> Wertebereich 0x0 - 0x3:
                   0x0 = stopped, 0x1 = isr, 0x2 = System reset,
                   0x3 = isr & system reset

void watchdog_config(unsigned char watchdog_presc, unsigned char
watchdog_mode)
{
 switch(watchdog_mode)
 {
 case 0x0:  WDTCSR |= (1<<WDCE) | (1<<WDE);
                WDTCSR = 0x0;
                break;
 case 0x1:  WDTCSR |= (1<<WDCE) | (1<<WDE);
                WDTCSR = (watchdog_presc&0x7) |  \
                         ((watchdog_presc&0x8)<<2) | (1<<WDIE);
                break;
 case 0x2:  WDTCSR |= (1<<WDCE) | (1<<WDE);
                WDTCSR = (watchdog_presc&0x7) |\
                         ((watchdog_presc&0x8)<<2) | (1<<WDE);
                break;
 case 0x3:  WDTCSR |= (1<<WDCE) | (1<<WDE);
                WDTCSR = (watchdog_presc&0x7) |\
                         ((watchdog_presc&0x8)<<2) | (1<<WDIE) | \
                         (1<<WDE);
                break;
 default:   WDTCSR |= (1<<WDCE) | (1<<WDE);
                WDTCSR = 0x0;
 }
}

nur wie läuft das mit dem Rücksetzen ab?!?
Einfach "WDR = 0;"?
Gast #346238
Lesenswert?
• ▲
▼
> "WDR = 0;"

Was soll das sein? 'wdr' ist ein Assembler-Befehl. Dem kann man
keinen Wert zuweisen. Entweder, Du fügst den wdr-Befehl per
Inline-Assembler ein (da Du nicht erzählst, welchen C-Compiler Du
benutzt, kann ich natürlich nicht konkret sagen, wie es in Deinem Fall
auszusehen hat) oder Du benutzt eine Bibliotheksfunktion bzw. -Makro.

In AVR-GCC-C läuft das entweder direkt über

asm volatile ("wdr"); //Inline-Assembler

oder mit

#include<avr/wdt.h>
//...
wdt_reset();

wobei das Makro wdt_reset() auch nix anderes macht, als den
Assembler-Befehl wdr inline einzusetzen.

In CodeVision gehts z.B. mit #asm("wdr")
Gast #346239
Lesenswert?
• ▲
▼
Hallo Jonny,

danke für deine Antwort! Ich benutze AVR-GCC-C. Genau das war es was
mir gefehlt hat. Kenn mich mit assembler leider net wirkl aus :).

Eine Frage hätte ich noch dazu:
Ich habe schon einen inline-Assembler Sleep-Befehl. Bei dem sind zwei
"::" am Ende. Kannst du mir erklären, was das bedeutet?

asm volatile ("sleep"::);   //:: am ende == ??

Grüße
Gast #346240
Lesenswert?
• ▲
▼
Lt. AVR-libc-Doku
(http://www.nongnu.org/avr-libc/user-manual/inline_asm.html) muss bei
Inline-Assembler immer die Parameter-Liste, deren erforderliche Teile
(Input- und Output-Parameter) durch Doppelpunkte getrennt werden,
angegeben werden, auch wenn sie leer ist. Die angesprochene Doku
scheint sich allerdings auf eine ältere Version zu beziehen. Aktuell
kann man bei parameterlosen Befehlen wie sleep, wdr, nop usw. die
Doppelpunkte weglassen. Wenn man sie trotzdem macht ist auch nicht
schlimm...

Vielleicht ist ja einer der WINAVR-Experten grade irgendwo hier in der
Gegend (Hallo Jörg Wunsch, kannst Du uns hören?) und kann das
kommentieren (ab welcher Version, warum usw..)

Gruß

Johnny
Gast #346241
Lesenswert?
• ▲
▼
Danke für die Info!

Der funktionierende Code lautet: (net dass des oben wer rauskopiert u
es funzt net ;)

void watchdog_config(unsigned char watchdog_presc, unsigned char
watchdog_mode)
{
cli();
unsigned char temp = 0x0;
temp = (watchdog_presc & 0x7)| ((watchdog_presc&0x8)<<2);

switch(watchdog_mode)
{

case 0x0:  asm volatile ("wdr"::); //Watchdog reset
    MCUSR &= ~(1<<WDRF);    //Flag zurücksetzen
                WD_CONTROL |= (1<<WD_CHANGE) | (1<<WD_ENABLE);
    WD_CONTROL = 0;
    break;
case 0x1:  asm volatile ("wdr"::); //Watchdog reset
    WD_CONTROL |= (1<<WD_CHANGE) | (1<<WD_ENABLE);
    WD_CONTROL = temp | (1<<WD_ISR);
    break;
case 0x2:  asm volatile ("wdr"::); //Watchdog reset
    WD_CONTROL |= (1<<WD_CHANGE) | (1<<WD_ENABLE);
    WD_CONTROL = temp | (1<<WD_ENABLE);
    break;
case 0x3:  asm volatile ("wdr"::); //Watchdog reset
    WD_CONTROL |= (1<<WD_CHANGE) | (1<<WD_ENABLE);
    WD_CONTROL = temp | (1<<WD_ISR) | (1<<WD_ENABLE);
    break;
default:   asm volatile ("wdr"::); //Watchdog reset
    WD_CONTROL |= (1<<WD_CHANGE) | (1<<WD_ENABLE);
    WD_CONTROL = 0x0;
}
sei();
}
Gast #455603
Lesenswert?
• ▲
▼
"Schau mal in die avr/wdt.h. Da gibts mehrere Funktionen, die im Prinzip
genau das machen, was Du da programmiert hast."

aber nicht ganz, z.B. den Watchdog als interrupt einstellen gibts da 
nicht

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 20 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.