Forum: Mikrocontroller und Digitale Elektronik AVR EEPROM verliert Daten


von Gast (Gast)


Lesenswert?

Hallo,

ist irgendwas bekannt, dass ein ATMEGA8 Daten verliert, die im EEPROM 
gespeichert sind?

Ich hab ein Programm, dass schreibt nur ein einziges mal Daten über eine 
Kommandosequenz über RS232, bestehend aus 3 Zeichen. Diverse Tests, ob 
das sinnvoll ist usw sind auch dabei. Nach 2 Wochen hat eine 
Speicherzelle des AVR-Controllers einfach was verloren.

Kann das eventuell mit einem unsauberen Reset zusammenhängen? Ist da 
irgendwas bekannt, dass es mit dem EEPROM Probleme geben kann?

Hier ein Teil aus der Main, der nur bei der Initialisierung einmal 
aufgerufen wird. Die Timer-Funktionen dürfte in diesem Zusammenhang 
uninteressant sein:
1
int main() {
2
        [...]
3
  timer_set(0,eeprom_read(0));
4
  timer_set(1,eeprom_read(1));
5
        [...]
6
}

und die Funktionen für das EEPROM sehen so aus:
1
uint8_t ee_params[] EEMEM = {0xff,0xff};
2
3
4
void eeprom_write(uint8_t adr, uint8_t data)
5
{
6
  if ((adr<0) || adr>sizeof(ee_params))
7
    return;
8
9
  eeprom_write_byte(&ee_params[adr], data); 
10
}
11
12
uint8_t eeprom_read(uint8_t adr)
13
{
14
  if ((adr<0) || adr>sizeof(ee_params))
15
    return;
16
17
  return eeprom_read_byte(&ee_params[adr]);
18
}

Hab ich da was falsch gemacht?

Grüße
Gast

: Gesperrt durch Moderator
von egberto (Gast)


Lesenswert?

ich habe so etwas mal mit schnellem an/aus schalten der Betriebsspannung 
provoziert bekommen - nach setzen der Brown-Out Fuse (bei 5V auf 4,2) 
war das weg.

egberto

von Erwin R. (er-tronik)


Lesenswert?

Mein Tipp, unbedingt Brown-Out einschalten und zur Sicherheit nie die 
ersten Bytes im EEPROM mit wichtigen Daten belegen.

Erwin

von Joachim (Gast)


Lesenswert?

Ja, ich hatte auch schon den Effekt bei einem Mega8, dass EEPROM Daten 
verfälscht waren oder sogar EEPROM-Zellen zerstört waren(!).
Letztlich zeigte sich, dass eine unsaubere Versorgungsspannung dafür 
verantwortlich war. Die Dinger mögen keine Spannungsspitzen!

Meine Schreibroutine (entspricht dem ATMEL-datenblatt).
Habe aber beim Starten des Schreibvorgangs sicherheitshalber die 
Interrupts deaktiviert.
1
void EEstore(data,address)
2
{
3
  while(EECR & 0x2)
4
  {
5
  }
6
  EEAR = address;
7
  EEDR = data;
8
  SREG = (SREG ^ 128); //Clr Interrupt enable Bit 
9
  EECR |= 0x4; //set EEMWE
10
  EECR |= 0x2; //set EEWE
11
  SREG = (SREG | 128); //Set Interrupt enable Bit 
12
}

Dein Code hilft nicht weiter. Wo z.B. ist "eeprom_write_byte"?

Joachim

von YS-500 (Gast)


Lesenswert?

>zur Sicherheit nie die
>ersten Bytes im EEPROM mit wichtigen Daten belegen.

Warum?

von Gast (Gast)


Lesenswert?

Danke schonmal für eure Antworten. Mit der BO werd ich es mal probieren.

eeprom_write_byte ist eine funktion in der Standardlibrary von WINAVR.

Grüße
Gast

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

>>zur Sicherheit nie die
>>ersten Bytes im EEPROM mit wichtigen Daten belegen.

>Warum?

Weil die EEPROM-Adressregister mit $0000 initialisiert werden, wenn der 
Controller startet. Im Fehlerfall betrifft das Problem also die erste 
Speicherzelle.

>Habe aber beim Starten des Schreibvorgangs sicherheitshalber die
>Interrupts deaktiviert.

