Hallo Zusammen, Ich bin gerade dabei den Watchdog zum ertsen Mal nicht abzuschalten. Bisher stellt sich noch nicht das gewünschte Ergebnis ein. Nur damit ich es richtig verstanden habe: Statt den Watchdog mit WDTCTL = WDTPW + WDTHOLD auszuschalten setze ich am Anfang der main() irgendein Intervall WDTCTL = WDTPW + WDTIS0 und dann später im Code mit WDTCTL = WDTPW + WDTCNTCL den Counter zurück. Hat sich das Programm aufgehängt geschieht dies nicht und es wird ein Reset ausgeführt, oder ? Mit diesen Einstellungen macht mein Program gar nix mehr. Ich denke mal, dass ich da irgendwas falsch verstanden habe... Gruß Seb
>am Anfang der main() irgendein Intervall WDTCTL = WDTPW + WDTIS0 Am besten noch ein WDTCNTCL mit rein damit du wirklich bei 0 startest. >und dann später im Code mit WDTCTL = WDTPW + WDTCNTCL den Counter zurück. "Später" solltest du aber genau berechnen, nicht das du den richtigen Zeitpunkt verpasst :) >Hat sich das Programm aufgehängt geschieht dies nicht und es wird ein >Reset ausgeführt, oder ? Ja. >Mit diesen Einstellungen macht mein Program gar nix mehr. Ich denke mal, >dass ich da irgendwas falsch verstanden habe... Dann berechne mal ob du den Counter rechtzeitig zurücksetzt.
>Mit diesen Einstellungen macht mein Program gar nix mehr. Ich denke mal, >dass ich da irgendwas falsch verstanden habe... So trivial der Watchdog erscheinen mag... die Tücke liegt doch manchmal im Detail ;-) Die sichere Vorgehensweise ist sicherlich den WDT in der aller ersten Anweisung in main() wie gewohnt erst mal zu deaktivieren:
1 | WDTCTL = WDTPW + WDTHOLD; |
Dann erfolgen alle Initialisierungen, die für Deine Applikation erforderlich sind. Erst bevor Deine eigentliche Hauptprogrammschleife beginnt, den WDT aktivieren:
1 | WDTCTL = WDTPW + WDTISx + WDTCNTCL; |
und natürlich sicherstellen, dass das Zurücksetzen des WDT
1 | WDTCTL = WDTPW + WDTCNTCL; |
immer vor Ablauf des WDT-Intervalls geschieht. >Hat sich das Programm aufgehängt geschieht dies nicht und es wird ein >Reset ausgeführt, oder ? Ein PUC um genau zu sein, kein POR! Zur Tücke: Wenn Du viele Variablen angelegt hast und Dein Compiler meint, er müsse diese alle erst initialisieren und dazu einen startup-code generiert, dann wird dieser startup-code vor Deiner main() ausgeführt. Dauert dies länger als das WDT-Intervall, dann läuft Dein µC von einem PUC in den nächsten, ohne jemals in der main() vorbeizukommen. In dem Falle, kannst Du nur den startup-code manuell modifizieren (WDT da drin ausschalten) oder weniger Variablen initialisieren lassen.
Ok, es beruhigt mich schonmal, dass ich ein paar Sachen richtig verstanden habe. Danke für eure Antworten, weil: 1. Habe ich den genauen Zeitpunkt nicht berechnet. und 2. Gibt es tatsächlich eine Reihe von Variablen. Jetzt werde ich mal weitertüfteln und mich ggf. nochmal melden. Gruß Seb
Hallo Stefan, Eigentlich habe ich alle deine Vorschläge berücksichtigt und trotzdem habe ich das Problem, dass mein Programm mit Watchdog unzuverlässiger ist als ohne. Das Programm wird zwar zurückgesetzt, jedoch viel öfter als mir lieb ist. :-) Habe als Referenz den ACLK und ein Intervall von WDTIS0 (4 sek) gewählt. Auch längere Intervalle brachten keine Besserung. Nehme ich den watchdog wieder raus ist alles paletti und ich bekomme meine Daten alle 100 ms ausgegeben. Trotzdem brauche ich die Sicherheit, dass sich im Falle eine Falles das Programm zurücksetzt. Irgendwie bin ich da etwas überrascht und stehe nun aufm Schlauch. Gruß Seb
>Das Programm wird zwar zurückgesetzt, jedoch viel öfter >als mir lieb ist. :-) Hört sich jetzt so an, als ob es gewollt sei, dass der WDT das Programm zurücksetzt... das ist nicht der Sinn dabei! Ohne weitere Informationen kann ich Dir leider auch nicht weiter helfen! Häng doch mal Dein Programm als formatierten Code an, mit µC-Typ und ACKL-Quelle (32kHz?)
Nein nein, so ist das natürlich nicht gewollt. Ich wollte damit nur sagen, dass der watchdog zwar bei Problemen richtig reagiert, aber das Programm einfach nicht mehr dazu kommt seine normalen Aufgaben zu erfüllen. ACLK ist 32 kHz Programm ist insg. sehr groß. Werde vielleicht mal ein paar wichtige Fragmente rausschneiden.
Seb wrote: > Nein nein, so ist das natürlich nicht gewollt. Ich wollte damit nur > sagen, dass der watchdog zwar bei Problemen richtig reagiert, aber das > Programm einfach nicht mehr dazu kommt seine normalen Aufgaben zu > erfüllen. > > ACLK ist 32 kHz > > Programm ist insg. sehr groß. Werde vielleicht mal ein paar wichtige > Fragmente rausschneiden. Was soll das bringen? Du musst dir halt überlegen, wie lang einzelne Programmteile dauern, wenn sie richtig abgearbeitet werden. Danach dann immer den Hund treten. Wenn das nicht passiert, hat sich das Programm festgefahren.
Vielleicht habe ich mich missverständlich ausgedrückt, aber genau das will ich ja erreichen. Das Programm braucht im Normalfall Bruchteile einer Sekunde, um seine Aufgabe zu erledigen. Ohne watchdog klappt dies zumeist auch wunderbar (und länger als eine Minute). Wenn ich den Hund dann wie oben erwähnt einstelle und in der main_loop den Counter zurücksetzen lasse, kommt es fast immer zu einem verfrühten reset des Programmes, obwohl eigentlich 4 Sekunden (ohne Zurücksetzen des Counters) bis zu einem reset gewartet werden sollen.
So, sitze nun wieder am watchdog und das Problem bleibt das Gleiche. Der PUC wird zu schnell ausgeführt, ergo setze ich den Timer wohl nicht schnell genug zurück. Habe schon einige Einstellungen ausprobiert und auch mal den Referenztakt geändert, aber das Ergebnis bleibt gleich. Der Programmausschnitt ist gekürzt, um Übersichtlichkeit beizubehalten. Refrenztakt ist der ACLK (32Khz). Habe ich nun mit WDTIS0 eine "watchdog-Zeit" von 4 s eingestellt ?
1 | //Interrupts initialisieren
|
2 | |
3 | // Initialisierung der Variablen nach Modulen:
|
4 | |
5 | // Variablen....
|
6 | |
7 | |
8 | |
9 | void main (void) |
10 | {
|
11 | |
12 | WDTCTL = WDTPW + WDTHOLD; // Watchdog stoppen |
13 | |
14 | |
15 | // Initialisierung aller nötigen Funktionen und Module :
|
16 | |
17 | INIT(); |
18 | |
19 | WDTCTL = WDTPW + WDTSSEL + WDTIS0 + WDTCNTCL; // Watchdog einschalten |
20 | |
21 | |
22 | while (1) |
23 | {
|
24 | |
25 | WDTCTL = WDTPW + WDTCNTCL ; // watchdog counter zurücksetzen |
26 | |
27 | }
|
28 | |
29 | }
|
30 | |
31 | |
32 | // Im Timer_A findet alle 100 ms eine Messung statt
|
33 | |
34 | |
35 | __interrupt void Timer_A (void) |
36 | {
|
37 | |
38 | static bool ledOn = false; |
39 | |
40 | |
41 | StartMeasurementHardware(); |
42 | |
43 | while(P3IN&0x20==1); |
44 | |
45 | ReadReg(0x00,bufferPress); |
46 | |
47 | DatenMitFunkVersenden (bufferPress); // |
48 | |
49 | }
|
nett, lass uns doch daran teilhaben, wenn du dir schon die Mühe machst zu sagen, dass du den Fehler gefunden hast ;-) naja, ich habs dann auch rausgefunden: Beitrag "Re: Watchdog MSP430 mit TIMERB zurücksetzen"
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.