EEPROM wird nicht korrekt ausgelesen

Gast #3635055
Hallo,

ich habe eine Frage bezüglich Arbeiten mit EEPROM.

Ich schicke über UART einen String zum Atmega8, dieser String wird dann 
im EEPROM gespeichert, sowie die Länge des Stringes.

Ds funktioniert auch wunderbar. Jetzt möchte ich allerdings den String 
wieder auslesen, das klappt auch, jedoch wird immer alles, was in dieser 
EEPROM Stelle geschriebn ist ausgelesen und nicht nur der teil, den ich 
gerne hätte.

Folgenden Teilausschnitt betrifft das EEPROM
1
// String ins EEPROM abspeichern
2
eeprom_write_block (&uart_string, &eeFooNummer,sizeof(uart_string));  // Nummer ins EEPROM abspeichern
3

4
//Länge des Strings extra abspeichern
5
NummerLaenge = strlen(uart_string);          eeprom_write_byte(&eeFooLaengeNummer,NummerLaenge);  // Länge der Nnummer ins EEPROM abspeichern
6

7
//EEPROM auslesen
8
NummerLaenge = eeprom_read_byte (&eeFooLaengeNummer);    // Auslesen der Länge der Nnummer
9
eeprom_read_block( &EepromNummerAusgelesen, eeFooNummer, NummerLaenge  );    // Nummer aus dem EEPROM lesen

wenn ich jetzt einen string abspeicher kann ich ihn ohne Probleme 
auslesen. Wenn ich jetzt allerdings einen kleineren String als den 
gespeicherten abspeicher, wird die Länge korrekt angezeigt, beim 
auslesen werden aber die nicht überschriebenen Zeichen vom alten String 
mit ausgegeben.

Warum ist das so ?
Gast
siehe
1
//Länge des Strings extra abspeichern
2
NummerLaenge = strlen(uart_string);          eeprom_write_byte(&eeFooLaengeNummer,NummerLaenge);  // Länge der Nnummer ins EEPROM abspeichern

Das ist auch nicht das problem, wenn ich einen neuen kleineren String 
abspeicher und ich mir dann beim auslesen die Länge auch ausgeben lasse, 
passt die auch, nur wird immer alles von andere ausgegeben.
Bsp.:
ich sende über UART: 12345
aus EEPROM ausgelesen: 12345
Länge ausgelesen: 5
ich sende über UART: 124
Länge ausgelesen: 3
aus EEPROM ausgelesen: 12445

Obwohl ich vermutet habe, dass nur 124 ausgelesen wird.......

Ich find den Fehler einfach nicht.
Gast
Oh sorry, das wird am Telefon schlecht dargestellt. Hmm, strlen() gibt 
die Länge ohne das abschließende \0 zurück. Ob da der Haken liegt?
Gast
>eeprom_read_block( &EepromNummerAusgelesen, eeFooNummer, NummerLaenge  );

Müsste das nicht

eeprom_read_block( &EepromNummerAusgelesen, &eeFooNummer, NummerLaenge 
);

lauten?

Ich denke das das mit dem &EepromNummerAusgelesen falsch ist und

eeprom_read_block( EepromNummerAusgelesen, &eeFooNummer, NummerLaenge 
);

sein sollte.

Wo ist der komplette Code?
Gast
Nachtrag:

Wenn du EepromNummerAusgelesen am Ende nicht mit 0 abschliesst
wird natürlich auch der bereits enthaltene alte Schrott mit angezeigt.

Versuch mal EepromNummerAusgelesen[NummerLaenge] = 0;
nach dem auslesen.
Gast
Hallo,

danke für die Antworten.

Ist es dnen möglich, die EEPROM Stelle vor dem Beschreiben mit einem 
neuen Wert zu löschen oder zurückzusetzen?

Weil die Anzahl der Zeichen stimmt ja überein, nur wird halt der alte 
Teil irgendwie nicht gelöscht....

Gruß
So wie du das EEPROM beschreibst, brauchst du die Länge überhaupt nicht 
speichern. In C ist jeder gültige String \0 terminiert und enthält somit 
implizit seine Längenangabe.

Willst du die Länge speichern, dann musst du allerdings diese 
0-Terminierung beim Lesen aus dem EEPROM auch wieder korrekt herstellen.
Das hier
1
eeprom_read_block( &EepromNummerAusgelesen, eeFooNummer, NummerLaenge  );    // Nummer aus dem EEPROM lesen
gewährleistet das nicht. Denn NummerLaenge ist die Anzahl der Zeichen 
ohne die abschliessende \0 Terminierung.

Da du den String so in den Speicher schreibst:
1
eeprom_write_block (&uart_string, &eeFooNummer,sizeof(uart_string));  // Nummer ins EEPROM abspeichern
steht die \0-Terminierung sowieso im EEPROM (sofern das Ausgangsmaterial 
im Array korrekt war). Du könntest daher den String entweder so 
zurücklesen
1
eeprom_read_block( &uart_string, eeFooNummer, sizeof(uart_string));    // Nummer aus dem EEPROM lesen

oder so
1
eeprom_read_block( &EepromNummerAusgelesen, eeFooNummer, NummerLaenge+1  );    // Nummer aus dem EEPROM lesen

oder so
1
eeprom_read_block( &EepromNummerAusgelesen, eeFooNummer, NummerLaenge  );    // Nummer aus dem EEPROM lesen
2
EepromNummerAusgelesen[NummerLaenge] = '\0';

in all diesen Fällen wird die \0-Terminierung wieder korrekt 
hergestellt. Persönlich würde ich die erste Variante nehmen und die 
Länge überhaupt nicht im EEPROM speichern.

Und PS:
Bei Arrays brauchst du kein & um es an eine Funktion zu übergeben. 
Arrays werden immer so an Funktionen übergeben, dass der Arrayname als 
Startadresse des Speicherbereihs fungiert. Genau genommen ist es falsch 
hier ein & zu schreiben, nur haben hier die Compilerbauer anscheinend 
resigniert und akzeptieren diesen Operator an dieser Stelle. Eigentlich 
müsste hier eine Fehlermeldung kommen, denn eine Adresse hat selbst 
keine Adresse.
Gast
Vielen Dank für die sehr ausführliche Antwort.

Ich werde es heute Abend direkt ausprobieren und eine kurze Rückmeldung 
geben.

Wegen der Fehlermeldung kommt bei meinem Compiler nicht mal eine 
Warnung, wahrscheinlich ist die Stufe zu niedrig eingestellt oder was 
auch immer.

Mit freundlichen Grüßen

Thorsten

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 12 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.