Forum: Mikrocontroller und Digitale Elektronik LED-Display Buchstaben und Wörter


von SuperGrobi (Gast)


Lesenswert?

Hallo,

ich hab mich da etwas in einem Programm verrannt und komme jetzt leider
nicht mehr weiter. Ich hoffe Ihr könnt mir bei meinem Problem helfen.
Also forlgendes.

Ich möchte mit C ein LED Punktmatrixdisplay ansteuern und habe mir
dafür eine Routine geschrieben, mit der ich einzelne Buchstaben an das
Display schicken kann. Die Buchstaben werden seriell in das Display
geschoben, insgesamt 16 Zeichen a 5*7 Punkte. Die Buchstaben habe ich
als "const" abgelegt also z.B.:

const int A_map[5] = { 62,5,5,5,62};
const int B_map[5] = { 63,37,37,37,26};
...usw.

Ich muss jetzt für jeden Buchstaben meine Routine "Display" aufrufen:


  for (i=0;i<5;i++)
    {Display(D_map[i]);}

...die dann die Daten in das Display schiebt.

soweit ist alles ok und funktioniert auch einwandfrei. Jetzt wird es
aber mühselig und nicht gerade platzsparend, wenn ich komplette Wörter
reinschieben will. Ich müsste also für das Wort "hallo" 5 mal diese
Routine mit der entsprechenden for-schleife aufrufen.

Ich hatte mir dann überlegt, das ich mir noch Konstanten mit ganzen
Wörtern anlege. Also z.B.

const char hallo[5] {h_map,a_map,l_map,l_map,o_map};

...und diese dann mit einer Schleife an die Display Routine schicke.
Da streikt jedoch der Compiler. Ihr seht also ich gehöre noch zu den
Anfängern.

Ich möchte narürlich jetzt keine fertige lösung von Euch haben, würde
mich jedoch freuen, wenn Ihr mir einen Weg zeigen könntet, wie ich das
machen kann.
Vielen Dank schon mal...

hier noch die "Display"-Routine:
1
void Display(int Schieb)
2
{
3
  unsigned int s,b;
4
        {c = Schieb[d];
5
        P3OUT |= 0x02;                  // Display Dunkel schalten
6
        P2OUT = 0x03;                   // CE und CLK Ein, RS Aus
7
        P2OUT &= 0xFD;                  // CE Aus
8
  P2OUT &= 0xFE;      // Taktausgang auf 0
9
        
10
  for(s=0;s<=6;s++)           // Für 8 Bit (kann beliebig erweitert
11
werden)
12
  {b = Schieb&128;          // Abfrage des Bit 0
13
   if (b==128)      // Ist Bit0 = 1
14
      P3OUT |= 0x01;    // ... dann setze Datenausgang auf 1
15
   P2OUT |= 0x01;      // Taktausgang auf 1
16
   Schieb<<=1;            // gesamtes Byte um 1 Bit nach links schieben
17
   P3OUT &= 0xFE;      // Datenausgang auf 0 zurücksetzen
18
   P2OUT &= 0xFE;                 // Taktausgang auf 0 zurücksetzen
19
   }
20
  b = Schieb&128;          // Abfrage des Bit 0
21
  if (b==128)      // Ist Bit0 = 1
22
      P3OUT |= 0x01;    // ... dann setze Datenausgang auf 1
23
  P2OUT |= 0x01;      // Taktausgang auf 1
24
  P2OUT |= 0x02;      // CE auf 1 zurücksetzen
25
  P3OUT &= 0xFE;      // Datenausgang auf 0 zurücksetzen
26
  P2OUT &= 0xFE;      // Taktausgang auf 0
27
        P2OUT &= 0xFB;      // RS ausgang auf 0 zurücksetzen
28
        P3OUT &= 0xFD;                  // Display hell schalten
29
        }

Gruß
Thomas

von SuperGrobi (Gast)


Lesenswert?

schaut hier niemand rein oder gibt es dafür wirklich keine Lösung ?

gruß
thomas

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

@SuperGrobi

erster Beitrag
Datum: 09.09.2005 18:47 [Freitag]

Nachfrage
Datum: 10.09.2005 07:53 [Samstag]


Erwartest du ernsthaft, daß hier "zig" Leute vor dem Bildschirm
hocken, und nur darauf warten, daß du einen Beitrag einstellst, um dir
dann schnellstmöglich zu antworten? Wahrscheinlich machst du das selbst
ja auch nicht (außer wenn du persönlich ein dringendes Anliegen hast,
und deinen eigenen Beitrag in 10-Minuten-Abstand auf Antworten
überprüfst) ..

Also gib dem Rest der Menschheit noch ein paar Tage, um über deine
Frage nachzudenken ...

von Thomas K. (thkais)


Lesenswert?

