Forum: Mikrocontroller und Digitale Elektronik Mal wieder String auf LCD


von Henk (Gast)


Lesenswert?

Tag Ihr Leute,

ich komm gleich zur Sache, kay?
Umgebung: ATMEGA16 @8Mhz mit HD44780 im 4Bit Modus mit Data an C0-C3; 
programmierung unter WinAVR, Zeichenausgabe funktioniert mit folgender 
Funktion:

______________________________________________________________________ 
_
void dout(unsigned char data)
{
  unsigned char dbackup=data;  //backup machen
  data=data>>4;      //oberers nibble nach unten
  data=data&0x0F;      //oberes nibble 0
  PORTC=data|(1<<PC4);    //an LCD-Port und RS (PC4) high
  en();        //enable strobe

  dbackup=dbackup&0x0F;    //original char, oberes nibble 0
  PORTC=dbackup|(1<<PC4);    //an LCD-Port mit RS high
  en();        //enable strobe
}
______________________________________________________________________ 
_

Geht alles wie gesagt "wunderbärchen", aber ich kriegs auch NACH googlen 
und  Tutorial- bzw. Forumssuche nicht hin, einen String aufs Display zu 
zaubern. Das wird wohl mit nem char-array[] in verbindung mit sprintf 
und nem zeiger gemacht, aber ich kriegs nicht gebacken.
Für die alten Hasen im Haus (KaHeBu, PeDa & Co.) sind das um drei Uhr 
nachts drei Zeilen in drei Sekunden aber mir könnte es drei Tage des 
langen WE versauen : )

Wenn jemand nen Vorschlag hätte und vielleicht noch was zum Thema 
Fließkomma nach String unter selben Voraussetzungen beizutragen hätte, 
das wär einfach, ja - wie Ostern halt.

Cheers,

Henk

von ARM-Fan (Gast)


Lesenswert?

Bin zwar keiner der genannten "Hasen", aber ich kriegs auch hin... ;-)
1
void LcdString(char * pStr)
2
{
3
  while(*pStr)
4
  {
5
     dout(*pStr++);
6
  }
7
}
8
9
void main()
10
{
11
  char meinText[] = "Hallo Welt";
12
  char meinBuffer[10];
13
  float zahl = 123.45;
14
15
  LcdString(&meinText);
16
17
  sprintf(&meinBuffer, "Wert: %f", zahl);
18
  LcdString(&meinBuffer);
19
}

  

von ARM-Fan (Gast)


Lesenswert?

Sorry, das mit dem sprintf wird in die Hose gehen, weil der "buffer"
mit seinen 10 Zeichen nicht groß genug für das Ergebnis ist.

Aber sollte ja nur ein Beispiel sein... ;-)

von He Ro (Gast)


Lesenswert?

Moin,

du solltest die & weglassen, denke ich - denn meinBuffer bzw. meinText 
ist ja schon ein Pointer auf das erste Zeichen des Strings (oder halt 
&(meinText[0]) schreiben - wobei ich denke, man kann hier die Klammern 
auch weglassen)

Wenn man nun die Adresse des Pointers übergibt...

Ohne Gewähr, HeRo

von Robert S. (razer) Benutzerseite


Lesenswert?

Klammern sind nicht notwendig

von Henk (Gast)


Lesenswert?

Yahoo!

Werds direkt morgen ausprobieren...

Besten Dank, ihr Buben!

Henk

von Henk (Gast)


Lesenswert?

Funktioniert! Danke nochmal!

von Joachim B. (jojo84)


Lesenswert?

Guten Morgen!

Ich benutze einfach mal dieses Thema hier, weil es passt und ich dann 
nicht extra ein neues Thema aufmachen muß :)

Aaalso, ich hab hier ein Pollin-LCD, wo ein nicht ganz standardmäßiger 
Zeichensatz drin ist (wer hätts gedacht ;) ...).

Jetzt möchte ich ein Array als String mit z.B. Umlauten ausgeben. Wo 
sich die Umlaute und so im Speicher des LCD befinden hab ich schon 
rausgefunden. Aber ich krieg da iwie keine hübsche Syntax hin!

