Hallo,
ich habe mir zwei Unterprogramme für die Ansteuerung eines LCD-Displays
geschrieben.
1
string_senden();//sendet einen String aufs Display
2
3
zeichen_senden();//sendet ein einzelnes Zeichen ans Display
Die beiden Programme funktionieren einwandfrei. Wenn ich allerdings
einen String mit ä, ö oder ü sende, wird anstelle der Zeichen nur ein
komisches Zeichen dargestellt.
1
string_senden("Programm wählen");//Hier wird anstelle des ä ein komisches Zeichen dargestellt.
Mein Display kann mit dem Hex-Code 0xE1 ein ä darstellen.
Mit folgendem code funktioniert es einwandfrei:
1
string_senden("Programm w"
2
zeichen_senden(0xE1);
3
string_senden("hlen")
Allerdings ist das etwas umständlich. Gibt es eine Möglichkeit, den
String in einem Aufruf zu senden. printf und solche Sachen würde ich
wenn möglich nicht nutzen, da dies ja viel Speicher verbraucht.
Fabian O. schrieb:> Ersetze die Sonderzeichen doch einfach in der zeichen_senden()-Funktion.
Dazu muss ich ermitteln, was an das Display bei einem Sonderzeichen
gesendet wird, muss bei jedem Zeichen das abfragen und wenn ein
Sonderzeichen kommt das Zeichen ersetzen. Wäre eine Möglichkeit. Aber
ein Problem:
Beim ü und ö wird irgend was komisches angezeigt. Hier geht das mit dem
ersetzen, da ich diese komischen Zeichen nicht brauche. Beim ä wird aber
ein µ angezeigt. Wenn ich ersetze, kann ich kein µ mehr anzeigen, wenn
das gewollt ist, da das Zeichen dann durch ein ä ersetzt wird.
Gibt es keine Möglichkeit, den String beim Unterprogrammaufruf so
einzugeben, dass gleich das korrekte Zeichen übermittelt wird?
>Gibt es keine Möglichkeit, den String beim Unterprogrammaufruf so>einzugeben, dass gleich das korrekte Zeichen übermittelt wird?
string_senden("Programm w\0xE1hlen");
Wenn du deinen String sendest, tust du das Zeichen für Zeichen. Das
heißt du guckst vor jedem Senden ob es sich bei deinem Zeichen um ein
Sonderzeichen handelt und schreibst es manuell um.
Ingo
Es gibt eine Reihe von Möglichkeiten das Problem zu lösen. Unter anderem
in verschiedenen Ausprägungen auch diejenigen die Du angedeutet hast.
Aber ein Missverständnis solltest Du doch vorher noch klären.
>Beim ä wird aber ein µ angezeigt.>Wenn ich ersetze, kann ich kein µ mehr anzeigen, wenn>das gewollt ist, da das Zeichen dann durch ein ä ersetzt wird.
Dieses Aussage leitet sich, für mich, aus nichts was ich sonst weiss,
ab. Wie kommst Du darauf?
Nehme ich mal einen Irrtum oder eine Fehlinformation vorweg, dann ist
das so: Es gibt keinen Zwang beim Austausch von 'ä' gegen 'µ' auch
gleichzeitig 'µ' gegen 'ä' auszutauschen. Ob Du das tust oder nicht
steht Dir frei. Es steht Dir auch frei ein schon einmal gegen ein 'µ'
ausgetauschtes 'ä' nocheinmal oder eben nicht noch einmal zurück gegen
ein 'µ' zu tauschen.
Willst Du wirklich beide Übersetzungen in jedem auftretenden String
realisieren, dann musst Du nur dafür sorge, das die Übersetzung nur
einmal erfolgt.
Wenn Du Deine Aussage nocheinmal genau betrachtest, erkennst Du, das Du
mit "Wenn ich ersetze..." eine Verkürzung in mehrerlei Hinsicht
vorgenommen hast. Ich schreibe das nicht, weil das schlimm ist oder
dumm, sondern weil es ein Zeichen ist, das Du einen Gedanken nicht
präzis genug formuliert hast um ihn zu realisieren. Verstehst Du was ich
meine?
Es fehlt: "was" und "wodurch". Es fehlt: Zu welchen Zeitpunkt? In
welcher Folge?
Das sind ja keine Fragen die Dir nicht aus dem täglichen Leben nicht
schon bekannt wären. Hat also nichts mit Anfänger zu tun. Erst das
Waschpulver und die Wäsche (die aber in beliebiger Reihenfolge) dann die
Tür schliessen, dann starten. Nicht die Wäsche in das Waschpulverfach
sondern. etcpp.
Genauso detailliert musst Du Dir vor allem bei auftauchenden Problemen
klarmachen, was geschieht, bzw. was geschehen soll.
Hoffe das hilft Dir.
R. F. schrieb:> Beim ä wird aber> ein µ angezeigt. Wenn ich ersetze, kann ich kein µ mehr anzeigen, wenn> das gewollt ist, da das Zeichen dann durch ein ä ersetzt wird.
Du ersetzt eben in zeichen_senden() auch ein 'µ' durch den Code, den ein
'ä' jetzt liefert. Du brauchst also eine Zuordnung zwischen
Eingabezeichen und Code für das Display.
Der Zeichensatz eines Displays stimmt oft nicht mit dem Zeichensatz des
PC überein. Dann definiert man eigene Zeichen, wie die Umlaute ä, ö, ü,
und ß. Das muß man dann auch in der Software noch mal berücksichtigen.
R. F. schrieb:> Beim ä wird aber ein µ angezeigt. Wenn ich ersetze, kann ich kein µ> mehr anzeigen, wenn das gewollt ist, da das Zeichen dann durch ein> ä ersetzt wird.
Doch, du darfst einfach nur kein "ä" senden, wenn du ein "µ" anzeigen
möchtest. Vergleiche einfach den Character-Generator von deinem Display
und den Zeichensatz, den du sonst verwendest. Und für den Fall der Fälle
bieten viele Displays auch die Möglichkeit einige Zeichen selbst frei zu
definieren.
Tschortsch schrieb:>>Gibt es keine Möglichkeit, den String beim Unterprogrammaufruf so>>einzugeben, dass gleich das korrekte Zeichen übermittelt wird?>> string_senden("Programm w\0xE1hlen");
Habe ich schon ausprobiert. Funktioniert wei dem Wort wählen auch
wunderbar, da dem Sonderzeichen ein h folgt.
Folgt dem Sonderzeichen aber einer der Buschstaben zwischen A und E
funktioniert es nicht.
Beispiel: "Sonderzeichen üben"
hier sende ich: "Sonderzeichen \xF5ben" (F5 steht bei meinem Display für
ü)
Dann kommt heraus: "Sonderzeichen *n" (Anstelle dem Stern irgend
einanderes komisches Zeichen.
Offenbar erkennt der Compiler \xF5BE als Zeichen, da B und E im
HEX-Format als "Zahl" vorkommt. Da das ganze gebilde dann zu lang wird,
nimmt er nur die letzten 2 Stellen und sendet in dem Beispiel BE, was
mit dem angezeigten Zeichen dann übereinstimmt.
Übrigens: Atmel Studio 6 und Mega16A
Man muß sein Zeichen natürlich in der Software zu dem selbst definierten
Zeichen übersetzen. Um ein ü zu senden, was man bspw. in der
Speicherstelle 7 definiert hat, muß man dann das ü zu 7 übersetzen.
Vollautomatisch macht es das Display nämlich nicht.
>Offenbar...
Da ist keine Vermutung nötig. Das ist genau festgelegt. Lies das bitte
nach.
Es werden nur und genau die ersten beiden Ziffern nach dem x als Teil
der Hexzahl betrachtet.
>Beispiel: "Sonderzeichen üben">hier sende ich: "Sonderzeichen \xF5ben" (F5 steht bei meinem Display für>ü)>Dann kommt heraus: "Sonderzeichen *n" (Anstelle dem Stern irgend>einanderes komisches Zeichen.
Dann musst du das Sonderzeichen als Oktalzahl eingeben.
Ein Byte als Oktalzahl besteht immer aus drei Stellen. Im String werden
Oktalzahlen mit \0 eingegeben, dann gibts keine Verwechslungsmöglichkeit
mehr.
hexadezimal F5 = dezimal 245 = oktal 365
string_senden("Sonderzeichen \0365ben");
Zum Umrechnen von Hex nach Oktal kann man bequem den Windows
Taschenrechner verwenden.
Hmm schrieb:>>Offenbar...>> Da ist keine Vermutung nötig. Das ist genau festgelegt. Lies das bitte> nach.> Es werden nur und genau die ersten beiden Ziffern nach dem x als Teil> der Hexzahl betrachtet.
Diese Lösung wäre mir ehrlich gesagt am liebsten. Aber wie bereits
geschrieben, funktionieren tut es bei mir mit dem Atmel Studio nicht.
Mache ich eventuell bei der Eingabe was falsch? Anstelle des
Sonderzeichens schreibe ich z.B. \xF5, ohne weitere Formatierung. Das
müsste doch so korrekt sein, und funktioniert ja auch, solange kein A-F
folgt.
Ich habe mir aber nochmals zu dem ersetzen Gedanken gemacht. Ich hatte
da mit meinen µ und ä noch einen Denkfehler. Ich glaube ich habe eine
funktionierene Lösung im Kopf. Muss es nur noch Programmieren und
testen.
Werde dann noch mal Rückmeldung geben.
Tschortsch schrieb:> Ein Byte als Oktalzahl besteht immer aus drei Stellen. Im String werden> Oktalzahlen mit \0 eingegeben, dann gibts keine Verwechslungsmöglichkeit> mehr.
\0 erkennt mein Programm string_senden als Stringende und höhrt auf zu
senden.
>Diese Lösung wäre mir ehrlich gesagt am liebsten.
Es geht hier nicht um eine Lösung. Was ich beschrieb war keine Lösung,
sondern ein Teil der Sprach-Definition. Das ist so. Egal ob Du das als
Lösung betrachtest oder nicht. Du hast gar keine Wahl.
Es ist wahrscheinlicher das Deine Beobachtung nicht vollständig oder
korrekt ist. Oder das Deine Beschreibung der Umgebung nicht vollständig
ist. Es gibt durchaus denkbare Fälle wo dieses Verhalten sinnvoll ist.
Nur passen die normalerweise und nicht widerspruchsfrei zu Deiner
Situation. z.B. Unicode-Strings.
Deswegen ist das hier:
>Ich habe mir aber nochmals zu dem ersetzen Gedanken gemacht.
auch zwecklos, solange die Voraussetzungen für diese Gedanken nicht
korrekt sind. Du kommst nämlich zu falschen Schlüssen, solange die zur
Voraussetzung haben, das \x nicht so funktioniert wie beschrieben.
>Mache ich eventuell bei der Eingabe was falsch? Anstelle des>Sonderzeichens schreibe ich z.B. \xF5, ohne weitere Formatierung. Das>müsste doch so korrekt sein, und funktioniert ja auch, solange kein A-F>folgt.
Du beliebst leider keine Angaben zu dem Display oder zu der Library zu
machen. Ergänze das bitte erstmal.
>\0 erkennt mein Programm string_senden als Stringende und höhrt auf zu>senden.
Ja. Das stimmt auch mit dem Sprachstandard überein.
Es stand ja auch da:
>in Byte als Oktalzahl besteht immer aus drei Stellen.
Bitte lies solche Aussagen immer gründlich und vollständig. Du kannst
nicht einfach nach belieben Teile von Aussagen weglassen, darauf
basierend was probieren und uns das hier als Fehler präsentieren ohne
auf die Dauer Unmut oder jedenfalls Weg-Gehen zu provozieren. Und lies
bitte immer eine C-Buch parallel zu solchen Sprachdefinitions-Fragen.
Nicht alles kann man immer feherfrei und vollständig wiedergeben.
R. F. schrieb:> Hmm schrieb:>>>Offenbar...>>>> Da ist keine Vermutung nötig. Das ist genau festgelegt. Lies das bitte>> nach.>> Es werden nur und genau die ersten beiden Ziffern nach dem x als Teil>> der Hexzahl betrachtet.>> Diese Lösung wäre mir ehrlich gesagt am liebsten.
Abgesehen von der Defintion, wie man Character durch Angabe ihres
Hex-Codes in einen String einbettet, ist diese Lösung trotzdem Unsinn.
Denn du willst dich nicht um solche Dinge kümmern müssen. Als
Programmierer willst du schreiben
lcd_string( "bitte wählen" );
und es ist Aufgabe der lcd_string Funktion bzw. der Funktion die von der
lcd_string benutzt wird um ein Zeichen (Achtung: Zeichen! Nicht Byte!)
auszugeben, für das 'ä', bzw. all die anderen Zeichen, den jeweils
zuständigen Code ans LCD zu schicken, den das LCD für dieses Zeichen
eben haben will. So viele derartige Sonderzeichen sind das ja nicht.
Alles andere ist zwar insofern interessant, weil es ein Technik ist, die
man als C-Programmierer selbstverständlich ebenfalls beherrschen muss,
aber in diesem Fall ist es Unsinn das so zu lösen.
Als Autofahrer kümmerst du dich ja auch nicht darum, welches Zahnrad in
welches andere Zahnrad greifen muss, damit der 4. Gang eingelegt ist.
Das ist Aufgabe des Getriebes das zu tun. Du legst den Ganghebel einfach
in das Fach der H-SChaltung, welches mit 4 beschriftet ist. Und den Rest
erledigt die Mechanik.
So, jetzt habe ich mal meinen Code für zeichen_senden erweitert. Ich
ersetze jetzt mittels einer switch case die Zeichen ä ö und ü.
Funktioniert einwandfrei. Jetzt noch in Fleissarbeit die restlichen
benötigten Sonderzeichen einfügen und das Problem ist gelößt.
Jetzt kann ich ganz normal string_senden("Sonderzeichen üben"); eingeben
und es wird korrekt angezeigt.
Mein Problem ist damit gelößt. Jetzt kann ich an meinem Projekt
weiterarbeiten.
Allerdings würde mich noch interessieren, warum es mit \xF5 nicht
funktioniert.
Ich gebe ein: string_senden("Sonderzeichen \xF5ben");
Es wird angezeigt: Sonderzeichen *n
Ich gebe ein: string_senden("Sonderzeichen \xF5iben");
Es wird angezeigt: Sonderzeichen üiben
Bei dem unteren Beispiel mache ich einen Schreibfewhler mit dem
zusätzlichen i, damit auf die HEX-Zahl kein A-F folgt. Dann ist die
Anzeige korrekt.
Hier nochmal ein paar Daten:
Mega16A
AtmelStudio 6
4x20er Display mit ST7066-Controller ROM-Code 0A
Die Programme habe ich komplett selbst geschrieben, verwende also keine
fertige Library (erhöht den Lerneffekt).
Durch das viele Ausprobieren und ändern fehlt hier momentan etwas die
Struktur. Ich bringe das ganze mal noch in "Form" und kann das Programm
dann noch hochladen.
R. F. schrieb:> So, jetzt habe ich mal meinen Code für zeichen_senden erweitert. Ich> ersetze jetzt mittels einer switch case die Zeichen ä ö und ü.> Funktioniert einwandfrei.
Na also. Durch den switch case muß alles durch. Bleibt immer noch die
Frage, ob man wirklich alles mit deutschen Umlauten dar stellen muß.