Variablen im EEPROM abspeichern

Gast #2380596
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.
Gast #2380606
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?
Persönliche Seite #2380614
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
Persönliche Seite #2380617
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...
Gast #2380645
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
  }
Gast #2380795
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.

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