Forum: Mikrocontroller und Digitale Elektronik Einfache Display Funktion.erweiterung


von Oliver D. (highspeed-oliver)


Lesenswert?

Hallo Leute,

nachdem mein Display nun Prima läuft bin ich gerade dabei mit meinen C 
Kenntnissen eine Funktion oder mehrere zu schreiben, die mir einen 
eingegebenen String auf meinem LCD anzeigt.
Gedacht ist es so das in ein "text[9]" für den anfang 10 kleinbuchstaben 
geschrieben werden. Diese sind dann auf dem Display anzuzeigen.

Nun dachte ich mir, eine Tabelle in form eines arrays oder eines:
int a=01100001; //Standard ASCI und Hitachi HD44780 belegung
int b=01100010;
...

anzulegen. Es wird dann das erste Zeichen des eingegebenen string 
aufgerufen, an die "vergleichs tabellen" funktion übergeben und als 
Rückgabewert erhalte ich dann den decodierten code, den ich in das 
display schreiben will.
Somit erspare ich mir, bei einem großen Programm ständig die Zeichen von 
Hand zu programmieren und kann einzeichen direkt im Programm 
nachschlagen und schreiben.
Der rest ist für mich machbar, wichtig ist erstmal nur einen character 
des eingegebenen string als rückgabewert mit dem dahinter abgelegten 
code zu erhalten.

Da ich noch Anfänger bin und wahrscheinlich nicht sehr effektiv 
programmiere, würde ich mir gerne tipps und anregungen holen um 
effizienten und stil gerechten Code zu erzeugen.

Denkt ihr, das eine solche idee gut ist oder eher mies?

Dankschön.

von Falk B. (falk)


Lesenswert?

@ Oliver D. (highspeed-oliver)

>Nun dachte ich mir, eine Tabelle in form eines arrays oder eines:
>int a=01100001; //Standard ASCI und Hitachi HD44780 belegung
>int b=01100010;

Qaurk. Du musst ASCII nicht neu erfinden. Das kennen sowohl der Compiler 
als auch dein Display bereits. Da kannst du ganz einfach und direkt mit 
Strings in C hantieren.

>Der rest ist für mich machbar, wichtig ist erstmal nur einen character
>des eingegebenen string als rückgabewert mit dem dahinter abgelegten
>code zu erhalten.

Ist doch schon ASCII !

>Denkt ihr, das eine solche idee gut ist oder eher mies?

Mies.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#LCD-Ansteuerung

MFG
Falk

von Severino R. (severino)


Lesenswert?

Hallo Oliver

Achtung: in einem text[9] haben nur 9 chars Platz, die Du über 
text[0]..text[8] ansprechen kannst.

Aber wenn ich Dich richtig verstanden habe, machst Du es Dir wirklich 
viel zu kompliziert. Denn 'a' hat den Wert 0x61, also binär 01100001, 
d.h. wenn Du 'a' ans Display sendest, sendest Du in Wirklichkeit 
01100001.

Schon erledigt!

von Karl H. (kbuchegg)


Lesenswert?

Oliver D. wrote:
> Hallo Leute,
>
> nachdem mein Display nun Prima läuft bin ich gerade dabei mit meinen C
> Kenntnissen eine Funktion oder mehrere zu schreiben, die mir einen
> eingegebenen String auf meinem LCD anzeigt.

Mach bitte nicht den Fehler, dass alle hier noch wissen bei welchem
Problem sie dir vor 3 Tagen geholfen haben. Die regulären Poster
lesen jeden Tage hunderte Fragen und versuchen sie so gut es geht
zu beantworten.

>
> Nun dachte ich mir, eine Tabelle in form eines arrays oder eines:
> int a=01100001; //Standard ASCI und Hitachi HD44780 belegung
> int b=01100010;
> ...
>
> anzulegen. Es wird dann das erste Zeichen des eingegebenen string
> aufgerufen, an die "vergleichs tabellen" funktion übergeben und als
> Rückgabewert erhalte ich dann den decodierten code, den ich in das
> display schreiben will.

OK. Das klingt als ob du nach einer Zeichensatz Tabelle suchst.
Aber wenn du ein HD44780 kompatibles Display hast, brauchst
du keine. Das Display weiß selber, wie es ein Zeichen anzuzeigen
hat. Du brauchst ihm nur den ASCII Code des Zeichens zu schicken.
Den ASCII Code hast du aber schon: genau mit diesem Code ist
ein Zeichen in deinem C-Programm gespeichert.

Oder verstehe ich dich völlig falsch.
Hat das irgendwas mit den, auf diesem Display möglichen,
8 selbstdefinierbaren Zeichen zu tun?