Zur Ausgabe von Strings benutze ich die Funktion aus dem Tutorial. Wenn 
ich jetzt z.B. "Zurück" ausgeben will, und das "ü" z.B. an Stelle 0x9A 
im Speicher liegt, muß ich das natürlich explizit an die 
Ausgabe-Funktion übergeben. Da würd ich gern schreiben:
1
char string_1[] = {"Zur", 0x9A, "ck"};
2
lcd_string(string_1);

Aber das geht nicht. Da sagt der Compiler:
../menue.c:12: error: (near initialization for 'string_1')
../menue.c:12: error: excess elements in char array initializer
(2x)

Ich muß im Moment schreiben:
1
char string_1[] = {'Z', 'u', 'r', 0x9A, 'c', 'k'};
2
lcd_string(string_1);

Aber da tipp ich mir ja nen Wolf! Ich hab schon das Netz durchforstet, 
aber ich find nix geschickteres... :( Hab ihr ne Idee, wie das hübscher 
geht?

Danke,
mfG,

Joachim

von Peter D. (peda)


Lesenswert?

1
char string_1[] = {"Zur" "\x9A" "ck"};
2
lcd_string(string_1);


Peter

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

"Zur", 0x9A, "ck"
ist gleich
 'Z', 'u', 'r', '\0', 0x9A, 'c', 'k', '\0'
Fällt dir was auf?

Mach doch eine Konvertierung in Echtzeit. Wenn also deine Ausgaberoutine 
ein 'ü' bekommt gibt sie ein 0x9A aus. Das kostet zwar etwas Rechenzeit, 
ist aber an andere Displays problemlos anpassbar.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> char string_1[] = {"Zur" "\x9A" "ck"};
Geht das wirklich? Werden die Strings ohne Terminierung zusammengefasst?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

char * string_1 = "Zur\232ck"; // \232 ist eine Oktalzahl

von Klaus W. (mfgkw)


Lesenswert?

1
char string_1[] = {"Zur""\x9A""ck"};

Edit: ok, zu spät

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> char * string_1 = "Zur\232ck"; // \232 ist eine Oktalzahl
Was, wenn ich jetzt aber "Menü3" ausgeben will?
char * string_1 = "Men\2323"; // \2323 ist auch eine Oktalzahl

von Klaus W. (mfgkw)


Lesenswert?

Lothar Miller schrieb:
> Geht das wirklich? Werden die Strings ohne Terminierung zusammengefasst?

Ja!
Seit K&R werden aufeinanderfolgende Strings vom Compiler zusammengefasst 
und nur der letzte terminiert.

von Klaus W. (mfgkw)


Lesenswert?

Lothar Miller schrieb:
>> char * string_1 = "Zur\232ck"; // \232 ist eine Oktalzahl
> Was, wenn ich jetzt aber "Menü3" ausgeben will?
> char * string_1 = "Men\2323"; // \2323 ist auch eine Oktalzahl

Deshalb die zusätzlichen "":
1
char * string_1 = "Men\232""3";

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Lothar Miller schrieb:
>> char * string_1 = "Zur\232ck"; // \232 ist eine Oktalzahl
> Was, wenn ich jetzt aber "Menü3" ausgeben will?
> char * string_1 = "Men\2323"; // \2323 ist auch eine Oktalzahl

Probiere es doch mal aus.

von Karl H. (kbuchegg)


Lesenswert?

Lothar Miller schrieb:
> "Zur", 0x9A, "ck"
> ist gleich
>  'Z', 'u', 'r', '\0', 0x9A, 'c', 'k', '\0'
> Fällt dir was auf?
>
> Mach doch eine Konvertierung in Echtzeit. Wenn also deine Ausgaberoutine
> ein 'ü' bekommt gibt sie ein 0x9A aus. Das kostet zwar etwas Rechenzeit,
> ist aber an andere Displays problemlos anpassbar.

Ist eine Möglichkeit.
Eine andere sieht so aus
1
#define CHAR_UE  "\x9A"
2
3
...
4
  char string_1[] = {"Zur" CHAR_UE "ck"};
5
  lcd_string(string_1);
6
...

Dann ist ebenfalls die leichte Austauschbarkeit gegeben.

von Klaus W. (mfgkw)


Lesenswert?

Makros gross zu schreiben, ist ja gut und schön.
Aber wie willst du jetzt ein großes Ü definieren? :-)

(Nicht schlagen, ich bin schon weg!)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Seit K&R werden aufeinanderfolgende Strings vom Compiler
> zusammengefasst und nur der letzte terminiert.
An dem Tag muß ich gerade krank gewesen sein... ;-)
Man lernt nie aus...

Stefan B. schrieb:
> Probiere es doch mal aus.
Gesagt, getan. Ergebnis:
1
   char t1[] = { "Hallo" " " "\"Welt\"" };
2
   printf("%s\n", t1);
3
4
   char t2[] = { "Hallo"" ""Welt" };
5
   printf("%s\n", t2);
6
7
   char t3[] = { "Hallo" " " "Welt" };
8
   printf("%s\n", t3);
9
10
   char t4[] = { "\x48""allo"" ""Welt" };
11
   printf("%s\n", t4);
12
13
   char t5[] = { "\110""allo"" ""Welt" };
14
   printf("%s\n", t5);
15
16
   char t6[] = { "\110allo"" ""Welt" };
17
   printf("%s\n", t6);
Gibt (mit MSVC++ 6.0)
1
Hallo "Welt"
2
Hallo Welt
3
Hallo Welt
4
Hallo Welt
5
Hallo Welt
6
§ a   b b
Fazit: die Oktalzahl sollte mit einem " terminiert werden... ;-)

von Karl H. (kbuchegg)


Lesenswert?

Lothar Miller schrieb:
>> Seit K&R werden aufeinanderfolgende Strings vom Compiler
>> zusammengefasst und nur der letzte terminiert.
> An dem Tag muß ich gerade krank gewesen sein... ;-)
> Man lernt nie aus...

Ja, das wissen viele nicht.
Dabei ist das so praktisch
1
  char Helptext[] = { "Dies ist ein Helptext\n"
2
                      "der aus mehreren Zeilen besteht.\n"
3
                      "Zwecks leichterer Editierbarkeit\n"
4
                      "wird er an den tatsächlichen Zeilenenden\n"
5
                      "auch im Editor umgebrochen, damit man auch im\n"
6
                      "Editor schon ungefähr sieht, wie es nachher\n"
7
                      "bei der Ausgabe aussehen wird.\n"
8
                      "\n"
9
                      "Besonders bei Tabellen oder wenn irgendwelche\n"
10
                      "Ausrichtungen zu berücksichtigen sind,\n"
11
                      "ist sowas extrem hilfreich:"
12
                      "Optionen      Bedeutung\n"
13
                      "-t            Tab auflösen\n"
14
                      "-n            kein CR senden\n"
15
                      "-s            sortiert\n"

von Stefan B. (stefan) Benutzerseite


Angehängte Dateien:

Lesenswert?

Lothar Miller schrieb:

> Stefan B. schrieb:
>> Probiere es doch mal aus.
> Gesagt, getan. Ergebnis:
>
>    char t6[] = { "\110allo"" ""Welt" };
>    printf("%s\n", t6);
>
> Gibt (mit MSVC++ 6.0)
> § a   b b
> Fazit: die Oktalzahl sollte mit einem " terminiert werden... ;-)

Seltsam, das kann ich nicht nachvollziehen. GCC (MinGW/MSYS) verhält 
sich beim Beispiel t6 ganz anders (s. Anhang)

von Klaus W. (mfgkw)


Lesenswert?

Lothar Miller schrieb:
>> Seit K&R werden aufeinanderfolgende Strings vom Compiler
>> zusammengefasst und nur der letzte terminiert.
> An dem Tag muß ich gerade krank gewesen sein... ;-)
> Man lernt nie aus...

Ich musste mich auch schwer beherrschen, nicht dezent auf
ein C-Buch hinzuweisen :-)
Aber das wäre bei dir erstens ungerecht gewesen, und zweitens
früher oder später auf mich zurück gefallen, wenn ich wieder
einen Bock schieße.

Aber in den Fingern hat es schon ziemlich gejuckt...

von Klaus W. (mfgkw)


