Forum: Compiler & IDEs EEPROM beschreiben in Fkt. -> Fehler


von Timebeast (Gast)


Lesenswert?

Hallo Leute,
ich bin gerade auf einen sehr merkwürdiges Verhalten der GCC Bibliothek 
<avr/eeprom.h> gestoßen. Schreiben und Lesen des EEPROMS an einer 
bestimmten Speicherstelle innerhalb einer Funktion geht. Werden das 
lesen/schreiben in eine Unterfunktion ausgelagert, geht es nicht mehr.
Randdaten: AVR-Studio 4.14, GCC 20080411, ATmega8535

Beispielprogramm welches das Verhalten an den Tag legt (Die Ausgabe, bei 
mir RS232, muß man sich halt nochmal selbst anpassen):
1
#include <avr/io.h>
2
#include <avr/eeprom.h>
3
//#include "RS232.h"
4
5
//Prototyp:
6
void write(uint8_t, uint8_t);
7
8
int main(void)
9
{
10
//  RS232_init(9600);
11
12
  uint8_t addr=0x04;
13
  uint8_t value=102;
14
15
  //So funktioniert es:
16
  //-------------------
17
  // eeprom_write_byte (&addr, value);  //Wert in EEPROM an Addresse schreiben
18
  //  RS232_write("Daten wurden geschrieben: %i \r",value);
19
  // value=0;              //Wert löchen
20
  //value = eeprom_read_byte (&addr);  //Wert aus EEPROM an Adresse lesen  
21
  //  RS232_write("Daten wurden gelesen: %i \r",value);
22
  
23
  //So funktioniert es nicht:
24
  //-------------------------
25
   write(addr, value);
26
   value=0;
27
     value = eeprom_read_byte (&addr);//Hier ist value "255" ???
28
//RS232_write("Daten wurden gelesen: %i \r",value);
29
  
30
  while(1);
31
return 0;
32
}
33
34
void write(uint8_t addr, uint8_t value){
35
   eeprom_write_byte (&addr, value);  //Wert in EEPROM an Addresse schreiben
36
//RS232_write("Daten wurden geschrieben in Fkt: %i \r",value);
37
   value=0;              //Wert löchen
38
   value = eeprom_read_byte (&addr);  //Wert aus EEPROM an Adresse lesen
39
                     //hier ist value noch "102"
40
//RS232_write("Daten wurden gelesen    in    Fkt: %i \r",value);
41
}

Jemand eine Idee?
 - Ich meine es geht zum Beispiel auch wenn ich sowohl addr und value 
als Pointer übergebe... nettes Workaround, aber für mich nicht 
praktikabel.
 - Im Tutorial steht man sollte den gesamten EEPROM als ein großes Array 
definieren, und die einzelnen Elemente dann als Adresse 
interpretieren... Auch ein nettes Workaround, wahrscheinlich werde ich 
es nun auch so machen.

Aber gibt es eine logische oder bekannte Erklärung für diesen "Fehler", 
sofern es einer ist...

Gruß
Ralf

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Du schreibst an die Adresse der Adresse...

von Stefan E. (sternst)


Lesenswert?

Du machst einen prinzipiellen Fehler beim Umgang mit den 
EEPROM-Funktionen.

> uint8_t addr=0x04;
> eeprom_write_byte (&addr, value);

Das "&" ist falsch. addr soll kein Pointer auf Daten sein, die die 
Adresse enthalten, sondern der Pointer ist die Adresse.
Richtig wäre:
eeprom_write_byte ((uint8_t *)addr, value);
Beim Lesen natürlich entsprechend.

Bei deiner Version beschreibst und liest du nicht die Adresse 0x04 im 
EEPROM, sondern die Adresse, die addr im RAM hat. Bei der Main-Variante 
scheint es zu funktionieren, weil es eine niedrige Adresse (aber nicht 
0x04) im RAM ist (globale Variable), und in der Funktion geht es nicht, 
weil die Adresse von addr dort für das EEPROM zu groß ist (das addr dort 
liegt auf dem Stack).

von Timebeast (Gast)


Lesenswert?

Juhu, wunderbar, funktioniert...

Hab ich mal echt falsch gedacht, vielen Dank.

Aber ist schon klasse, gestern noch mit drei Leuten vor dem Problem 
gestanden, und jetzt wo die Lösung auf dem silber Tablett präsentiert 
wird, ist es natürlich jedem klar gewesen bzw. "Ja Ja, das hab ich mir 
schon gedacht".

Sehr witzig...

Vielen Dank nochmal

Einen wundervollen halb Sommertag Euch noch, bei mir scheint die Sonne 
jetzt definitiv etwas heller ;-)

Gruß
Ralf

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.