(absichtlich etwas umständlich programmiert)
1
void lcd_puts( const char text[] )
2
{
3
  int i;
4
5
  while( text[i] != '\0' ) {
6
    lcd_data( text[i] ); // oder wie auch immer deine
7
                         // Ausgabefunktion für ein einzelnes
8
                         // Zeichen heist
9
    i++;
10
  }
11
}

Diese Funktion gibt einen String aus. Dabei stützt sie sich
auf eine weitere Funktion, die in der Lage sein muss, ein
einzelnes Zeichen auszugeben. Diese Funktion muesstest du
ja bereits haben.

Verwendet wird das dann so
1
int main()
2
{
3
  const char* Text1 = "Erster Text";
4
  char Text2[] = "Zweiter Text";
5
6
  lcd_puts( Text1 );
7
  lcd_puts( Text2 );
8
  lcd_puts( "Dritter Text" );
9
}

von Oliver D. (highspeed-oliver)


Lesenswert?

Hallo,

achso, also wenn ich z.B. ein a sende, wird es automatisch in einen int 
umgewandelt bzw. über die asci tabelle umgewandelt?

Das ist ja äußerst praktisch...so brauche ich das "rad " nicht neu 
erfinden...

Gut, dann werde ich das ganze mal ohne die tabelle machen.

Wie schreibe ich das dann in c?

mein übergabewert, also buchstabe umwandeln in ein asci.

int uebergabe;
char ausgabe

uebergabe=ausgabe;

Wird dabei dann automatisch in ein asci umgewandelt?

von Oliver D. (highspeed-oliver)


Lesenswert?

Mit den selbstdefinierbaren zeichen hat es nichts zu tun...
Ich wusste halt einfach nicht, dass man einfach aus einem buchstaben "a" 
umwandeln kann ich asci, was das ganze natürlich ungemein verinfacht.

von Oliver D. (highspeed-oliver)


Lesenswert?

So, ich bin jetzt einfach mal hingegangen und habe gesagt
Als uebergabe bekommt meine funktion ein "a".
rueckgabe ist ein int.

rueckgabe = uebergabe;

Ich erhalte dann in DEV c++ eine 97 dez , was 61 hex ist.
In Binär ist das aber 1100 0001.
Das entspricht aber nicht dem Datenblatt des Hitachi.
Ein "a" sieht dort so aus: 0110 0001

Die Umwandlung klappt also, aber dummerweise ist das nicht konform zu 
meinem display :(

von Oliver D. (highspeed-oliver)


Lesenswert?

Ach habe den Fehler gefunden...
Der Blöde windows taschenrechner...
Klar, es fehlt natürlich die 0 am anfang, weil ich nicht einstellen 
kann, dass ich ein 1 byte breites register habe.

Alles klar.

Dann weiß ich ja nun bescheid :)

Jetzt muss ich nurnoch high und low nibble voneinander trennen und 
schreiben.
Das werde ich mal versuchen bevor ich frage.

von Karl H. (kbuchegg)


Lesenswert?

Oliver D. wrote:

> achso, also wenn ich z.B. ein a sende, wird es automatisch in einen int
> umgewandelt bzw. über die asci tabelle umgewandelt?

Ein 'a' ist in C eine Zahl.
Ob du

  char c = 'a';
  char c = 97;
  char c = 0x61;

schreibst, ist Jacke wie Hose. Es ist alles dasselbe:
Der Variablen c wird das Bitmuster 01100001 zugewiesen.

> Ich erhalte dann in DEV c++ eine 97 dez , was 61 hex ist.
> In Binär ist das aber 1100 0001.

Du hast dich verzählt :-)
0x61 ist binär 0110 0001

