Hallo,
ich habe einen ATmega644 und möchte mit dem Watchdog den Controller
booten. Hier mein verwendeter Code:
1
#include<stdio.h>
2
#include<avr/interrupt.h>
3
#include<avr/io.h>
4
#include<avr/wdt.h>
5
6
printf("ATmega644 Controller Boot\n");
7
cli();
8
wdt_enable(WDTO_15MS);
9
while(TRUE){};
Der Controller gibt zwar schön den printf() string auf dem
Atmel-Studio-7 Terminal Window aus, aber er bootet nicht und bleibt
anscheinend irgendwo hängen. Das cli() habe ich eingefügt, damit er
während der nächsten 15 ms keinen Interrupt mehr verarbeitet. Bei den
von mir bisher verwendeten Controllern ATmega8 und ATmega32 funktioniert
dieser Code einwandfrei.
Zur Info: Wie im Fuse-Menu zu sehen, habe ich das WDTON flag nicht
gesetzt.
Weiß jemand, was ich da falsch gemacht habe ?
Danke schon mal für jede Antwort.
Grüße Manni
Hi
<> Bei den
>von mir bisher verwendeten Controllern ATmega8 und ATmega32 funktioniert>dieser Code einwandfrei.
Der ATMega644 ist aber weder ein ATMega8 noch ein ATMega32. Also lies
das Datenblatt!
MfG Spess
Manfred L. schrieb:> Weiß jemand, was ich da falsch gemacht habe ?
Ja, der Watchdog ist der Watchdog. Ein cli() interessiert ihn nicht. Das
von dir angesprochene Fuse-Bit sorgt nur dafür, wenn ich mich recht
entsinne, dass man den Watchdog nicht aus versehen ausschalten kann, er
ist dann IMMER an wenn es gesetzt ist.
Aber deine Code-Zeilen sehen auch komisch aus, ich vermisse hier
irgendwie mindestens etwas in der Form wie:
M. K. schrieb:> Warum genau hast du keine main()?
Und meckert der Compiler nicht bei Code außerhalb von Funktionen?
Auf jeden Fall gibt es keine Instanz, die diesen Code ausführt.
Peter D. schrieb:> Und meckert der Compiler nicht bei Code außerhalb von Funktionen?> Auf jeden Fall gibt es keine Instanz, die diesen Code ausführt.
Hallo Peter,
schön dass Du wieder "mitspielst".
Wie üblich hast Du natürlich recht, dass dieser Code-Schnipsel keine
Instanz ergibt, aber ich wollte den Beitrag hier nicht mit 50 KByte C
Source-Code voll-müllen.
Der generierte Assembler-Code im .lss file sieht so aus:
Dieser Code entspricht dem in der ATmega644 Dokumentation
(2593O–AVR–02/12) auf Seite 49-51 vorgeschlagenen Code. Zur weiteren
Info:
- es läuft kein Bootloader
- es sind keine weiteren externen interrupts enabled
- nur der TIMER0 läuft für eine Tastenabfrage a la PeDa Methode,
die ich schon in zig Projekten erfolgreich eingesetzt habe
--> nochmals Dank dafür !
Ich habe einfach den Verdacht, dass an den Fuses etwas nicht stimmt, die
komplette Übersicht der Fuse-Einstellung nochmals hier im attached Bild.
Spess53 schrieb:> Der ATMega644 ist aber weder ein ATMega8 noch ein ATMega32. Also lies> das Datenblatt!
Ist mir bekannt und habe ich auch gelesen, siehe oben :-)
Danke für den hilfreichen Kommentar.
Daß der Compiler den korrekten Code erzeugt, ist klar. Aber wir wissen
immer noch nicht, welche Funktion ihn ausgeführt.
Um zu sehen, ob er in der Schleife hängt, laß doch darin ne LED blinken
(5Hz) und setze den Wachhund auf 2s.
Langen Code anhängen, nicht einfügen.
Du hast zwar die Startup-Time auf 4.1 ms (+16 Clocks) gestellt, aber
bist du dir sicher, dass alle deine Initialisierungen durchlaufen, bevor
der Watchdog ein zweites Mal zuschlägt?
d.H., was passiert könnte folgendes sein:
Power-On
Init (braucht insg. länger als 15ms)
UART-Ausgabe
Watchdog-an auf 15ms
Watchdog reset
Init
Watchdog reset
Init
Watchdog reset
.....
Gegenprobe: Watchdog auf mehr als 15ms stellen, oder ganz am Anfang
deiner Initialisierung wieder abschalten.
Nachtrag: Im Atmega644 - Datenblatt steht explizit, dass der
Watchdog-Reset den Watchdog selber nicht abschaltet.
>> the device will be reset and the Watchdog Timer will stay enabled
Peter D. schrieb:> laß doch darin ne LED blinken> (5Hz) und setze den Wachhund auf 2s.
Danke Dir für den Hinweis. Aber den String "ATmega644 Controller Boot"
gibt er ja ordnungsgemäß auf dem Terminal Window aus, d.h. bis dahin
lebt der Controller noch. Nur danach beibt er "hängen". Aber an dem "
_asm__ __volatile_ ( ..." Code kann ich ja nichts ändern da er mit
Assembler aus wdt.h vom Compiler erzeugt wird.
Ich werde Deinen Vorschlag trotzdem mal ausprobieren.
Es geht darum, nachzuweisen, dass er nach 2 Sekunden (blinken) wirklich
neu startet und erst danach irgendwo hängen bliebt.
Es wäre auch hilfreich, wenn du ganz am Anfang vom Init einen freien I/O
Pin ganz kurz auf low-high-low setzt. Dieses Muster kann man mit einem
Oszilloskop oder Logic Analyzer anzeigen und sehen, ob es sich
regelmäßig (z.B. in Intervall des Watchdog Timeouts) wiederholt.
Εrnst B. schrieb:> Nachtrag: Im Atmega644 - Datenblatt steht explizit, dass der> Watchdog-Reset den Watchdog selber nicht abschaltet.>>> the device will be reset and the Watchdog Timer will stay enabled
Hei der Daus --> Sauerei:
den Satz im Datenblatt habe ich gelinde gesagt beim Lesen offensichtlich
total verpennt. Jetzt ist mir klar, warum der Controller nach dem
Watchdog Setzen Code sich nicht mehr zurück meldet --> weil ich den
Watchdog im Code nicht mehr zurücksetze. So einfach ist die Sache, grrrr
!
Bei den ATmega8 und ATmega32 Controllern war das nicht der Fall, die
meldeten sich ordnungsgemäß zurück und der Watchdog war abgeschaltet.
Vielen Dank für diesen hilfreichen Kommentar !
Jetzt rufe ich einfach diese Methode auf und das funktioniert
einwandfrei.
Manfred L. schrieb:> Jetzt rufe ich einfach diese Methode auf und das funktioniert> einwandfrei.void Menu_SoftwareReset (void)> {> void (*reboot)() = 0x0000 ;> (*reboot)();> }
Quark, das macht keinen Reset, alle IO-Register bleiben gesetzt.
Im Datenblatt steht, wie man es richtig macht:
"WDE is overridden by WDRF in MCUSR. This means that WDE is always set
when WDRF is set. To clear WDE, WDRF must be cleared first."
Mir ist nicht klar, weshalb das ursprüngliche Programm nicht
funktioniert - sollte da nicht im 15 ms-Takt diese Textzeile auf dem
Terminal erscheinen, 115.2 kBd vorausgesetzt?
Jetzt habe ich nicht aufgepasst: wie kommt Ernst B. auf
> Startup-Time auf 4.1 ms (+16 Clocks) gestellt
? Das Fuse-Low-Byte steht auf 0xEF, dazu lese ich im Datenblatt '14CK +
65 ms', oder?
S. Landolt schrieb:> Jetzt habe ich nicht aufgepasst: wie kommt Ernst B. auf>> Startup-Time auf 4.1 ms (+16 Clocks) gestellt> ? Das Fuse-Low-Byte steht auf 0xEF, dazu lese ich im Datenblatt '14CK +> 65 ms', oder?
Kommt drauf an, ob es ein ATmega644 (65ms) oder ein ATmega644P (4.1ms)
oder ein Atmega644PA (0ms) ist.
Manfred L. schrieb:> ich habe einen ATmega644
Und im Screen-shot steht ebenfalls nur 'ATmega644'. Woher dann dort der
Text mit 'Start-up time ...' kommt, verstehe ich nciht.
Manfred L. schrieb:> Hei der Daus --> Sauerei:> den Satz im Datenblatt habe ich gelinde gesagt beim Lesen offensichtlich> total verpennt. Jetzt ist mir klar, warum der Controller nach dem> Watchdog Setzen Code sich nicht mehr zurück meldet --> weil ich den> Watchdog im Code nicht mehr zurücksetze. So einfach ist die Sache, grrrr> !
So ausführlich hab ich es nicht gesagt aber in meinem ersten Post hier
habe ich dir bereits gesagt, dass dein Watchdog an ist. Und der würde
versuchen in der main() (oder einem Äquivalent davon) zu starten...die
du nicht hast...und daher auch nix passieren kann...
Manfred L. schrieb:> Bei den ATmega8 und ATmega32 Controllern war das nicht der Fall, die> meldeten sich ordnungsgemäß zurück und der Watchdog war abgeschaltet.
Mit Sicherheit, wenn das Programm genauso wie hier aufgebaut war, war
das auch beim ATMega8 und ATMega32 so. Die CPUs sind nämlich identisch,
die Teile unterscheiden sich (mehr oder weniger) nur in ihrer
Peripherie. Aber vielleicht hattest du den obigen Code beim ATMega8 und
ATMega32 ja doch in der main() stehen, dann war das Verhalten ganz
gewiss anders. Aber nochmal, was du anscheinend auch nicht verstanden
hattest: Ein cli() deaktiviert den Watchdog nicht...und das ist auch gut
so ;)
MaWin schrieb:> Die Bootsektor-Fuse BOOTRST ist nicht gesetzt. Deshalb springt er zur> main statt zum Bootloader.
Vor allem zu einer nicht existierenden main() ;)
S. Landolt schrieb:> Jetzt habe ich nicht aufgepasst: wie kommt Ernst B. auf>> Startup-Time auf 4.1 ms (+16 Clocks) gestellt> ? Das Fuse-Low-Byte steht auf 0xEF, dazu lese ich im Datenblatt '14CK +> 65 ms', oder?
Das habe ich einfach aus dem Screenshot von manni übernommen, ohne da
nochmal exakt im Datenblatt nachzuforschen…
S. Landolt schrieb:> an Ernst B.:> Nochmals Entschuldigung; ich schrieb ja, dass ich mich da völlig vertan> hatte.
Nicht nötig. Ich lag eh falsch, hab das erste "K" bei den "16K CK"
übersehen :)
M. K. schrieb:
Danke Dir für die weiteren Hinweise.
M. K. schrieb:> Und der würde> versuchen in der main() (oder einem Äquivalent davon) zu starten...die> du nicht hast...und daher auch nix passieren kann...
Ich arbeite seit fast 20 Jahren mit den Dingern --> wieso soll ich keine
main() haben ? Mein oben zietierer Code ist nur ein Schnipsel von ca 50
KByte C-Source Code, den ich, wie schon gesagt, nicht hier im Beitrag
einfügen / anhängen wollte, da er mit dem Problem nichts zu tun hat. Ja
in der Tat: die 50 KByte haben wirklich eine main() und da springt er
auch schön hin, wenn der Watchdog Reset ausgelöst wird.
Wie Du schon richtig bemerkt hast, ist der Watchdog leider dann immer
noch aktiv und löst immer wieder einen Reset aus, weil ich ihn im
Init-Teil des Source Codes nicht ausschalte. Und das war genau mein
eingebauter Fehler, weswegen ich diesen Beitrag gestartet hatte.
M. K. schrieb:> Mit Sicherheit, wenn das Programm genauso wie hier aufgebaut war, war> das auch beim ATMega8 und ATMega32 so.
Nicht ganz, denn ich habe dies heute nochmals ausprobiert, d.h.:
gleichen kurzen Test-Code auf ATmega644 und ATmega32 geflashed. Der
Unterschied ist, dass der ATmega644 sich nicht mehr meldet, aber der
ATmega32 meldet sich wieder und arbeitet ordnungsgemäß alles ab.
Es gibt demzufolge doch Unterschiede im Aufbau, wie z.B. die Fuse
CKDIV8, die das Clock-Signal durch 8 teilt, wenn enabled. Das hat mich
einen ganzen Abend gekostet, bis ich das endlich herausgefunden hatte.
M. K. schrieb:> Aber nochmal, was du anscheinend auch nicht verstanden> hattest: Ein cli() deaktiviert den Watchdog nicht...und das ist auch gut> so ;)
Wie gesagt: ich bin kein Neuling und weiß, dass cli() nix mit dem
Watchdog zu tun hat.
------------
Trotzdem vielen Dank für Deinen ersten Beitrag, der mich auf das Problem
aufwerksam gemacht hat. Hoffe, man trifft sich mal wieder.
Grüße Manni
> Trotzdem vielen Dank für Deinen ersten Beitrag, der> mich auf das Problem aufwerksam gemacht hat.
Das verstehe ich nun nicht - war es nicht eher der erste Beitrag von
Ernst B.?
Der Unterschied ist doch, dass in der ATmega8-Generation der
Watchdog-Reset den Watchdog abschaltet, beim ATmega644 bleibt er aktiv.