Forum: Mikrocontroller und Digitale Elektronik Variablen im EEPROM abspeichern


von Lukas B. (Gast)


Lesenswert?

Hallo,

ich möchte gerne einige Variablen im internen eeprom des AtMega8 
abspeichern. Das funktioniert soweit auch einwandfrei, mir ist lediglich 
noch nicht ganz klar, wie ich den Inhalt meiner Variablen "dynamisch" in 
das eeprom schreibe.

Der Code sieht folgendermaßen aus:
1
//Variablen für die Weckzeit
2
volatile uint8_t w1_minute;
3
volatile uint8_t w1_stunde;
4
volatile uint8_t w2_minute;
5
volatile uint8_t w2_stunde;
6
7
//EEPROM-Variablen EEMEM
8
uint8_t w1_minute_ee EEMEM;
9
uint8_t w1_stunde_ee EEMEM;
10
uint8_t w2_minute_ee EEMEM;
11
uint8_t w2_stunde_ee EEMEM;
12
13
//######## eeprom-Funktionen ####### 
14
#define EEPROM_DEF 0xFF
15
16
void eeprom_read (void){
17
 
18
    //EEPROM-Variablen lesen und den Weckzeit-Variablen zuordnen
19
    w1_minute = eeprom_read_byte (&w1_minute_ee);
20
    w1_stunde = eeprom_read_byte (&w1_stunde_ee);
21
    w2_minute = eeprom_read_byte (&w2_minute_ee);
22
    w2_stunde = eeprom_read_byte (&w2_stunde_ee);
23
24
  //Standardinhalt für leeres EEPROM setzen (Wert 0)
25
  uint8_t w1_minuteDefault = 0;
26
  if ((w1_minute = eeprom_read_byte (&w1_minute_ee)) == EEPROM_DEF){
27
        w1_minute = w1_minuteDefault;
28
    }
29
    uint8_t w1_stundeDefault = 0;
30
  if ((w1_stunde = eeprom_read_byte (&w1_stunde_ee)) == EEPROM_DEF){
31
        w1_stunde = w1_stundeDefault;
32
    }
33
    uint8_t w2_minuteDefault = 0;
34
  if ((w2_minute = eeprom_read_byte (&w2_minute_ee)) == EEPROM_DEF){
35
        w2_minute = w2_minuteDefault;
36
    }
37
    uint8_t w2_stundeDefault = 0;
38
  if ((w2_stunde = eeprom_read_byte (&w2_stunde_ee)) == EEPROM_DEF){
39
        w2_stunde = w2_stundeDefault;
40
  }
41
}
42
43
void eeprom_write (void){
44
    w1_minute = 30; //statische Zuweisung nur testweise
45
    eeprom_write_byte(&w1_minute_ee, w1_minute); 
46
  eeprom_write_byte(&w1_stunde_ee, w1_stunde); 
47
  eeprom_write_byte(&w2_minute_ee, w2_minute); 
48
  eeprom_write_byte(&w2_stunde_ee, w2_stunde); 
49
}

Wie man sehen kann, schreibe ich die Werte der Weckzeit-Variablen per 
eeprom_write in das eeprom. Wenn ich jetzt wie hier einen konstanten 
Wert zuordne, wird dieser in das eeprom geschrieben und beim nächsten 
Start auch wieder ausgelesen und angezeigt.
Meine Frage ist jetzt, wie ich die Funktion void eeprom_write am besten 
aufrufen soll. Wenn ich sie einmal im Hauptprogramm aufrufe, sind die 
Weckzeit-Variablen noch 0 und entsprechend wird das eeprom auch auf 0 
gesetzt und nichts erneut eingelesen.
Ich möchte aber, dass das eeprom immer die aktuellen Werte der 
Weckzeit-Variablen, die per Tastendruck hoch- und runtergezählt werden 
können, enthält. Eine while-Schleife oder ein Aufruf durch einen Timer 
erscheint mir nicht sinnvoll, da die Lebensdauer des eeproms ja begrenzt 
ist.
von Lukas B. (Gast)


Lesenswert?

Edit:

Ich habe jetzt die Funktion void eeprom_write in meine Tasterfunktion 
gepackt, sodass jedes Mal, wenn ich einen Taster drücke und somit die 
Variable hochzähle, das eeprom beschrieben wird.
Ist das in Bezug auf die Lebensdauer sinnvoll oder könnte man es noch 
besser machen?
von Jonathan S. (joni-st) Benutzerseite


Lesenswert?

Wie wär's damit: Sobald der Benutzer seine Eingabe bestätigt, speicherst 
Du sie ab. Oder du schaust, ob der Variablen-Inhalt ungleich dem 
EEPROM-Inhalt ist und speicherst die Weckzeit dann ab. Damit würde es 
sogar noch speichern, wenn das EEPROM seine zugesicherten Zyklen 
eigentlich schon überschritten hat - wenn der Wert nicht richtig ins 
EEPROM geschrieben wurde, schreibts Du einfach nochmal - so kann man die 
Lebensdauer eines EEPROMs nochmal ein bisschen verlängern. Oder Du 
speicherst die Weckzeit ab, sobald deine Uhr(?) ausgeschaltet wird - 
dazu müsstest Du nur den Wegfall der Stromversorgung detektieren und mit 
einem großen Elko die Spannung noch so lange aufrechterhalten, wie Du 
zum Speichern brauchst.

Such' dir was aus...


Gruß
Jonathan
von Jonathan S. (joni-st) Benutzerseite


Lesenswert?

Lukas B. schrieb:
> Ich habe jetzt die Funktion void eeprom_write in meine Tasterfunktion
> gepackt, sodass jedes Mal, wenn ich einen Taster drücke und somit die
> Variable hochzähle, das eeprom beschrieben wird.
> Ist das in Bezug auf die Lebensdauer sinnvoll oder könnte man es noch
> besser machen?

Nicht gut. Nimm besser die Beim-Ausschalten-speichern-Variante, die ich 
eben schon beschrieben habe. Dazu müsste es sogar einen Artikel hier im 
Wiki geben...
von Lukas B. (Gast)


Lesenswert?

Danke schon mal. Die zweite Variante erscheint mir reichlich kompliziert 
und bei den Verbrauchern, die an der Stromversorgung hängen, bräuchte 
ich einen recht großen Elko.
von Lukas B. (Gast)


Lesenswert?

Ich rufe jetzt in der Schleife im Haupprogramm diesen Code auf. Ist das 
so besser als das eeprom bei jedem Tastendruck zu aktualisieren? Es 
funktioniert jedenfalls genauso gut.
1
  
2
  //EEPROM-Speicherung
3
  //Schreiben des EEPROMS, wenn Werte geändert werden
4
  if (w1_minute != w1_minute_ee || w1_stunde != w1_stunde_ee || 
5
    w2_minute != w2_minute_ee || w2_stunde != w2_stunde_ee || 
6
    alarm != alarm_ee){
7
    eeprom_write();
8
  }
von Jonathan S. (joni-st) Benutzerseite


Lesenswert?

Ja, das ist in Ordnung. Aber noch besser wäre eine Abfrage für jede 
einzelne Variable, sodass unnötige Schreibvorgänge vermieden werden.
von Lukas B. (Gast)


Lesenswert?

Ich habe es jetzt wieder auf meine erste Variante geändert, sodass die 
Werte nur bei einem Tastendruck geändert werden.
Bei der obigen Variante sind mir einige Probleme aufgefallen. Wenn man 
zum Beispiel die Stromversorgung sehr schnell an- und ausschaltet, wird 
das EEPROM mit 0 überschrieben, evtl. weil die Variablen noch den Wert 0 
haben.

In meinen Augen ist die aktuelle Variante die optimalste (bei meinem 
geringen Aufwand), da das Eeprom wirklich nur beim Drücken einer Taste 
beschrieben wird und ansonsten keine zusätzliche Belastung des Eeproms 
stattfindet. Sollte das Eeprom irgendwann einmal beschädigt sein, muss 
man halt den Controller tauschen, so teuer sind die ja nicht.
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.