Ich hätte es etwas anders gemacht, z.B. so:

const charmap [Gesamtanzahl_Bytes] = {
62,5,5,5,62,
63,37,37,37,26,
(codes für c),
(codes für d),
etc.
}

Da jeder Buchstabe 5 Zeichen hat, kannst Du den Index ganz einfach
ausrechnen: Zeichen_nr * 5.
Also:
Basis = Zeichen_nr * 5
Und dann per Schleife x = 0..4 den Index [Basis + x] benutzen.

Andere Möglichkeit: Ein zweidimensionales Array.

const charmap [Anzahl Buchstaben][5] = {
{62,5,5,5,62},
{63,37,37,37,26},
etc.
}

Dann kannst Du mit charmap[Zeichen_nr][x] mit x = 0..4 die
entsprechenden Daten aus dem Array lesen.

von Christian Büch (Gast)


Lesenswert?

Hi,

mach dir ein Mehrdimensionales Array wo der Index eines Buchstaben
gleich mit dem ASCII "Wert" zu bestimmen ist. Damit hast du es
leichter ...

code char Font3[]= {
0x00,0x00,0x00, /* Espace  0x20 */      // 0
0x00,0x5C,0x00, /* ! */                   // 1
0x0C,0x00,0x0C, /* " */                   // 2
0x7C,0x28,0x7C, /* # */                     // 3
0x7C,0x44,0x7C, /* 0x */                    // 4
0x24,0x10,0x48, /* % */                     // 5
0x28,0x54,0x08, /* & */                     // 6
0x00,0x0C,0x00, /* ' */                     // 7
0x38,0x44,0x00, /* ( */                     // 8
0x44,0x38,0x00, /* ) */                     // 9
0x20,0x10,0x08, /* // */                    // 10
0x10,0x38,0x10, /* + */                     // 11
0x80,0x40,0x00, /* , */                     // 12
0x10,0x10,0x10, /* - */                     // 13
0x00,0x40,0x00, /* . */                     // 14
0x20,0x10,0x08, /* / */              // 15
0x38,0x44,0x38, /* 0  0x30 */             // 16
0x00,0x7C,0x00, /* 1 */                     // 17
0x64,0x54,0x48, /* 2 */                     // 18
0x44,0x54,0x28, /* 3 */                     // 19
0x1C,0x10,0x7C, /* 4 */                     // 20
0x4C,0x54,0x24, /* 5 */                     // 21
0x38,0x54,0x20, /* 6 22*/
0x04,0x74,0x0C, /* 7 23*/
0x28,0x54,0x28, /* 8 24*/
0x08,0x54,0x38, /* 9 25*/
0x00,0x50,0x00, /* : 26*/
0x80,0x50,0x00, /* ; 27*/
0x10,0x28,0x44, /* < 28*/


Mit ein paar weiteren Funktionen kann ich nun mit einer Funktion

LcdPrint("Hallo")

Strings auf dem Display ausgeben. Ist zwar was arbeit, aber letztlich
lohnt es sich !

von Togger (Gast)


Lesenswert?

Hi Grobi,
ich entwickle im mom auch ein LED Display.
Die Ansteureung funktioniert ähnlich wie bei dir.
Um Texte auszugeben verwende ich Arrays mit 10 Strings, sollen aber
noch mehr werden.
Ein String kann 40 Zeichen lang werden.
Die Ansteuerung der Punktmatrix erfolgt in einer
Timerinterruptroutine.
Es werden z.b. 10 Zeichen ausgegeben.
Ist der String länger, muß solange nach rechts gescrollt werden, bis
der String vollständig erschienen ist.
Dann kommt der nächste.
Die einzelnen Zeichen habe ich in einem Array im EEProm abgelegt, so
wie im letzten Beitrag von Christian.
Das Ding soll ein Terminkalender werden, der so nebenbei noch Außen und
Innentemperatur anzeigt und natürlich Datum und Uhrzeit (DCF).
Die Termine werden per PC eingegeben.
Jetzt fehlt mir nur noch ein bischen Sound ;-)
Ist ne Menge Arbeit.
Axo: die Stringscrollroutinen habe ich in Assembler geschrieben, weil
so spare ich Speicherplatz und ich weiss auch nicht, ob die sonst in
Basic schnell genug gewesen wären.

Hoffe, dir ist die Stringausgabe etwas klarer geworden.

lg Ralf

von SuperGrobi (Gast)


Lesenswert?

Hallo,