> Die Umwandlung klappt also, aber dummerweise ist das nicht konform zu
> meinem display :(

Doch. Ist es.
Hinweis: Die Standard ASCII Zeichen, also alle Buchstaben von
A bis Z, von a bis z, die Sonderzeichen wie . , ; : - + * # etc.
die Ziffern 0 bis 9 sind im ASCII Code allesammt kleiner als
128, haben also niemals das höchstwertige Bit gesetzt. Erst mit
solchen Krüppeln wie ü Ü ä Ä ö Ö ß (also alles was im Lateinischen
Alphabet in irgendeiner Form sprachspezifisch ist) kommt man mit
dem regulären ASCII 7-Bit nicht mehr aus und mann muss die Zeichen
mit einem Code größer als 128 zu hilfe nehmen wodurch das linkste
Bit gesetzt wird.

von Karl H. (kbuchegg)


Lesenswert?

Oliver D. wrote:
> Ach habe den Fehler gefunden...
> Der Blöde windows taschenrechner...

Hex Zahlen nach binär zu übertragen ist einfach.
Eigentlich liegt die Begründung für die Beliebtheit
von Hex Zahlen in der Programmierung nur in dieser
einfachen Umsetzbarkeit zu binär bei gleichzeitiger
Kompaktheit in der Schreibweise.

Die Trennung in High Nibble und Low Nibble ist ja
noch leicht. Jeder Buchstabe ist ein Nibble.

Und für jeden Nibble gilt:

   0      0000
   1      0001
   2      0010
   3      0011
   4      0100
   5      0101
   6      0110
   7      0111
   8      1000
   9      1001
  10 = A  1010
  11 = B  1011
  12 = C  1100
  13 = D  1101
  14 = E  1110
  15 = F  1111

Da fallen einem ein paar Besonderheiten sofort auf:
* Die binär letzte Stelle ist abwechselnd immer 0 und 1.
  Daraus folgt sofort, dass alle ungeraden Zahlen hinten
  immer eine 1 haben
* Die 2-er Potenzen 1, 2, 4, 8  kann man schnell auswendig.
  das ist jeweils eine einzelne 1 und ansonsten lauter Nuller.
* 7 und F sind auch leicht zu merken: F sind alle Stellen auf 1
  und für 7 als Vorgänger von 8 ( = 1000) hat eine 0 am Anfang
  und danach lauter 1.
* A (also dezimal 10) ist binär 1010 (also 2 mal die 10 hintereinander)
* alles was größer 8 ist, hat an vorderster Stelle schon mal eine 1
* den Rest kann man dann ganz schnell simultan an den Fingern und
  im Kopf nachzählen.

von Falk B. (falk)


Lesenswert?

GRUNDLAGEN IM C-BUCH NACHSCHLAGEN!

von Oliver D. (highspeed-oliver)


Lesenswert?

Hmm, also sowas steht nicht in den Grundlagen meines C buches...

Ehm, das mit dem HIGH LOW nibble swap und den hex zahlen ist eine gute 
idee.
Es sind zwei zeichen für high und low doch weiß ich nicht, wie ich das 
schreiben soll.

angenommen ich sage,
wert='a';

wobei a mein character ist und wert ein int.
Dann bekomme ich eine schöne Binäre kombi in meine 8 bit geschrieben.
Aber wie kriege ich das dann getauscht?

Von sowas steht in meinem C buch garnix.

von Oliver D. (highspeed-oliver)


Lesenswert?

Oder könnte ich einfach für das high nibble einen rechtsshift machen?

von Karl H. (kbuchegg)


Lesenswert?

Oliver D. wrote:
> Hmm, also sowas steht nicht in den Grundlagen meines C buches...
>
> Ehm, das mit dem HIGH LOW nibble swap und den hex zahlen ist eine gute
> idee.
> Es sind zwei zeichen für high und low doch weiß ich nicht, wie ich das
> schreiben soll.
>
> angenommen ich sage,
> wert='a';
>
> wobei a mein character ist und wert ein int.

Vergiss ganz schnell die int.
Du brauchst keine int.
Du arbeitest mit Bytes. Und der Datentyp für
Bytes in C ist der char (*). Noch besser ist ein unsigned
char. Oder aber gleich die neue Schreibweise

uint8_t

> Dann bekomme ich eine schöne Binäre kombi in meine 8 bit geschrieben.
> Aber wie kriege ich das dann getauscht?

In C willst du das nicht wirklich tauschen. Wozu auch.
Alles was du brauchst ist das High Nibble und das Low Nibble
getrennt.

  uint8_t c = 0x61;

  uint8_t Low  = c & 0x0F;
  uint8_t High = ( c >> 4 ) & 0x0F;


Edit: (*)
Das klingt am Anfang überraschend. Aber auch ein char ist einfach
nur eine Variable die Zahlen speichert. Der einzige Unterschied,
neben der Anzahl der Bits, zwischen int und char besteht darin,
dass char bei einer Ein/Ausgabe auf ein Standard-Gerät mit
den Standard Ein/Ausgabefunktionen anders behandelt wird.
Während von einem int vor der Ausgabe eine textuelle Repräsentierung
der Zahl erzeugt wird, unterbeleibt dies bei einem char. Der Inhalt
einer char Variablen (der Zahlenwert) wird so wie er ist binär
an das Gerät geschickt.
Das ist schon alles. In C ist ein char, ein unsigned char,
ein signed char, nichts anderes als Variablen für kleine Zahlen
mit einer Sonderbehandlung bei Standard I/O.

von Oliver D. (highspeed-oliver)


Lesenswert?

Alles klar, danke für den Tipp mit den chars... und der neuen 
Schreibweise.

Das mit dem high nibble ins low nibble schreiben und dem shift operator 
hatte ich mir ebenfalls so gedacht. Das mit dem low nibble ist ne prima 
lösung.

Danke

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.