Forum: Mikrocontroller und Digitale Elektronik mehrere Variablen in EEPROM speichern


von Lokus P. (derschatten)


Lesenswert?

Wenn ich mehrere Zahlen-Variablen ins EEPROM speichern möchte, muß ich 
mir dafür die Funktion eeprom_write_block hernehmen oder geht das auch 
mit eeprom_write_byte.

Falls ja, ich versuche gerade 2 Variablen zu schreiben und zu lesen:
1
volatile uint8_t nKonfig;
2
volatile uint8_t light;
3
4
volatile uint8_t EEMEM eeprom_tasten = 1;
5
volatile uint8_t EEMEM eeprom_lcd = 2;
6
7
int main(void)
8
{
9
  init();                            // Einschaltsequenz starten
10
  sei();                            // Interrupts aktivieren
11
12
  lcd_update();
13
14
  nKonfig = (eeprom_read_byte(&eeprom_tasten));
15
  light = (eeprom_read_byte(&eeprom_lcd));
16
...
Der compiler kommt mir jedoch mit einer Warnung:

../main.c:351: warning: passing argument 1 of '__eerd_byte_m8' discards 
qualifiers from pointer target type

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Dein Code widerspricht so ziemlich allem, was im AVR-GCC-Tutorial 
über EEPROM geschrieben steht.
1
#include <avr/io.h>
2
#include <avr/eeprom.h>
3
4
#define BLOCKGROESSE 42
5
6
// Daten im RAM
7
volatile uint8_t nKonfig;
8
volatile uint8_t light;
9
uint16_t ramblock[BLOCKGROESSE];
10
11
// Daten im EEPROM
12
volatile uint8_t eeprom_tasten EEMEM = 1;
13
volatile uint8_t eeprom_lcd EEMEM = 2;
14
uint16_t eepromblock[BLOCKGROESSE] EEMEM = { 13, 11, 42 };
15
16
int main(void)
17
{
18
  // Daten aus den EEPROM Variablen in die RAM Variablen schaufeln
19
  // Byte for Byte Qualitait
20
  nKonfig = eeprom_read_byte(&eeprom_tasten);
21
  light = eeprom_read_byte(&eeprom_lcd);
22
23
  // Blocktransfer
24
  eeprom_read_block(ramblock, eepromblock, sizeof(eepromblock))
25
26
  while(1);
27
}

Über die Dekoration volatile würde ich zumindest bei den EEPROM-Daten 
nochmal nachdenken. Die dürften seltenst sinnvoll in einer ISR geändert 
werden... Ohne volatile kommt auch die Warnung nicht.

von Ingo (Gast)


Lesenswert?

Hallo, habe auch genau dieses Problem, dass die Warnung kommt. Aber ich 
möchte die Variable im EEPROM in einer ISR ändern, nämlich wenn über den 
RXT interrupt Parameter geändert werden, welche im EEPROM stehen. 
Wegcasten kann man diese Warnung auch nicht! Was also tun damit die 
Warnung verschwindet?

Ich Grabe die Leiche wieder aus, dann spare ich mir einen neuen Beitrag.

Ingo

von Peter D. (peda)


Lesenswert?

Ingo schrieb:
> Aber ich
> möchte die Variable im EEPROM in einer ISR ändern

EEPROM schreiben kostet pro Byte 8ms. Möchtest Du wirklich, daß Dein 
Programm abschmiert, weil die CPU so elendig lange stehen bleibt?

Generell hat man für EEPROM-Daten immer eine Arbeitskopie im SRAM.
Und nur bei Bedarf wird der EEPROM damit geupdatet.
Entweder im Main, damit die Interrupts weiter laufen.
Oder ganz clever im EEPROM-Interrupt ohne jede Zeitvergeudung.


Ingo schrieb:
> Ich Grabe die Leiche wieder aus, dann spare ich mir einen neuen Beitrag.

Nicht gut, da Dein Problem ja ein völlig anderes ist.


Peter

von Ingo (Gast)


Lesenswert?

Nein ist kein Anderes, ist absolut das selbe. Du weißt weder ob sich 
mein ganzes Programm in einer ISR abspielt oder sonst was. Also nur die 
eigentliche Frage beantworten. Trotzdem danke für den Hinweis.


Ingo

von Peter D. (peda)


Lesenswert?

Ingo schrieb:
> Du weißt weder ob sich
> mein ganzes Programm in einer ISR abspielt

Ich gehe eben von einem sinnvollen Programmkonzept aus.
Kann gut sein, daß ich damit manchen besser einschätze, als er ist.

Aber Du hast irgendwie doch recht, wir wissen garnichts.
Du hast nichts mitgeteilt, also können wir auch nicht helfen.
Jeder weiß eigentlich, bei Programmierfragen ist ein Quellcode als 
Anhang und die exakte Fehlermeldung mit Zeilennummer das mindeste.


Peter

von Stefan E. (sternst)


Lesenswert?

Ingo schrieb:
> Wegcasten kann man diese Warnung auch nicht!

Klar kann man das.

von Ingo (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Ingo schrieb:
>> Wegcasten kann man diese Warnung auch nicht!
>
> Klar kann man das.

Ja, aber wenn ich das so schreiben würde:
1
volatile unsigned int temp=0;
2
...
3
temp = eeprom_read_byte (&eeFooByte));
meckert der Compiler.

mache ich es so
1
volatile unsigned int temp=0;
2
...
3
temp =  eeprom_read_byte (&(unsigned int)eFooByte));

