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 ?
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.
>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?
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.
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.
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
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.