also erst mal vielen Dank für die Tips. Ich werd das dann mal mit den
verschiedenen Vorschlägen ausprobieren. Erst mal mit dem
zweidimensionalen Array (wusste gar nicht, das das geht :). Mit dem
Chars im Eprom speichern ist natürlich auch nicht schlecht, jedoch hab
ich die Platine leider schon fertig geätzt und zusammengebaut. Soll nen
Wecker mit Dimmerfunktion werden, also wenn Aufsteh-Zeit ist, soll das
Licht langsam angehen. Dafür hatte ich mir bei Ebay ein paar HCMS 2923
ersteigert mit 2*8 Zeichen. Man glaubt es kaum, aber die LED Display
verbrauchen ja weniger Strom als so ein sch*iß LCD Display.

Als µC verwende ich einen MSP430 F1232. Der hat 8kB Speicher. Mit
meinen "relativ" einfachen Routinen bin ich da jetzt schon bei 3,5
kB. Und ich hab erst 4 Wörter die Uhrzeit und den Dimmer programmiert.
Ein Menü wollte ich da noch reinbringen. Wenn ich das dann da mal so
vorrausschauend hochschätze wird mir langsam der Speicher knapp. Darum
versucher ich auch erst mal drum herum zu kommen, die komplette ASCII
Tabelle da reinzuflashen. Das ist ja dann fast 1,5 kB.

Aber mal sehen, vielleicht spare ich ja dann doch dafür mehr Code.
Ich werd mich dann demnächst noch mal melden, was draus geworden ist.

Gruß
Thomas

von SuperGrobi (Gast)


Lesenswert?

So, also ich hab es jetzt wie vorgeschlagen als einziges Array
definiert. Also mit:

const char charmap[320] = {
62,81,73,69,62,         // 0
0,65,127,64,0,          // 1
... usw.

Das hat dann auch noch den Vorteil, da ich die Zahlen 0-9 direkt an
erster Stelle gesetzt habe, daß ich diese ohne große Umwandlungsroutine
direkt benutzen kann, also mit der Routine
Display(0); wird dann auch eine "0" dargestellt usw.

Vielen Dank nochmal an alle, die geholfen haben.

gruß
Thomas

von Daniel W. (daniel2008)


Lesenswert?

Hmm, wieso eine 0 als 0 übergeben? Die Textausgaberoutine soll Text
ausgeben, also 0 als "0" engegennehmen (also vom Typ char[])
Die gesamte ASCII-Tabelle braucht man auch nicht, nur die benötigten
Zeichen als Bitmuster.
Da holt man sich dann passend zum aus dem der Textroutine übergebenem
String ausgelesenen Zeichen einfach das passende Bitmuster raus.
Um die Helligkeit konstant zu halten und ggf. Schatten zu verhindern,
empfielht es sich, das Timing kosntant zu halten. Ich habe das (als mir
selbst gestellte Zusatzaufgabe im Rahmen eines Praktikums, in dem
eigentlich nur das Spiel "Pong" zu programmieren war) so gelöst, dass
ich ein Array als "Framebuffer" genutzt habe, das dann immer komplett
ins Display kopiert wird.

Ob mit oder ohne Interruptnutzung ist eigentlich nicht so wichtig, ohne
Interrupts dürfte es aber gerade als Anfänger einfacher sein (z.B. gibt
es so nette Scherze, dass static-Variablen innerhalb einer ISR zu
völlig unverhersehbaren Programmabläufen führen (und daher nicht
nutzbar sind, zumindest nicht mit CodeVision AVR) oder dass globale
Variablen, die in der ISR und dem Hauptprogramm genutzt werden als
"volatile" deklariert sein müssen.

Auch kann es u.U. "haarig" werden, wenn während eine ISR abläuft, ein
weiterer Interrupt auftritt.

Totaler Blödsinn ist natürlich, komplette Texte als fertige Bitmuster
bereits im Speicher abzulegen, die gängigen Controller haben MIPS im
Überfluß, aber beim Flash-ROM haben die Hersteller doch meist sehr
gegeizt.

Aber das wird sicher in 2 bis 4 Jahren auch erledigt sein, wenn man
sich mal den Preis für einen 128 MB-USB-Stick anguckt, dann weiß man,
dass 1 MegaBYTE nichtmal einen Dollar kosten können, Controller mit
128kB dürften also über kurz oder lang der Standard werden. Geben tut
es die ja schon längst, aber das sind dann derzeit noch die teuren
Varianten.

Vor 5 bis 10 Jahren hatten die günstigen Varianten ja gerademal so um
die 256 Byte... [z.B. das Ding, was in der C-Control von der blauen
Apotheke steckt, dort wurde dann externer Speicher per I2C angebunden,
mann, bin ich froh das lahme Ding (ca. 100 -interpretierte-
BASIC-Befehle/Sek.) nicht mehr im gruseligen, mit beknackten
Beschränkungen verseuchtem BASIC programmieren zu müssen!].
Allerdings ist es zugegebenermaßen sehr einsteigerfreundlich, aber
eignet sich aus Kostengründen leider wirklich nur, wenn man nur ein
einziges Projekt realisieren will.

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.