EEPROM verliert Daten!

OP #2067567
Lesenswert?

Hallo zusammen,

Ich habe festgestellt dass die paar Variablen die ich im EEPROM ablege 
(5% ausgelastet) manchmal verloren gehen. Beim Aufruf wird dann irg 
etwas anderes, aber nicht der abgespeicherte Wert ausgelesen. Das 
passiert aber nur selten deshalb kann ich es nicht recht 
nachvollziehen... hat jemand eine Idee wiran das liegen kann? Folgendes 
sollte doch korrekt sein?!

Verwende folgende Lib
1
#include <avr/eeprom.h>

Schreibe zB wie folgt:
1
for(i = 0; i<6; i++)
2
{
3
eeprom_write_byte(&eeChannelArray[i], channelArray[i]);
4

5
eeprom_write_word(&eeBatteryLevel[i], batteryLevel[i]);
6
}

und lese wie folgt:
1
channeArray[i] = eeprom_read_byte(&eeChannelArray[i]);
2
    
3
batteryLevel[i] = eeprom_read_word(&eeBatteryLevel[i]);


Init:
1
unsigned char eeChannelArray[6] EEMEM = { JOB0, JOB1, JOB2, JOB3, JOB4, JOB5};
Gast #2067572
Lesenswert?

Bist du so Doof oder tust Du nur so.

Lerne erst mal durchs lesen

Als erstes muss geprüft werden, ob ein vorheriger Schreibzugriff schon 
abgeschlossen ist. Danach wird die EEPROM-Adresse, auf die geschrieben 
wird, in das IO-Register EEAR (EEPROM Address Register) geladen. Dann 
schreibt man die Daten, welche man auf der im Adressregister 
abgespeicherten Position ablegen will ins Register EEDR (EEPROM Data 
Register). Als nächstes setzt man das EEMWE Bit im 
EEPROM-Kontrollregister EECR (EEPROM Control Register) um den 
Schreibvorgang vorzubereiten. Nun wird es zeitkritisch - es darf nun 
keinesfalls ein Interrupt dazwischenfahren - denn man muss innerhalb von 
4 Taktzyklen das EEWE Bit setzen um den Schreibvorgang auszulösen. Um 
das unter allen Bedingungen sicherzustellen werden die Interrupts kurz 
gesperrt. Danach startet der Schreibvorgang und läuft automatisch ab. 
Wenn er beendet ist, wird von der Hardware das EEWE Bit im Register EECR 
wieder gelöscht.
Gast #2067587
Lesenswert?

Hi

>Als erstes muss geprüft werden, ob ein vorheriger Schreibzugriff schon
>abgeschlossen ist. Danach wird die EEPROM-Adresse, auf die geschrieben
>wird, in das IO-Register EEAR (EEPROM Address Register) geladen. Dann
>schreibt man die Daten, welche man auf der im Adressregister

Ups, ein Hellseher. Du weisst also, was sich hinter 'eeprom_write_byte' 
vebirgt?

MfG Spess
Gast #2067610
Lesenswert?

Mal ein anderer (und nicht ganz so unhöflicher) Tip: Brownout-Detektor 
einschalten, wenn der EEPROM benutzt wird. Das erste Byte (#0) möglichst 
nicht benutzen (mit Dummy-Variable füllen), da es besonders häufig von 
Datenverlust betroffen zu sein scheint.
Gast #2067622
Lesenswert?

Das schliesst jedoch nicht aus, dass die Vcc im tagelangen Betrieb 
einmal in einen Spannungsbereich abfällt, in dem der µC noch nicht 
abstürzt, aber das EEPROM beim Lesen oder Schreiben kompromittiert wird.

Die Brownout Fuse kann verhindern, dass der AVR in diesem miesen 
Vcc-Bereich überhaupt arbeitet. Dadurch dass der µC unterhalb des 
Brownout-Levels in den Reset gezwungen wird.

Und man kann am Programmanfang auswerten und anzeigen, ob ein 
Brownout-Reset (oder je nach µC andere Resets) aufgetreten ist.

Hast du einen Überblick, ob der AVR durchläuft oder ob unbeobachtete 
Resets (Power-On, Watchdog, Brownout) stattgefunden haben, die eine 
höhere EEPROM-Schreiblast erzeugen als angenommen?

Kannst du eine Häufung von Fehlern an bestimmten EEPROM Adressen 
feststellen? Adresse 0 ist da besonders interessant.
OP #2067713
Lesenswert?

Danke erst mal für Eure Tipps!

Also gelesen wird der EEPROM erst nach der Begrüßungssequenz das sind 
mehrere 100ms.

BrownOut ist inaktiv, da würde ich mich dann mal ran machen! Und danach 
teste ich das nochmal durch.

Prinzipiell sind aber meine lese und schreibe Vorgänge (s.o.) ,oder? Und 
da ich auf dem EEPROM mit keinerlei weiterer Zeiger Arithmetik arbeite 
sollte da auch nichts schief gehen.
#2067734
Lesenswert?

D. Berg schrieb:
> Prinzipiell sind aber meine lese und schreibe Vorgänge (s.o.) ,oder?

Naja, ich finde die AVR-GCC Funktionen ziemlich umständlich, langsam und 
groß.
Ich lege immer eine Kopie im SRAM an zum Arbeiten und lese/schreibe mit 
einer Funktion dann den EEPROM:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=91306

Der Vorteil neben der Kleinheit ist auch, daß sie unnötiges Schreiben 
vermeidet.
Man kann also immer die ganze Struktur zum Schreiben übergeben und sie 
schreibt nur die Änderungen.

Da die GCC-Funktionen über einen indirekten Call aufgerufen werden, kann 
ich mir auch gut vorstellen, daß ein wildgewordener Pointer oder ein 
Stacküberlauf ein versehentliches Schreiben auslöst.


Peter

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren