Forum: Mikrocontroller und Digitale Elektronik _|| in flash? eeprom_read_byte()


von Martin (Gast)


Lesenswert?

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

von Simon K. (simon) Benutzerseite


Lesenswert?

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

von Martin (Gast)


Lesenswert?

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

von Martin (Gast)


Lesenswert?

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!

von Simon K. (simon) Benutzerseite


Lesenswert?

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.

von Stefan E. (sternst)


Lesenswert?

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_t addr = 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
 char data;
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.

von Martin (Gast)


Lesenswert?

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

von Stefan E. (sternst)


Lesenswert?

1
 uint8_t myByte;
2
..
3
 lcd_string(&myByte);

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.

von Simon K. (simon) Benutzerseite


Lesenswert?

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.

von Martin (Gast)


Lesenswert?

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.

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.