Forum: Mikrocontroller und Digitale Elektronik Watchdog läßt sich nicht stoppen


von Wilfried J. (wilfried)


Lesenswert?

Hallo, ich bin ein Neuling der Programmierung. Ich hoffe, ich bin hier
richtig. Nun zu meinem Problem:
Ich programmiere für den ATMega88 eine Empfängerschaltung für USART,
Daten werden konvertiert und über TWI an eine Motorsteuerung übergeben.
Das funktioniert (auch mit Interruptsteuerung) einwandfrei. Nun soll
diese Schaltung so ganz nebenbei auch einen Accu laden bzw. überwachen
- das funktioniert auch. Nun möchte ich, wenn der ACCU ganz leer ist,
den Prozessor schlafen legen (SLEEP). Dummerweise ist auch ein Watchdog
programmiert, weil die Schaltung über lange Zeit unbeobachtet (im
Wohnwagen) ist. Will ich den Watchdog ausschalten, verwende ich die
Sequenz aus dem ATMEL Datenblatt:
__disable_interrupt ();
__watchdog_reset ();
MCUSR &= ~(1<<WDRF);
WDTCSR |= (1<<WDCE) | (1<<WDE);
WDTCSR = 0x00;
Dann den Sleep-Mode Power Down und __SLEEP ();
Der Prozessor kümmert sich überhaupt nicht darum und läuft immer wieder
in diese Routine und wieder und wieder....
Wenn ich den Watchdog nicht einrichte, dann legt er sich schlafen, also
kann nur er daran Schuld sein. Ich habe schon alle möglichen
Schreibweisen probiert, aber kein Erfolg. Das Internet gibt auch nicht
viel her zu diesem Thema, bzw. bechreibt immer nur das selbe wie im
Datenblatt. Ich habe auch schon mit wdt.h probiert, aber die
verfügbaren funktionieren nicht mit dem ATMega88. Bitte Hilfe, ich
verzweifle sonst.  Danke.

Wilfried

von Wilfried Jahn (Gast)


Lesenswert?

Kann das sein?
60 mal gelesen und keiner weiß eine Antwort. Sollte dieses Problem noch
nicht irgendwo anders aufgetreten sein?
Sollte ich den Fehler doch noch selber finden, werde ich es hier
posten. Trotzdem Danke für die Aufmerksamkeit.

Wilfried

von Thomas J. (Gast)


Lesenswert?

Wird der Watchdog etwa per WDTON-Fuse aktiviert ? Falls das der Fall
ist lässt er sich nicht durch Software abschalten.

Gruss Thomas

von Wilfried J. (wilfried)


Lesenswert?

Leider nein, sonst hätte ich jetzt den Fehler. Der ATMega ist im
Auslieferungszustand (die Fusebits betreffend). Wenn ich das Datenblatt
richtig verstehe (was für Anfänger nicht selbstverständlich ist), dann
ist WDTON defaultmäßig 1 (unprogrammed) und das soll heißen wegen der
Invertierung "nicht gesetzt". Ich habe mir mit den Versuchen zu
Fusebits bereits 2 Meags erschossen, obwohl ich im Internet darüber
schon viel gelesen habe. AVRDude bringt mir beim Lesen der Hfuse 0x20
und Lfuse 0x9D, das sollte richtig sein.

Gruß (und danke)
Wilfried

von ecslowhand (Gast)


Lesenswert?

Hallo Wilfried !

Ich habe beim Mega88 keine Probleme beim Watchdog ausschalten. Habe
ebenfalls den Code aus dem Datasheet übernommen, allerding in
Assembler.

Ich initialisiere den WD direkt nach dem Rest, zuvor kommt lediglich
noch der Stackpointer .

Wenn die Fuses richtig sind, kanns eigentlich nur noch an den
Interruptvectoren liegen. Würde ich mal überprüfen.

Schau noch mal nach bezüglich des Watchdogtimer-Prescalers. Hierzu gibt
es auch eine Anmerkung im Datasheet.

Viel Glück, EC

von Wilfried J. (wilfried)


Lesenswert?

Hallo ecslowhand,

