Hallo, ich habe folgendes Problem: Nach EEPROM Schreiben mit einer der GCC-Funktionen, z. B. #define Lm1L 0x10 eeprom_write_word((uint16_t *) Lm1L, Lim1); gibt es immer einen Watchdog RESET. Der Schreibvorgang funktioniert jedoch. Der Watchdog ist eingeschaltet, Zyklus 64ms (WDTCR=0x0a), der Watchdog wird etwa alle 10ms mittels wdt_reset() bedient. Sollen mehrere EEPROM-Schreibvorgänge nacheinander ausgeführt werden so wird nur der erste ausgeführt. Selbst bei maximaler Watchdog-Periode (2,1s) gibt es den Reset. Wird der Watchdog jedoch ausgeschaltet so funktioniert alles problemlos, auch mehrere EEPROM-Schreibvorgänge unmittelbar nacheinander sind kein Problem. Controller: ATmega8515, Betriebsspannung 5V, AVR Studio 4.15, aktueller GCC-Compiler Bei Simulation mittels AVR Studio gibt es keine Hinweise auf Fehlfunktionen. Hat jemand eine Idee, was ich hier falsch mache? Vielen Dank schon im Voraus.
Übrigens: Ohne Code in diesem Forum zu posten ist, wie ohne Auto zur Autowerkstatt gehen!
Ok, hier ist das Hauptprogramm sowie die Prozeduren zur Initialisierung und zum Schreiben im EEPROM. Andere Programmteile können mit dem beschrieben Problem eigentlich nichts zu tun haben. Übrigens: Das Ganze ist eine Umsetzung eines Programms vom AT90S8515 auf den ATmega8515. Die Software ist auf dem alten Prozessor seit vielen Jahren problemlos gelaufen.
dls wrote:
> Ok, hier ist das Hauptprogramm...
das ist seeeehr kurz!
Tut mir leid, das mit dem Dateianhang hat wohl nicht geklappt... Hier mal das Problem in Kurzform: #include <avr/io.h> // avr Header File für IO Ports #include <avr/pgmspace.h> // Makros für Flash-Konstanten #include <avr/wdt.h> // Makros für Watchdog Timer #include <avr/eeprom.h> // Makros für den EEPROM-Zugriff // Definition EEPROM-Adressen: #define H1 0x66 #define H2 0x67 #define H3 0x68 #define H4 0x69 char H; FUSES = { .low = FUSE_SUT0, .high = HFUSE_DEFAULT, }; // Hauptprogramm int main(void) { int j; DDRA=0x1f; // Datenrichtung Port A PORTA=0xff; // Schaltereingänge mit Pull-Up, LEDs aus WDTCR=0x0f; // Watchdog ein, Zyklus 2s j=0; PORTA&=0xef; // LED ein while(1) { j++; if ((j % 128)==0) { wdt_reset(); _EEGET(H,H1); if (H==0xff) { eeprom_write_byte((uint8_t *) H1, 0x34); eeprom_write_byte((uint8_t *) H2, 0x56); eeprom_write_byte((uint8_t *) H3, 0x78); eeprom_write_byte((uint8_t *) H4, 0x90); } } } return 1; } Controller: ATmega8515, Taktfrequenz 6MHz, Vcc=5V Das Resultat im EEPROM ist: :10006000FFFFFFFFFFFF3456FFFFFFFFFFFFFFFF14 Wird der Watchdog nicht eingeschaltet (WDTCR=... auskommentiert) so werden alle vier Bytes wie gewünscht in den EEPROM geschrieben. Wenn nach jedem "eeprom_write_byte..." ein "wdt_reset();" eingefügt wird dann klappt es auch. Ähnliches Verhalten beim Schreiben von Worten und Langworten. Die Watchdog-Periode müsste doch mit 2s lang genug sein für viele EEPROM-Schreibvorgänge, oder? Beim AT90S8515 in Verbindung mit dem alten IAR-C-Compiler gab es dieses Problem definitiv nicht. Hat jemand eine Erklärung dafür?
Probier doch mal den folgenden Code zum setzten des Watchdog Timeouts:
1 | #include <avr/interrupts.h> |
2 | |
3 | ...
|
4 | |
5 | cli(); |
6 | WDTCR = (1<<WDCE) | (1<<WDE); |
7 | WDTCR = 0x0f; // Watchdog ein, Zyklus 2s |
8 | sei(); |
Wenn es damit geht dann empfehle ich das ATmega8515 Datasheet ab Seite 50 warum das so ist und worin die Unterschiede zwischen einem ATmega8515 und einem AT90S8515 liegen. Wenn es nicht geht wünsche ich noch schöne Weihnachten und viel Glück bei der Lösung des Problems :-)
Noch einfacher/komfortabler lassen sich die vier Zeilen von Thomas so schreiben (siehe avr-libc-Doku):
1 | wdt_enable(WDTO_2S); |
Tassilo
Danke, Thomas und Tassilo, die Änderung hat das Problem beseitigt. Das Datenblatt hatte ich so verstanden, dass nur zum Abschalten des Watchdogs das WDCE-Bit erforderlich ist. Außerdem hat mein Programm im Simulator korrekt funktioniert, die Initialisierung des Watchdogs wurde genau so angezeigt wie nach der Änderung. Lediglich im "echten" Controller gab es immer den Watchdog-Reset. Ich denke, ich muss mir bei Gelegenheit mal den erzeugten Assemblercode genau ansehen, um zu verstehen, wo hier wirklich der Unterschied liegt. Euch auch schöne Weihnachtstage!
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.