Forum: Mikrocontroller und Digitale Elektronik Font erstellen und ansprechen in C


von reflection (Gast)


Lesenswert?

Hallo zusammen

Ich habe mir eine 8x8 Matrix gebaut die nun auch Buchstaben ausgeben 
soll.

Soweit so gut :o) Ich habe mir die Fonts mal in einem .txt File 
"gezeichnet"

...##...
..###...
...##...
...##...
...##...
...##...
.######.
........

Ich muss, damit die Matrix korrekt funktioniert das Ganze Zeilenweise 
schicken. Gut, dann wäre das dann z.B. 0x18, 0x38, 0x18 .......

So, angenommen ich fülle das alles in ein Array, also z.B alle 
Grossbuchstaben, wie kann ich das dann ansprechen? Muss ich da manuell 
immer in diesem Array suchen, oder gibt es da eine schönere Möglichkeit. 
Meine, da sind dann weiss nicht wieviele solcher Hex Buchstaben drin. 
Klar, ich weiss wieviele Hex Werte ich senden muss um einen Buchstaben 
darzustellen, aber muss ich da wirklich immer quer durchs ganze Array 
suchen um z.B. das A zu finden?

Das Beste wäre natürlich wenn ich im Tool nachher sowas schreiben könnte 
wie: sendDate('A'); und auf der Matrix würde ein A angezeigt. Nur wie 
setzt man das um?
Bin schon weiss nicht wie lange am überlegen, aber irgendwie komm ich 
auf keinen grünen Zweig. Vielleicht habt ihr ja ne Blitzidee wie man das 
umsetzen könnte.

Gruss reflection

von Michael Wilhelm (Gast)


Lesenswert?

Wie wäre es, wenn du ein Array machst für die Großbuchstaben und dann 
vom ASCII-Wert 65 (dezimal) abziehst.

MW

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das Array durchsuchen musst Du ja nicht. Jedes Zeichen ist exakt 
gleich hoch, und so kannst Du aus dem Zeichencode die Position in der 
Tabelle ausrechnen.
Also:

   Pointer = Zeichencode * Anzahl_Bytes_Pro_Zeichen.

Wenn Du nicht den vollständigen ANSI/ASCII-Zeichensatz abbildest, kannst 
Du Speicherplatz sparen, indem Du unbenutzte Zeichenpositionen am Anfang 
weglässt, für die Berechnung heißt das dann

   Pointer = (Zeichencode - Ausgelassene_Zeichen) * 
Anzahl_Bytes_Pro_Zeichen;

Alternativ kannst Du auch mit einer zweiten Tabelle arbeiten, die für 
jedes Zeichen den Startindex in der Bitmap-Tabelle enthält, aber das hat 
natürlich nur einen Sinn, wenn die Zeichen unterschiedlich groß sind.

von Udo (Gast)


Lesenswert?

reflection wrote:
>> Ich muss, damit die Matrix korrekt funktioniert das Ganze Zeilenweise
>> schicken.

Wie ich aus deinen anderen Threads noch weis, benutz du den MAX7221.
Wie kommst du darauf, das du die Zeichen Zeilenweise schicken musst?

Die Adressierung der Matrix des MAX7221 ist Spaltenorientiert 
ausgelegt....

Gruß
Udo

von Gerd B. (silicat) Benutzerseite


Lesenswert?

1
unsigned char font[8][256]={ //Array mit 256Zeichen, jedes Zeichen 8 Bytes
2
{0x18, 0x38, 0x18,0x18,0x18,0x18,0x7E,0x00},
3
{0x18, 0x38, 0x18,0x18,0x18,0x18,0x7E,0x00},
4
{0x18, 0x38, 0x18,0x18,0x18,0x18,0x7E,0x00},
5
....
6
}
7
8
void sendDate(char c)
9
{
10
int i;
11
  for (i=0;i<8;i++)
12
    sendeByte(font[i][c]); // bzw [c-KONSTANTE], falls die Fonts nicht bei ASCII 0 beginnen
13
}

(habs aber nicht ausprobiert, ich hoffe die Reihenfolge der 
Array-Dimension passt)

Gruß, siliCAT

von reflection (Gast)


Lesenswert?

@Udo

Yup genau um den MAX7221 geht es. Ich kann ja jede, laut Datenblatt ROW 
direkt ansprechen, die Column aber nicht. Wenn ich also in der ersten 
ROW den Wert FF reinschreibe und die Matrix vor mir liegen habe, 
leuchtet die ganze erste Zeile (ROW) Darum nahm ich an ich muss es 
Reihenweise schicken (von oben nach unten) Habe das auch mit einem 
Buchstaben getestet und das funzt super. Eigentlich kommts ja nur drauf 
an wie die Matrix vor einem liegt. Lasse mich aber gerne eines anderen 
belehren. Um eine '1' darzustellen kann ich folgenden Code nehmen und 
das geht.

SetRow(0x00, 0x18);
SetRow(0x01, 0x38);
SetRow(0x02, 0x18);
SetRow(0x03, 0x18);
SetRow(0x04, 0x18);
SetRow(0x05, 0x18);
SetRow(0x06, 0x7E);
SetRow(0x07, 0x00);

Vieleicht meinen wir auch beide dasselbe :o)

Gruss und merci für die Tipps

reflection

von Udo (Gast)


Lesenswert?

reflection wrote:

>> Eigentlich kommts ja nur drauf
>> an wie die Matrix vor einem liegt.

Klar, kann ich die 8x8 Matrix drehen und dann sagen, Spalte ist jetzt 
Zeile....insofern muss ich mich korrigieren, der 7221 ist nicht 
Spaltenorientiert sondern Digitorientiert zu adressieren.

