Forum: Compiler & IDEs ATmega 8515 Watchdog-Reset nach EEPROM-Write


von dls (Gast)


Lesenswert?

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.

von Klaus (Gast)


Lesenswert?

Der Fehler ist in Zeile 48 deines Codes!

von Klaus (Gast)


Lesenswert?

Übrigens: Ohne Code in diesem Forum zu posten ist, wie ohne Auto zur 
Autowerkstatt gehen!

von dls (Gast)


Lesenswert?

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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

dls wrote:
> Ok, hier ist das Hauptprogramm...

das ist seeeehr kurz!

von dls (Gast)


Lesenswert?

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?

von Thomas H. (innot)


Lesenswert?

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 :-)

von Tassilo B. (big_t)


Lesenswert?

Noch einfacher/komfortabler lassen sich die vier Zeilen von Thomas so 
schreiben (siehe avr-libc-Doku):
1
wdt_enable(WDTO_2S);

Tassilo

von dls (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.