Lesenswert?

Klaus Wachtler schrieb:
> Seltsam, das kann ich nicht nachvollziehen. GCC (MinGW/MSYS) verhält
> sich beim Beispiel t6 ganz anders (s. Anhang)

Ich habe auch ziemlich fest in Erinnerung, daß bei Hex-Werten
maximal zwei Stellen genutzt werden und der Rest nicht dazu gehört,
und bei Oktalzahlen drei Stellen.
Der gcc 4.3.2 scheint da gelegentlich auch mehr Stellen vernaschen zu
wollen; ich glaube fest, daß sich das Verhalten hier geändert hat -
vielleicht im Zuge der Unicode-Infektion.
Was der Standard dazu sagt (welcher überhaupt?), weiß ich nicht.

Aber in Zukunft wird man wohl ein paar mehr Gänsefüßchen spendieren 
müssen.

von Klaus W. (mfgkw)


Lesenswert?

PS: Was macht das Board hier denn falsch?
Ich habe nicht mich selbst zitiert, sondern Stefan B. (stefan).

von Joachim B. (jojo84)


Lesenswert?

Ui, das schlug ja ein, wie eine Bombe ;) ...

Auf jeden Fall Dankeschön für die Antworten, das hat geholfen!

Gruß

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Stefan B. schrieb:
> Seltsam, das kann ich nicht nachvollziehen.
Das hat mich stutzig gemacht, und tatsächlich:
ich habe mich selber aufs Glatteis gelegt... :-/
1
   char t1[] = { "Hallo" " " "\"Welt\"" };
2
   printf("%s\n", t1);
3
4
   char t2[] = { "Hallo"" ""Welt" };
5
   printf("%s\n", t2);
6
7
   char t3[] = { "Hallo" " " "Welt" };
8
   printf("%s\n", t3);
9
10
   char t4[] = { "\x48""allo"" ""Welt" };
11
   printf("%s\n", t4);
12
13
   char t5[] = { "\110""allo"" ""Welt" };
14
   printf("%s\n", t5);
15
16
   char t6[] = { "\110allo"" ""Welt" };
17
   printf("%s\n", t6);
18
19
   char t7[] = { "\60\61""2""\x33""4" }; // = "01234"
20
   printf("%s\n", t7);
Gibt korrekt:
1
Hallo "Welt"
2
Hallo Welt
3
Hallo Welt
4
Hallo Welt
5
Hallo Welt
6
Hallo Welt
7
01234


Mit
1
char t7[] = { "\60\612""\x334" }; // = "01234"
Kommen die Fehler
error C2022: '394' : too big for character
error C2022: '820' : too big for character
Es werden also sowohl bei Oktal- wie auch bei Hexzahlen alle in Frage 
kommenden Ziffern dazugenommen...

EDIT:
>> PS: Was macht das Board hier denn falsch?
Es markiert nur 2 Stellen einer Hex-Zahl als signifikant (s.o. \x33 
lila, die 4 dann rot).

von Andreas F. (aferber)


Lesenswert?

Lothar Miller schrieb:
> Mit
>
1
> char t7[] = { "\60\612""\x334" }; // = "01234"
2
>
> Kommen die Fehler
> error C2022: '394' : too big for character
> error C2022: '820' : too big for character
> Es werden also sowohl bei Oktal- wie auch bei Hexzahlen alle in Frage
> kommenden Ziffern dazugenommen...

Bei Oktal nach Standard: nö, nicht alle, aber bis zu drei Stellen, wobei 
es nur darauf ankommt, dass das gültige Oktalziffern (0-7) sind, nicht 
ob am Ende noch ein gültiges Zeichen rauskommt (bei 8 Bit i.d.R. \000 
bis \377).
1
octal-escape-sequence:
2
        \ octal-digit
3
        \ octal-digit octal-digit
4
        \ octal-digit octal-digit octal-digit

Bei Hex: hier werden in der Tat beliebig viele Stellen geschluckt, 
solange es gültige Hexziffern sind.
1
hexadecimal-escape-sequence:
2
        \x hexadecimal-digit
3
        hexadecimal-escape-sequence hexadecimal-digit

Andreas

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.