habe jetzt das Programm abgespeckt und es ist nur noch die Routine mit
dem Watchdog und sleep vorhanden (die includes und variablendef.
natürlich auch). Habe auch schon mit ATMEL Support Kontakt, die meinen,
daß mein Code "seems to be OK" sei. Das Einzige, was sie sich
vorstellen können, ist die 4 Clock - Sache. Aber ich verwende doch das
originale Programm aus dem datasheet, da sollte man doch meinen es ist
in Ordnung. Mein Chef hat gestern gemeint, nachdem ich ihm die
Einstellung der Fusebits erklärt (so wie ich es verstehe) hatte, ich
sollte doch das WDTON mal ändern, vielelicht ist das Datenblatt nicht
OK. Nachdem ich dann mit AVRDUDE die Batch - Zeile aus
http://www.klaus-leidinger.de/mp/Mikrocontroller/AVR-Prog/AVR-Programmer.html
"avrdude -p ATMEGA88 -P COM3 -b 38400 -c avr910  -U hfuse:w:0x30:m"
eingegeben und ausgeführt hatte, meldete AVRDUDE, daß er beim Verify
nicht 30 sondern 10 gelesen hat, bietet recovery an um dann zu sagen
sorry! 10 heißt, daß SPIEN programmiert ist und das wars dann für ISP.
Es wäre mal gut, wenn mir jemand die Sache mit den Fusebits für den
Mega88 genau erklären könnte, sonst werde ich noch Großabnehmer bei
Atmel und wir sollten doch unser Geld im Land lassen.
Jetzt werde ich den Lötkolben anwerfen.

Wilfried

von ecslowhand (Gast)


Lesenswert?

Moin Wilfried !

Das WDTON-Bit im HighFuseByte musst Du auf "1" setzen, wenn Du den WD
nicht benutzen möchtest. Dies ist auch der Defaultwert bei
Auslieferung.

Mit den Fusebits ist das eigentlich eine simple Sache, Verwirrung gibts
nur, weil eine "1" nicht unbedingt "enabled" heisst.

Schau doch mal im aktuellen Datasheet (REV G) nach auf Seite 283ff.
Mach Dir doch in Excel o.ä. eine Tabelle, die Dir die Fuses berechnet
und dabei einige "spezielle" wie z.B. SPIEN und auch die CKSELx fix
setzt, damit es keine bösen Überraschungen gibt.

Bezüglich der WD-Initialisierung schaue auch mal ins Datasheet Seite
53.


Lg EC

von Mark H. (haemi)


Lesenswert?

Weil's grad ums Berechnen der Fuse-Werte ging...

Der Online-Fuse-Rechner ist abrufbar unter: http://palmavr.sf.net/fc/

Ich muß aber nachwievor darauf hinweisen, daß Atmels XML-Files
(hauptsächlich bei älteren AVR-Modellen) teilweise widersprüchlich bis
falsch sind. Und da diese XML-Files das Backend des Rechners bilden,
kann es zu falschen Ausgaben kommen.

Nähere Infos hier:
http://www.mikrocontroller.net/forum/read-1-305204.html

Mark

von Wilfried J. (wilfried)


Lesenswert?

Hallo an Alle,

habe mir gerade die neue Version "G" von Atmel geholt, aber da steht
nicht viel Neues drin für meine Sache. Ich habe gelesen auf der Seite
283, daß SPIEN nicht über die serielle Programmierung verädert werden
kann. Warum hat dann AVRDUDE die 0x20 der hfuse nicht in 0x30 wie
gewollt, sondern in 0x10 geändert (SPIEN = 1, also unprogrammiert). Ich
habe normalerweise überhaupt kein Problem (ich bin schon älter, aus der
Zeit des 8080) mit der Umrechnung von hex nach binär oder Wertigkeiten
oder..., aber hier steige ich offensichtlich aus. Für den nächsten
Versuch mit dem WD dauert es noch etwas, denn ich muß auf der
selbstgeäzten Platine schon zum 3. mal den Prozessor (TQFP32)
wechseln.

Wilfried

von ecslowhand (Gast)


Lesenswert?

Bist Du sicher, das der WD das Problem erzeugt ???
Oben schreibst Du : "Der Prozessor kümmert sich überhaupt nicht darum
und läuft immer wieder
in diese Routine und wieder und wieder....".

Welche Routine ? Die der WD-Initialisierung ? Oder macht der ATMEGA
"zufällig" einen Reset ?

TIPP: Gib Dir doch als erstes (also nach dem power-on-reset) mal das
MCUSR-Register aus (per rs232 oder Leds oder..).

Deaktiviere mal den Sleep-Mode (ist ja auch recht komplex
einzustellen), nicht das Du Dir da irgendwas "ins Gemüse haust".

LG EC

von Wilfried J. (wilfried)


Angehängte Dateien:

Lesenswert?

Hallo ecslowhand,

