Forum: Compiler & IDEs im EEPROM speichern: Fehlermeldung


von minastaros (Gast)


Lesenswert?

Hallo Leute,

ich versuche, Werte im EEPROM (ATmega8) zu speichern, krieg aber immer
Fehlermeldungen. Folgendes:

const uint16_t iEEPROM_ADR = 2;  // EEPROM-Adresse in der Konstante
eeprom_write_word (iEEPROM_ADR, iWert);

Das funktioniert, der Wert wird brav im EEPROM an Adressen 2 und 3
abgelegt, der Compiler motzt jedoch mit:

warning: passing arg 1 of `eeprom_write_word' makes pointer from
integer without a cast


Im Forum fand ich einige Beispiele, die die Adresse anders
deklarieren:

uint16_t iEEPROM_ADR _attribute_ ((section (".eeprom")));

Jetzt meckert der Compiler nicht mehr, das Programm läuft aber auch
nicht. Außerdem kann ich ja so nicht explizit bestimmen, dass der Wert
an Adresse 2 (oder wie auch immer) abgelegt wird. Was ist falsch?

Erweitertes Beispiel: Ich will mehrere Werte im EEPROM ablegen, sieht
so aus:

uint8_t c;
uint16_t iWert;

for (c = 0 ; c < 16 ; c++) {
  iWert = foo();
  eeprom_write_word ((i * 2), iWert);
}

Gleiches Problem wie oben, es funktioniert, die Werte werden schön
abgelegt, aber der Compiler motzt.

Kann mir das jemand korrigieren?

Ich benutze WINAVR mit dem GCC.

Danke und Gruß, min

von Werner B. (Gast)


Lesenswert?

Der prototyp der funktion ist
<eeprom.h>
...
extern void eeprom_write_word (uint16_t *addr, uint16_t val);
...
</eeprom.h>

der typ des ersten parameters muss also ein zeiger-typ sein
Am einfachsten über eine typecast

const uint8_t * iEEPROM_ADR = (uint8_t *)2;
eeprom_write_word (iEEPROM_ADR, iWert);

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Naja, wenn der Prototyp aber doch einen Pointer auf uint16_t erwartet,
warum sollte man dann einen uint8_t Poitner verwenden?

Nene! Besser gleich beides richtig machen:
1
#define EEPROM __attribute__ ((section (".eeprom")))
2
3
uint16_t iWert;
4
uint16_t ee_iWert EEPROM;
5
6
  eeprom_write_word(&ee_iWert, iWert);

So ausm Kopf, sollte funktionieren...

von minastaros (Gast)


Lesenswert?

Hallo Werner,
danke für den Tip, hat fast geklappt; Patrick hat auch recht mit den
16-Bit-Zeigern, allerdings läuft die Sache mit den attribute nicht
bei mir. Den typecast braucht es auch beim Aufruf der Funktion.
Folgendes geht jetzt einwandfrei, ohne Warnungen vom Compiler:

const uint16_t * iEEPROM_ADR = (uint16_t *) 2;  // an Adr. 2 im EEPROM
eeprom_write_word ((uint16_t *) iEEPROM_ADR, iWert);

klappt auch in der For-Schleife, wobei man c in 1-er-Schritten erhöhen
muss, da automatisch um 2 Byte weitergesprungen wird (praktisch):

eeprom_write_word ((uint16_t *) (iEEPROM_ADR + c), iWert);

und als READ:

iWert = eeprom_read_word ((uint16_t *) iEEPROM_ADR);


Gruß und weiter frohes Coden!  minastaros

von chris (Gast)


Lesenswert?

Hallo,
genau dieses 2byte weiterspringen möchte ich nicht, sondern nur 8-bit
weit. Dieses kann ich erreichen, wenn ich den typ von uint16_t auf
uint8_t abändere. Funktioniert super, aber die Fehlermeldung:
 "warning: passing arg 1 of `eeprom_write_word' from incompatible
pointer type"
ist wieder da, da der compiler ja 16-bit erwartet.
Frage: kann man das nicht irgendwie umgehen?
danke

von chris (Gast)


Lesenswert?

hallo,
vergesst es bitte, nach dem 3 Bier und 1. Halbzeit GER-POL hab ichs
auch gefunden.....
.-)

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.