im EEPROM speichern: Fehlermeldung

Gast #237671
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
Gast #237672
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);
Persönliche Seite #237673
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...
Gast #237674
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
Gast #237675
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

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.