Hi,
ich erhalte beim Lesen immer _|| hinter dem Zeichen, welches ich im
Eeprom gespeichert habe. Woran kann das liegen? Ich komm einfach nicht
dahinter. Hier ist mein Programm:
int main (void) {
char *addr = "0x01";
lcd_init();
while(!eeprom_is_ready());
eeprom_write_byte((unsigned char *)addr, 'F');
lcd_setcursor ( 0, 1);
char data;
while(!eeprom_is_ready());
data = eeprom_read_byte((unsigned char *)addr);
lcd_string("!!");
lcd_string("!!");
lcd_string(&data);
lcd_string("!!");
lcd_string("!!");
}
Was auch ein bisl komisch ist, wenn ich *addr als unsigned definiere,
sagt mein Compiler, dass der Wert "0x01" nicht unsigned ist (differs in
signedness). Die Funktion eeprom_write_byte und eeprom_read_byte nehmen
aber nur unsigned Werte an. Daher habe ich hier nochmal gecastet.
Vielleicht ist meine Deklaration auch komplett falsch?
Wäre super wenn mir jemand helfen könnte. Mich stört eigentlich nur das
"_||" hinter dem gespeicherten Zeichen.
Danke!
Gruß,
Martin
Klar, weil du nur das Zeichen 'F' in den EEPROM schreibst, ohne eine
abschließende '\0' um den String zu terminieren. Du behandelst beim
Ausgeben quasi ein einzelnes Zeichen als kompletten String.
> char *addr = "0x01";
Das ist aber auch Quatsch! Was versuchst du denn eigentlich zu machen?
Das Programm sieht sehr eigenartig aus.
Schon mal ein C-Buch in Erwägung zu ziehen, bevor du auf die Creme de la
Creme (Mikrocontroller in C) losgehst?
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#EEPROM
Hi,
ich bin in C tatsächlich nicht fit :). Habe aber schon einiges gelesen.
Ich raffe das meistens eh erst dann, wenn ich es in der Praxis anwende.
Ich habe deine Variante getestet. Schreibe ich "\0" hinter meinem
Zeichen, nimmmt der das nicht an. Der Compiler sagt:
main.c:215:43: warning: multi-character character constant
main.c: In function 'main':
main.c:215: warning: large integer implicitly truncated to unsigned type
Der Link von dir beschreibt das direkte Zugreifen auf ein EEPROM. Warum
das Rad neu erfinden?
char *addr = "0x02";
Wie soll ich sonst deklarieren? Bei allen anderen Varianten meckert der
Compiler. Bzw. gibt Warnings aus. Das hier ist die einzige Variante die
ohne Warning funktioniert.
Kann es sein das in dem Header eeprom.h das "\0" fehlt?
Gruß,
Martin
Sry. Habe jetzt erst gesehen das es ein anderer Link ist. Ich hatte
vorhin etwas ähnliches gelesen. Ich schau mir das mal an. Vielleicht
klappts dann ja :). Danke!
Martin schrieb:> Hi,>> ich bin in C tatsächlich nicht fit :). Habe aber schon einiges gelesen.> Ich raffe das meistens eh erst dann, wenn ich es in der Praxis anwende.>> Ich habe deine Variante getestet. Schreibe ich "\0" hinter meinem> Zeichen, nimmmt der das nicht an. Der Compiler sagt:>> main.c:215:43: warning: multi-character character constant> main.c: In function 'main':> main.c:215: warning: large integer implicitly truncated to unsigned type
Da kann man so nix zu sagen, außer: Code zeigen. Und außerdem habe ich
'\0' geschrieben und nicht "\0" (Ja, das ist ein Unterschied. Einzelnes
Zeichen vs. String).
> Der Link von dir beschreibt das direkte Zugreifen auf ein EEPROM. Warum> das Rad neu erfinden?
Was anderes als Direkt zugreifen machst du doch auch nicht?
> char *addr = "0x02";> Wie soll ich sonst deklarieren?
Na, wie wärs mit richtig? So wie es da jetzt steht legst du einen String
an und benutzt die RAM-Adresse des Strings irgendwie im EEPROM, wobei
der String nie benutzt werden würde. Also dermaßen am Ziel vorbei,
vorbeier geht es nicht mehr.
char* addr = (char*) 0x02;
wäre zum Beispiel ein Anfang, mal so aus der Hüfte getippt. Aber warum
lässt du die EEPROM Variablen nicht direkt vom Compiler verwalten? Der
reserviert für dich dann den EEPROM Speicher, sodass du nicht aus
versehen zwei Variablen überlappend anlegst. Siehe den Artikel.
> Bei allen anderen Varianten meckert der> Compiler. Bzw. gibt Warnings aus. Das hier ist die einzige Variante die> ohne Warning funktioniert.
Und das heißt dann, dass die richtig ist? Is klar!
> Kann es sein das in dem Header eeprom.h das "\0" fehlt?
Nein, das kann nicht sein (Mal davon abgesehen, dass diese Aussage
einfach keinen Sinn ergibt).
Du solltest wirklich erst mal anfangen ein C Tutorial oder ein C Buch
(besser) durchzulesen. Alles andere macht es nur noch komplizierter.
Martin schrieb:> char *addr = "0x02";> Wie soll ich sonst deklarieren? Bei allen anderen Varianten meckert der> Compiler. Bzw. gibt Warnings aus. Das hier ist die einzige Variante die> ohne Warning funktioniert.
Um das beantworten zu können, müsstest du erst mal erklären, was das
überhaupt werden soll. Falls du einfach an die Adresse 0x02 im EEPROM
schreiben willst, sähe das z.B. so aus:
1
uint16_taddr=0x02;
2
eeprom_write_byte((uint_8*)addr,'F');
> Kann es sein das in dem Header eeprom.h das "\0" fehlt?
Was sollte das dort auch zu suchen haben?
Dein Problem ist dies:
1
chardata;
2
...
3
lcd_string(&data);
Du hast ein einzelnes Zeichen, und übergibst dann die Adresse dieses
Zeichens an eine Funktion, die unter der Adresse einen String erwartet.
Mit dem EEPROM und was darin steht, hat das Problem rein gar nichts zu
tun.
Das offizielle Beispiel funktioniert bei mir auch nicht:
lcd_init();
uint8_t eeFooByte = 123;
uint8_t myByte;
lcd_setcursor ( 0, 1);
myByte = 98;
eeprom_write_byte(&eeFooByte, myByte);
myByte = eeprom_read_byte(&eeFooByte);
lcd_string(&myByte);
Bei der Ausgabe erhalte ich immer ein _|| hinter dem Zeichen
Was für ein "offizielles Beispiel" soll das denn sein?
Du machst da exakt den gleichen Fehler wie oben. Nochmal: das Problem
hat mit dem EEPROM und seinem Inhalt nicht das geringste zu tun.
Genau, siehe 1. Antwort:
Simon K. schrieb:> Klar, weil du nur das Zeichen 'F' in den EEPROM schreibst, ohne eine> abschließende '\0' um den String zu terminieren. Du behandelst beim> Ausgeben quasi ein einzelnes Zeichen als kompletten String.
Oder auch von Stefan:
Stefan Ernst schrieb:> Dein Problem ist dies: char data;> ...> lcd_string(&data);> Du hast ein einzelnes Zeichen, und übergibst dann die Adresse dieses> Zeichens an eine Funktion, die unter der Adresse einen String erwartet.> Mit dem EEPROM und was darin steht, hat das Problem rein gar nichts zu> tun.
PS: Du hast übrigens anscheinend nicht das Geringste verstanden vom dem
Artikel. Bei der Variable eeFooByte muss das Schlüsselwort EEMEM
angegeben werden! Ansonsten macht der Code keinen Sinn, da eeFooByte im
RAM liegt, du aber auf der gleichen Adresse im EEPROM rumwerkelst.
So, ich lese gerade C für Linux in 21 Tagen und bin jetzt genau an
dieser Stelle mit dem \0. :) Mir wird jetzt einiges klarer. Ich hoffe,
dass ich das Buch noch diese Woche durcharbeiten kann. Bin jetzt erst
bei der Hälfte. Danach werde ich mir nochmal das AVR Tutorial reinziehen
und nochmal von vorne anfangen... Trotzdem danke für die Antworten.