kommt er mir dem "&" durcheinander hält es für eine logische UND 
Verknüpfung.

Ingo

von Karl H. (kbuchegg)


Lesenswert?

Ingo schrieb:

> Ja, aber wenn ich das so schreiben würde:
>
1
> volatile unsigned int temp=0;
2
> ...
3
> temp = eeprom_read_byte (&eeFooByte));
4
>
> meckert der Compiler.

'meckert der Compiler' ist keine vernünftige Fehlermeldung.
Auch wenn es manchmal nicht so aussieht: Fehlermeldungen haben einen 
Grund und der Grund ist in der Fehlermeldung enthalten. Ich gebe zu, 
manchmal ist es schwer den Grund zu entdecken, wenn man die C-Syntax 
noch nicht so drauf hat.

> volatile unsigned int temp=0;
> ...
> temp =  eeprom_read_byte (&(unsigned int)eFooByte));
> [/c]
>
> kommt er mir dem "&" durcheinander hält es für eine logische UND
> Verknüpfung.

Nö, das tut er nicht.
Eine Und Verknüpfung hat immer eine linke Seite und eine rechte Seite

    a & b

Das ist hier nicht der Fall, also kann es auch kein Und sein. Das weiß 
auch der Compiler. Und du kannst davon ausgehen, dass der Compiler die 
C-Syntax sehr viel besser kennt als du.

Aber: Durch das Umcasten eines Bytes zu einem unsigned int, hast du eine 
temporäre Variable erzeugt (eben den unsigned int) und von dem kannst du 
nicht die Adresse nehmen. Daher kann "&(unsigned int)eFooByte" nicht 
richtig sein.

Das ist aber auch nicht das was du wolltest.
Du wolltest die Adresse von eFooByte nehmen.
Und das schreibt sich als

    &eFooByte

und dann diese Adresse als die Adresse eines unsigned int aufgefasst 
wissen:
    (unsigned int*)&eFooByte


Damit, dass du links vom = einen unsigned int hast, hat das herzlich 
wenig zu tun. Du kannst nicht dadurch, dass du der Funktion den 
Adressdatentyp eines unsigned int unterjubelst (selbst wenn du das 
richtig gemacht hättest - "(unsigned int*) &eFooByte" ) die Funktion 
dazu bringen, dass sie etwas anderes tut als ein einzelnes Byte 
auszulesen.

Also: Wie lautet die Fehlermeldung im genauen Wortlaut. Damit fängt 
jegliche Analyse an. "meckert der Compiler" ist kein genauer Wortlaut. 
Und dann sieht man sich eben alle Datentypen der beteiligten Operationen 
an und kontrolliert, wo man den Fehler gemacht hat.

Eine Warnung bezüglich Datentypen kann man IMMER wegcasten. Letzten 
Endes ist ein derartiger Cast die Anweisung an den Compiler: "Halt's 
Maul, ich weiß es besser." Nur sollte man auch sicher gehen, dass man es 
auch wirklich besser weiß.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Das heist dann ja auch so:
((unsigned int*)&eFooByte))

Natürlich gehen mehrere Variablen ins EEPROM, kannst die Adresse 
jedesmal ändern, musst nur aufpassen, dass du nix überschreibst.
writeword belegt zB 2 Adressen, steht aber alles hier auf 
Anleitungsseiten

von Ingo (Gast)


Lesenswert?

Hallo, danke für die Antworten. Ich habe diesen Tread wieder aufgemacht, 
weil ich die Warnung (erster Beitrag) auch bekomme, wenn ich die 
Variable volatile mache. Mein Cast ist offensichtlich falsch gewesen, so 
wie es Karl-Heinz und Martin geschrieben haben.

Ich habe nur das selbe Problem gehabt wie der TE, jedoch will ich keine 
2 Variablen oder sonst was machen, geht nur darum das volatile 
wegzucasten.

Danke

Ingo

von Karl H. (kbuchegg)


Lesenswert?

wobei sich allerdings die Frage erhebt, wozu man EEMEM Variablen 
überhaupt als volatile markiert.
Diese 'Variablen' sind nur ein Hilfskonstrukt, damit man eine 
Adressallokierung im EEPROM bekommt. Machen kann man mit diesen 
Variablen sowieso nichts, ausser die eeprom_xxxx Funktionen mit ihren 
Adressen aufrufen. Und die kann ein Compiler sowieso nicht 
wegoptimieren.

von Ingo (Gast)


Lesenswert?

Somit währe volatile überflüssig, selbst wenn ich sie in einer isr 
verändere?


Ingo

von Karl H. (kbuchegg)


Lesenswert?

Ingo schrieb:
> Somit währe volatile überflüssig, selbst wenn ich sie in einer isr
> verändere?

Welches volatile?
Das hier?
1
volatile uint8_t EEMEM eeprom_tasten = 1;

Das ist eine EEMEM Variable. Was soll das volatile denn hier bewirken?


Oder ist dir nicht klar, worum es bei volatile eigentlich geht?
http://www.mikrocontroller.net/articles/FAQ#Was_hat_es_mit_volatile_auf_sich

von Ingo (Gast)


Lesenswert?

Im, meine Fragen sind beantwortet, besten Dank.


Ingo

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.