reflection wrote:

>> SetRow(0x00, 0x18);

wenn du als Adresse 0x00 und dann als Data 0xXX sendest, dann passiert 
gar nichts, denn mit 0x00 als Adresse hast du das No-Op Register 
angesprochen und der Datenwert wird im Schieberegister des 7221 nur ein 
Byte weitergeschoben (wenn du nur einen 7221 hast, ist der Datenwert 
über Dout komplett aus dem Schieberegister rausgeschoben)

Um die einzelnen Digits anzusprechen, musst du als Adressen die Werte 
0x01 bis 0x08 nehmen.

Gruß
Udo

von Udo S. (udo)


Angehängte Dateien:

Lesenswert?

ich habe mal ne Zeichentabelle- und nen Laufschrift-Code angehangen. Der 
Code war für einen ATmega32, musst du ggf. auf deinen Controller 
anpassen.

Gruß
Udo

von refkection (Gast)


Lesenswert?

Hallo Udo

Vielen Dank, werde ich mir gerne mal ansehen! Hast natürlich recht, ich 
hatte das auch mit 0x01 im Code, aber den hatte ich gerade nicht zur 
Hand und habe es aus dem Kopf schnell reingeschrieben, darum der blöde 
Fehler.

Danke nochmals für die hilfreichen Tipps. Werde es zuerst mal selber 
probieren und wenn ich nicht weiterkomme Deinen Code zu rate ziehen

Allen ein schönes Wochenende

Greets

reflection

von reflection (Gast)


Lesenswert?

Salu zusammen

So, der Font steht. Nun habe ich aber noch ein kleines Prob:

Ich möchte ja den Font im Flash und nicht im RAM ablegen. Dachte daher 
ich definiere das Teil im Header File mittels

#definde char font[128][8]= {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00}, // Char Space
                  {0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x00}, // 
Char !
                  {0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00}, // 
Char "
...
}

Nun frisst das aber mein Compiler nicht (MSP430 und mspgcc) Bringt 
einfach eine Fehlermeldung. Kann ich das so nicht definieren? Die 
Fehlermeldung sagt leider nicht sehr viel aus, nur dass ein Fehler in 
der Definiton vorliegt.

Hoffe mir kann einer helfen.

Habe es im Moment einfach im .c File definiert.

char font[128][8]= {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00...

und das funktiioniert. So schreibt er mir aber das doch ins RAM oder 
sehe ich das völlig falsch?

Gruss reflection

von Udo S. (udo)


Lesenswert?

Hallo reflection,

hast du dir meine Zeichensatztabelle mal angeschaut? Ich hatte das 
gleiche Problem und es mit PROGMEM gelöst.
1
#include <avr/pgmspace.h>
2
3
unsigned char PROGMEM ch_32[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};  // Code for char Space 
4
unsigned char PROGMEM ch_33[8] = {0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x00};  // Code for char !
5
unsigned char PROGMEM ch_34[8] = {0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00};  // Code for char "

Ich weis jetzt nicht ob dein Compiler die PROGMEM-Funktion kennt.

PROGMEM bewirkt, dass der Code zur Laufzeit im Programmspeicher bleibt 
und nur der Teil der aktuell benötigt wird, ins RAM kopiert wird.

Gruß
Udo

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

So ein Konstrukt wie PROGMEM braucht man auf dem MSP430 glücklicherweise 
nicht. Das ist eine von-Neumann-Maschine und daher viel 
unproblematischer in C zu programmieren.

Variablen, die als const deklariert sind, landen beim MSP430 
automatisch im Flash-ROM, um mehr muss man sich nicht kümmern.

Wenn man sicher sein will, einfach mal im Map-File die Adresse der 
Variablen nachsehen und im Datenblatt nachsehen, wo RAM und wo Flash-ROM 
liegt.

von Udo S. (udo)


Lesenswert?

Das ist natürlich super einfach. Sorry, wie gesagt, MSP kenn ich nicht.

Gruß
Udo

von reflection (Gast)


Lesenswert?

Hey Jungs

Vielen Dank für die Hilfe, werde ich heute gleich mal probieren!

@Rufus

Ich habe noch ein anderes "Problem" oder besser gesagt, ich habe einfach 
keinen Plan wie ich das angehen soll.

Geht immer noch um den 3D Cube

Schlussendlich möchte ich auf dem PC ein GUI haben mit welchem ich die 
Muster erzeugen kann. Programmierung des GUI ist kein Problem (eine 
Kollegin von mir ist ein JAVA Crack :o)
So, dann trudeln die Daten irgendwie über die serielle Schnittstelle zum 
MSP (als File oder wie auch immer).
Ich sehe das Problem nicht darin, dass ich die Muster anzeigen kann, 
aber abspeichern und bei einem Neustart des Cube (ohne PC Anbindung) 
wieder ablaufen lassen.

Fragen die sich mir stellen:

1. Wo müssen die Daten hin? --> Flash? Wie macht man das?
2. Wie spreche ich die Daten bei einem Start des MSP an?
3. Wie speichere ich die Muster ab, kann ich von diesen übermittelten 
Daten auf Funktionen zugreiffen die sich bereits in meinem Programm (im 
MSP) befinden? Also z.B. Delay Funktion
4. In welchem Format müssen die Daten an den MSP übertragen werden? Habe 
ja keinen externen compiler, oder übertrage ich da gleich die Hex Werte 
mit denen ich den Cube steuere (MAX7221)

Sorry für die wahrscheinlich dummen Fragen, aber mit so etwas musste ich 
mich halt bis Dato nie beschäftigen.

Für eine allfällige Hilfe wäre ich sehr dankbar

Gruss aus der Schweiz

reflection

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.