www.mikrocontroller.net

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


Autor: Timebeast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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):
#include <avr/io.h>
#include <avr/eeprom.h>
//#include "RS232.h"

//Prototyp:
void write(uint8_t, uint8_t);

int main(void)
{
//  RS232_init(9600);

  uint8_t addr=0x04;
  uint8_t value=102;

  //So funktioniert es:
  //-------------------
  // eeprom_write_byte (&addr, value);  //Wert in EEPROM an Addresse schreiben
  //  RS232_write("Daten wurden geschrieben: %i \r",value);
  // value=0;              //Wert löchen
  //value = eeprom_read_byte (&addr);  //Wert aus EEPROM an Adresse lesen  
  //  RS232_write("Daten wurden gelesen: %i \r",value);
  
  //So funktioniert es nicht:
  //-------------------------
   write(addr, value);
   value=0;
     value = eeprom_read_byte (&addr);//Hier ist value "255" ???
//RS232_write("Daten wurden gelesen: %i \r",value);
  
  while(1);
return 0;
}

void write(uint8_t addr, uint8_t value){
   eeprom_write_byte (&addr, value);  //Wert in EEPROM an Addresse schreiben
//RS232_write("Daten wurden geschrieben in Fkt: %i \r",value);
   value=0;              //Wert löchen
   value = eeprom_read_byte (&addr);  //Wert aus EEPROM an Adresse lesen
                     //hier ist value noch "102"
//RS232_write("Daten wurden gelesen    in    Fkt: %i \r",value);
}

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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du schreibst an die Adresse der Adresse...

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Timebeast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.