jetzt kommt ja richtig Leben rein, das macht ja Spaß.
Vielleicht denke ich ja falsch, aber wenn ich den Wachhund erst nicht
enable, also die Initialisierung nicht anspringe, dann schläft der
Prozessor wunderbar und läßt sich nur durch Resetknopf oder aus-ein
wieder zum Leben erwecken, genauso wie ich es haben will. Die Routine,
die ich meine, ist eine Endlosschleife, in der der Accu gemessen wird
und Verschiedenes, wie voll, halbvoll, fastleer, ganzleer (dann soll er
schlafen) erkannt wird und entsprechende Maßnahmen eingeleitet werden
sollen. Eine davon ist eben schlafen. Ich habe das Programm ja schon
abgespeckt, USART, TWI und Interruptsteuerung ist raus. Eine LED hat
bis zur letzten Änderung permanent geleuchtet, die hat im Fehlerfall
dann schnell geblinkt, so als ob das Programm nur bis zum sleep läuft
und dann resetiert wird.
Wer mir verspricht, nicht zu lachen, der kann die PDF im Anhang
anschauen - ich programmiere erst seit ein paar Monaten in C und hab'
mehr auf Erfolg gesetzt als auf programmieren lernen (der Druck von
oben). Das Meiste hab' ich auch schon geschafft, bis auf....

Wilfried

von Wilfried J. (wilfried)


Lesenswert?

Hallo, hallo,

ich muß da nochmal eingreifen, wenn die PDF so oft angeschaut wird. Das
Programm ist noch lange nicht fertig! Wenn es fertig wird (hoffentlich)
soll es jeden Accuzustand erkennen und auch eine Erhaltungsladung
machen können. Auch habe ich schon an die Steuerung verschiedener
Ladeströme gedacht oder die Erkennung von Accutypen (das wird aber
schwierig).
Oder will da nur jemand etwas zu lachen?

Wilfried

Übrigens ecslowhand, die Vorbereitung für den sleep ist meiner Meinung
nach ganz einfach - nur zwei Zeilen - funktionieren tut es, auch wenn
es zu einfach sein sollte.

von ecslowhand (Gast)


Lesenswert?

Damit meinte ich die verschiedenen Konfigurationen (sleep, powerdown,
powersave,...). Die "Wakeup"-Initialisierungen der entsprechenden
Module  wird oft vergessen und plötzlich macht der Prozessor nicht das,
was man sich erhofft (erdacht) hat.

LG EC

von Wilfried J. (wilfried)


Lesenswert?

Hallo ecslowhand,

OK, verstanden. In meinem Fall soll ja nur ein Reset oder Spannung
unterbrechen wieder zum Start führen, da brauch ich mir auch keine
Gedanken machen, den Knopf wird jeder finden.
Übrigens, Platinchen läuft wieder. Aber das nächste Mal wird es eine
Flickerei. Es sind schon 2 Pad's angehoben. Nach dem Neuprogrammieren
ist mir dann aufgefallen, daß ich auch den Aufruf "init_usart();"
gelöscht habe - bei soviel Unterspannung ist allerdings mein Fehler
sofort wieder aufgetreten.
Hatte gerade eine kleine Pause während des Schreibens. Ich habe die
"wdt_init" mal disabled und hab' mich gewundert, warum der Fehler
immer noch auftritt. Erst nachdem ich auch den Aufruf "wdt_off" mit
// behandelt hatte, geht er wieder in den Schlafmodus. Das heißt, meine
Routine "wdt_off" schaltet den Hund EIN! UND DAS SOLL NICHT SEIN!

Wilfried

von Axel R. (Gast)


Lesenswert?

1
void wdt_off ()
2
{
3
__disable_interrupt ();
4
__watchdog_reset ();
5
 
6
   MCUSR = 0x00;
7
   WDTCSR |= (1<<WDCE) | (1<<WDE);
8
   WDTCSR = 0x00;
9
10
__enable_interrupt ();
11
}

kann man sich ja nun eigentlich nur noch so erklären, das das verodern
und zurückschreiben evtl. länger als 4Takte dauert.
Kannst Du dir nicht mal den erzeugten ASM der Routine wdt_off()
ausgeben lassen? Vlt. istz die Compileroptimierung irgentwie blöd
eingestellt und es dauert 5 oder 6 Takte.
Denn erst bei Atmega 48/88 usw. "liegt" der Watchdog im extenden
IO-Bereich und ist nicht mehr mit IN/OUT, sondern mit STS/LDS ect. zu
erreichen. Das braucht wohl zwei Takte länger.
Allerdings sollte der IAR da locker irgentwas fertiges bei haben, um
den Watchdog ein-und auschaltzen zu können, oder?

von Wilfried J. (wilfried)


Angehängte Dateien:

Lesenswert?