Sollte man generell machen, da sonst die atomische Schreiboperation 
unterbrochen werden kann und somit nicht ausgeführt wird.

von Lutz (Gast)


Lesenswert?

>>>zur Sicherheit nie die
>>>ersten Bytes im EEPROM mit wichtigen Daten belegen.

>>Warum?

>Weil die EEPROM-Adressregister mit $0000 initialisiert werden, wenn der
>Controller startet. Im Fehlerfall betrifft das Problem also die erste
>Speicherzelle.

Na ja. Wenn ich das EEPROM lese oder beschreibe und eine falsche (oder 
hier gar keine Adresse, also 0x00) benutze, ist das ja meine Schuld. 
Ansonsten muß man ja alle defaultwerte oder gar Register irgendwie 
berücksichtigen ,da ja standardmäßig auf diese zugegriffen wird.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Nee Lutz, das haste jetzt falsch verstanden. Der Controller 
initialisiert, bevor Dein Programm überhaupt erst startet, seine 
Hardware-Register, somit auch die EEPROM Steuerregister. Startet der 
Controller nun ohne Brown-Out Detektor, kann es aufgrund unzulänglicher 
Spannung passieren, daß die CPU Befehle falsch interpretiert und 
zufälligerweise auf das EEPROM schreibt. Da die Adressregister noch auf 
$0000 stehen, wird also allermeist die unterste EEPROM-Adresse von dem 
fehlerhaften Schreibvorgang betroffen sein. Dieses Problem tritt mit 
aktiviertem BOD nicht auf.

von Gast (Gast)


Lesenswert?

Das versehentliche überschreiben der EEPROM Daten auf Adresse $0000 war 
ein Problem der ersten Generation der AVRs (AT90Sxxxx), die keine 
Brow-Out Detection hatten. Der Effekt traf meist beim Einschalten (oder 
beim vorhergehenden Ausschalten) auf.
 Die ATmegaxxx sollten das Problem bei aktivierter Brow-Out Detection 
nicht mehr zeigen.

Gruß Norbert

von Gassi (Gast)


Lesenswert?

Vor einigen Jahren hatte ich diese Fehler öfter, trotz brown out 
detector und sauberer VCC. Ich denke, die Teile waren seinerzeit etwas 
"schrottig" in dieser Beziehung. Zur Sicherheit hatte ich die Daten 
immer mehrfach und mit Prüfsumme gespeichert.
Welches Fertigungsdatum hat den Dein Mega8?

von Lutz (Gast)


Lesenswert?

@TravelRec
Ach so, daß ist natürlich ganz was anderes. Danke.

von Christian P. (peterfrosta)


Lesenswert?

habe auch das Problem, das das EEPROM von meinem Atmega168 nach einer 
Weile Daten verliert. Der resetet sich aber auch schon mal von aleine 
(Proto-bastel-Typ). Ich hatte die Hoffnung dass es an diesen 
"EMV?!"Resets liegt.

Werde sofort checken ob BO aktiviert ist.

Nun eine doofe Frage.
wie vermeide ich das nutzen der ersten EEPROM Adressen?

quick and dirty würde mir jetzt nur einfallen:
a) pointer auf addresse $0000+n*8bit (16/32)
b) a[0] bis a[x] von a[y] leer lassen     | mit 0<x<y

vermutlich beides Unfug ?! ;)

danke und gruß

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

8 Jahre... nicht schlecht!

von C-hater-hater (Gast)


Lesenswert?

Wo steht denn WIE man die ersten speicheradressen ausspart?

von >= (Gast)


Lesenswert?

Gast schrieb:
> void eeprom_write(uint8_t adr, uint8_t data)
> {
>   if ((adr<0) || adr>sizeof(ee_params))

Die Abfrage ist fehlerhaft.

if (adr >= sizeof(ee_params))

von Draco (Gast)


Lesenswert?

>= schrieb:
> Die Abfrage ist fehlerhaft.
>
> if (adr >= sizeof(ee_params))

Erstens das und zweitens macht sizeof NICHT das was er denkt, schon 
garnicht nach einem Reset!

von g457 (Gast)


Lesenswert?

> [..] zweitens macht sizeof NICHT das was er denkt, schon garnicht nach
> einem Reset!

..drittens ist das falsch, viertens bitte ggf. einen eigenen Fred 
aufmachen, weil fünftens dieser hier fast acht Jahre alt ist!

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.