Hallo zusammen, ich bin Neuling auf dem Gebit uC-Programmierung und
möchte gerne beim auftreten eines bestimmten Zustandes in meinem
Programm, einen Reset auslösen. Ich programmiere einen ATmega2560 in C.
Nun habe ich gelesen das hierbei der Watchdog mir Abhilfe schaffen kann.
Im Tutorial habe ich gelesen, dass ich zunächst die #include <avr/wdt.h>
einfügen muss.
Gut, aber wie muss ich jetzt weitermachen?
void wdt_init(void)
{
MCUSR = 0;
wdt_disable();
return;
}
kann ich dann einfach beim Auftreten von error wdt_reset() schalten und
mein Programm resetet?
if( error == 1 )
{
wdt_reset();
}
würde das so passen ich check das irgenwie immer noch nicht so ganz mit
der Watchdog-Geschichte.
Das geliche ist, wenn ich auf ein Flag warten will und das wird
innerhalb einer bestimmten Zeit nicht gesetzt, wie muss ich da vorgehen?
Bin über jede Hilfe glücklich.
uC-Anfänger schrieb: > void wdt_init(void) > { > MCUSR = 0; > wdt_disable(); > return; > } > kann ich dann einfach beim Auftreten von error wdt_reset() schalten und > mein Programm resetet? > if( error == 1 ) > { > wdt_reset(); > } > würde das so passen ich check das irgenwie immer noch nicht so ganz mit > der Watchdog-Geschichte. Nein. Sinn und Zweck eines Watchdog ist es, den Controller zu resetten, wenn sich das Programm an irgendeiner Stelle aufgehängt hat. Man kann den Watchdog natürlich auch zum gezielten Resetten benutzen, indem man diesen Zustand herbeiführt. Erstmal wird der Watchdog gestartet: wdt_enable(value) "value" ist ein Wert für die Zeit, genaugenommen wird damit der Prescaler eingestellt, nach der ein Reset durchgeführt wird. Damit startet man den Watchdogtimer. Wenn dieser Timer überläuft, wird ein Reset ausgeführt. Damit das nicht passiert, gibt es die Funktion "wdt_reset()". Damit wird der Zähler wieder auf 0 gesetzt. Diese Funktion baut man nun an geeigneter Stelle im Programm ein, meist in der Hauptprogrammschleife. Kehrt das Programm jetzt beispielsweise nicht rechtzeitig aus einer Interruptbehandlung zurück, läuft der Zähler über und es gibt einen Reset. Um einen gezielten Reset herbeizuführen, muß der WDT erstmal beim Start des Programms abgeschaltet werden: wdt_disable(); In der Funktion, die den Reset ausführen soll, startest du dann den Watchdog mit der kürzest möglichen Zeit: wdt_enable(0); Das sind ungefähr 15 oder 16 ms, schneller geht nicht, und wartest auf den Reset: while(1){} uC-Anfänger schrieb: > Das geliche ist, wenn ich auf ein Flag warten will und das wird > innerhalb einer bestimmten Zeit nicht gesetzt, wie muss ich da vorgehen? Das machst du so ähnlich. Du lässt einen Timer laufen, der nach der Time-Out-Zeit überläuft und einen Interrupt auslöst. Den Timer startest du, wenn du auf das Flag wartest und stoppst ihn, nachdem du das Flag erhalten hast. Oder wenn du etwas über den UART gesendet hast und auf Antwort wartest. Dauert es zulange, läuft der Timer über und löst einen Interrupt aus. Für längere Zeiten oder wenn du den Timer auch noch für etwas anders nutzen willst, baut man eine oder mehrere Variablen ein und fragt die entsprechend ab. mfg.
uC-Anfänger schrieb: > Das geliche ist, wenn ich auf ein Flag warten will und das wird > innerhalb einer bestimmten Zeit nicht gesetzt, wie muss ich da vorgehen? Das macht man nicht mit dem Watchdog, da dieser einen echten Reset auslöst. D.h. sämtliche gerade laufenden Tasks werden gekillt und das will man ja nicht. Sieht auch äußerst unprofessionell aus, wenn LEDs und Displays flackern, Relais klappern, Motoren stottern, Einstellungen vergessen werden usw. Man setzt daher einen Timeout-Handler auf. Ein Timerinterrupt prüft, ob eine bestimmte Zeit vergangen ist und ruft diesen dann auf. Erfolgt das gewünschte Ereignis rechtzeitig, wird der Timeout-Handler wieder gestoppt (Zeitvariable = 0). Peter
Hallo zusammen, Danke für die Antworten. Wenn ich einen ERROR detektiere, möchte ich aber einen Reset auslösen. Da eignet sich der Watchdog ja soweit dafür. Also im Grunde muss ich ja nur die Header <avr/wdt.h> einbauen und bei if( error == 1 ) wdt_enable(0); setzen, oder? Aber ich muss den doch auch irgendwie initialisieren. Muss ich zu Beginn des Programmes, in meiner main, den Watchdog erst deaktivieren? Wäre nett wenn mir hierzu vielleicht jemand nochmals helfen könnte. VG
uC-Anfänger schrieb: > Muss ich zu Beginn des Programmes, in meiner main, den Watchdog erst > deaktivieren? Beim ersten Mal nicht. Aber nach einem Watchdog-Reset bleibt der Watchdog eingeschaltet. Und würde sonst sofort wieder nach Ablauf der Verzögerung resetten. mfg.
OK zusammenfassend also: - <avr/wdt.h> einbinden - wdt_disable() in main setzen - dann in meine main-loop - if(error == 1) wdt_enable(0); --> reset!!! --> wdt_disable() --> ab in die main-loop und weiter gehts
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.