Hallo Axel,

daran habe ich auch schon gedacht und den Wert als 0x1e ausgegeben. Der
Abstand zwischen dem ersten sts und dem nächsten sind eigentlich nur 2
Taktzyklen. Nämlich der nächste Ladebefehl (ob mit 1<< oder 0x ist hier
dasselbe). Wenn man den sts, der das WDCE - Bit setzt nicht rechnet weil
er ja schon gelaufen ist, dann sind es wirklich nicht mehr. In der
angehängten PDF (leider keine bessere Qualität möglich mit meinen
augenblicklichen Mitteln) ist das gut zu sehen mit entspr.
Vergrößerung. Außerdem ist bei der Initialisierung dieselbe Problematik
und da funktioniert es ja ausgezeichnet. Ich habe schon mal aus dem
Internet eine wdt.h probiert, aber die funktioniert überhaupt nicht
oder ich bin zu dumm (500 errors). IAR selbst gibt darüber nichts her.
Ich weiß jetzt natürlich auch nicht, wieviele Taktzyclen ein sts
braucht aber Atmel sollte es schon wissen sonst hätten sie sich den
Druck sparen können.

Wilfried

von ecslowhand (Gast)


Lesenswert?

STS braucht 2 Taktzyklen

von Axel R. (Gast)


Lesenswert?

na dann weis ich auch nicht.
vlt. durch den Simluator vom AVR Studio schieben und den CycleCounter
ansehen? Wird der IAR ja auch irgentwas in der Art haben. kA.

Gruß und viel Erfolg/Glück noch
AxelR.

von Wilfried J. (wilfried)


Lesenswert?

Hallo, an alle, die sich hier beteiligt haben.

Jetzt funktioniert mein Watchdog!
Mit Freude kann ich verkünden, daß ich den Fehler selbst beseitigt
habe, allerdings ist dies nicht ohne Eure Hilfe geschehen. Die
hartnäckigen Hinweise auf diese 4 Zyklen haben mich auf eine Idee
gebracht, die allerdings vom original Datasheet abweichend ist. Es ist
schon schwach von Atmel, ein Assemblerprogramm abzudrucken, das so
nicht funktionieren kann, denn da hat der Compiler möglicherweise nicht
mehr soviel Einfluß darauf.
Nun zu meiner Lösung, die sicher mancher brauchen kann.
Ich habe (mit IAR - Compiler) ein Register (15) gelockt, dieses mit dem
Befehl
"__regvar __no_init unsigned char WDTCSR_BYTE @15;"
definiert, das ich in der main belegen kann. Jetzt gibt der sts direkt
das R15 aus ohne es vorher mit ldi laden zu müssen.
Ich hab' natürlich mit einer Endlosschleife getestet, ob der Watchdog
überhaupt noch funktioniert - er tut es, und diesmal auch mit der
eingestellten Zeit. Ich muß zugeben, daß die Idee zwar von mir ist, für
die Ausführung habe ich allerdings gespickt und bis zum funkionieren die
Errormeldungen des Compilers ausgewertet.
Vielen herzlichen Dank nochmal für alle, die sich an diesem Problem
beteiligt haben. Jeder hat ein bisschen dazu beigetragen. Beim nächsten
Problem bin ich wieder hier.

Viele Grüße

Wilfried

von Axel R. (Gast)


Lesenswert?

Respekt!
Und das hat noch kein anderer rausgefunden?
Wie machen das andere Compiler? ich habe mal das Forum durchforstet,
aber nichts in der Art gefunden.
Schade ums R15, oder?

AxelR.

von Wilfried J. (wilfried)


Lesenswert?

Erstmal danke für die Anerkennung, aber Not macht erfinderisch, außerdem
denken vielleicht gerade Anfänger noch "ungebremst".
Eigentlich müßte es gereicht haben, denn in Assembler angeschaut
brauchen ein ldi und ein sts nur 3 Takte. Aber ich weiß ja nicht, was
der IAR noch dazubastelt, dazu müßte man den hex-code disassembieren.
Aber man muß ja nicht alles wissen. Ich habe auch mit dem AVR-Studio 4
probiert, aber das konnte ich gar nicht starten, der hat alle in der
iom88.h definierten pin's angemeckert. Wahrscheinlich hat noch
irgendwas gefehlt. Außerdem bin ich jetzt mit dem IAR eingearbeitet,
der ist auch bis 4K kostenlos. Das R15 kann ich noch verschmerzen, der
ATMega88 hat genug davon (noch).
Nochmal vielen Dank. War bestimmt nicht das letzte mal hier.

Wilfried

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.