www.mikrocontroller.net

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


Autor: Martin (Gast)
Datum:

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

Autor: Simon K. (simon) Benutzerseite
Datum:

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

Autor: Martin (Gast)
Datum:

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

Autor: Martin (Gast)
Datum:

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

Autor: Simon K. (simon) Benutzerseite
Datum:

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

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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:
uint16_t addr = 0x02;
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:
 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.

Autor: Martin (Gast)
Datum:

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

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
 uint8_t myByte;
..
 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.

Autor: Simon K. (simon) Benutzerseite
Datum:

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

Autor: Martin (Gast)
Datum:

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

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.