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
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
Wird der Watchdog etwa per WDTON-Fuse aktiviert ? Falls das der Fall ist lässt er sich nicht durch Software abschalten. Gruss Thomas
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
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
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
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
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
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
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
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
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.
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
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
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?
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
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.
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.