Guten Morgen, habe hier gesucht, bin leider nur nicht fündig geworden. Hat jemand schon fertige GLCD Fonts? Alles ab 6x8? Würde gerne mal ausprobieren wie andere Zeichen auf dem GLCD aussehen. Danke im vorraus!
Habe gerade was passen könnte gefunden. Mir kommen noch ein paar Verständnissfragen auf.. https://github.com/johnmccombs/arduino-libraries/blob/master/glcd/fonts/fixednums7x15.h In der Headerdatei steht, dass die Zeichen "7x15" groß sind. Als beispiel die '0'
1 | // char '0'
|
2 | 0xfc, 0xfe, 0x03, 0xe1, 0x1b, 0xfe, 0xfc, |
3 | 0x0f, 0x1f, 0x36, 0x21, 0x30, 0x1f, 0x0f, |
Habe mir die Funkionen geschrieben die mir die Daten zum Display schicken. Wenn ich das "Array für die '0'" jetzt übertragen würde, würde ja nur Müll im Display angezeigt werden.. Wie müssten die "for" Schleifen jetzt aussehen?
1 | glcdClear(); |
2 | while(1) |
3 | {
|
4 | uint8_t i = 0; |
5 | glcdGotoXY(2,0); |
6 | for (; i < 7 ; i++) |
7 | {
|
8 | glcdSendData(newArray[i]); |
9 | }
|
10 | glcdGotoXY(3,0); |
11 | for (; i < 14 ; i++) |
12 | {
|
13 | glcdSendData(newArray[i]); |
14 | }
|
15 | }
|
:
Bearbeitet durch User
Hi >Wenn ich das "Array für die '0'" jetzt übertragen würde, würde ja nur >Müll im Display angezeigt werden.. Nö, das passt schon. Gilt aber nur für Displays mit senkrechter Byteausrichtung und für eine 0 mit Schrägstrich. MfG Spess
Okay. Wie kommt man am besten auf den Anfang der Zahl?
1 | void glcdWidthNumb(uint8_t numb, uint8_t x, uint8_t y) |
2 | {
|
3 | uint8_t i = numb; |
4 | |
5 | glcdGotoXY(x,y); |
6 | for (; i<(numb+8) ; i++) |
7 | {
|
8 | glcdSendData(swapBits(fixednums8x16[i+6])); |
9 | }
|
10 | glcdGotoXY(x+1,y); |
11 | for (; i<(numb+16) ; i++) |
12 | {
|
13 | glcdSendData(swapBits(fixednums8x16[i+6])); |
14 | }
|
15 | }
|
So das man die Funktion mit glcdWidthNumb('1',0,0) aufrufen kann?
Jan H. schrieb: > habe hier gesucht, bin leider nur nicht fündig geworden. Naja, schlecht gesucht: Beitrag "Re: LCD Schriftarten ( Fonts in veschiedenen Größen )" Ein 64x128 Font wie in der Überschrift braucht aber schon ordentlich Speicherplatz, 1024 Bytes pro Zeichen! Da würde ich eher einen kleineren Font wählen und dann in doppelter Breite und Höhe ausgeben.
Thomas F. schrieb: > Ein 64x128 Font wie in der Überschrift braucht aber schon ordentlich > Speicherplatz, 1024 Bytes pro Zeichen! > Da würde ich eher einen kleineren Font wählen und dann in doppelter > Breite und Höhe ausgeben. Stimmt habe mich vertan. Es sollte 6 x 8 heißen.
Jan H. schrieb: > habe hier gesucht, bin leider nur nicht fündig geworden. Da haste aber schlecht gesucht... Jan H. schrieb: > for (; i<(numb+8) ; i++) > { > glcdSendData(swapBits(fixednums8x16[i+6])); Mir scheint, daß du nicht systematisch an die Sache herangehst. Also, du hast ein GRAFIK Lcd, ja? Da solltest du zu allererst dran denken, dein physisches LCD (also die Schnittstelle, deren Bedienung usw) vom logischen Display (also Bildspeicher mit XXX mal YYY Pixeln) zu trennen. Das macht dir das Leben deutlichst leichter, glaub's mir. Bei deinem logischen Display brauchst du zu allererst eine Funktion zum Setzen von Pixeln, etwa so: void SetzePixel(int X, int Y, byte wie); Das "wie" gestaltet sich bei monochromen Displays recht einfach: schwarz, weiß, invertierend. Auf diese Funktion zum Pixel Setzen baust du dir nun alle anderen Funktionen auf: Textzeichen malen, Rechtecke füllen, Linien zeichnen, Kreise zeichnen, Bilder/Icons malen und so weiter. Dabei merkst du gleich, daß bereits ab der SetzePixel-Funktion das Ganze recht hardwareunabhängig wird. Es bleibt eigentlich nur noch die Dimension, also wieviele Pixel in X und in Y. Als zweites brauchst du eine globale bool Variable, die du bei jedem Pixel-Schreiben setzt. Als drittes brauchst du eine Funktion zum blockweisen Übertragen der Pixel zum LCD. Die wird in der Grundschleife aufgerufen, wenn die obige Variable true ist. Diese Funktion schaufelt den ganzen logischen Display-RAM in das Display und setzt obige Variable wieder auf false zurück. So. Damit hast du ein relativ geräteunabhängiges GDI und einen "Hardware-treiber" für dein aktuelles Display. So herum geht das viel besser. W.S.
W.S. schrieb: > Bei deinem logischen Display brauchst du zu allererst eine Funktion zum > Setzen von Pixeln, etwa so: > void SetzePixel(int X, int Y, byte wie); Hallo, das ist sicher richtig wenn man von potenter Steuerungshardware ausgeht. Handelt es sich um einen kleinen µC will man sicher eher nicht 6x8=48 Funktionsaufrufe pro Zeichen, da wird man den Abstraktionslayer doch näher in Richtung Hardware legen wollen. Der andere Quelltext im Thread erinnert auch schwer an einen 8bit AVR o.ä. Jan H. schrieb: > Wie müssten die "for" Schleifen jetzt aussehen? > glcdClear(); > while(1) > { > uint8_t i = 0; > glcdGotoXY(2,0); > for (; i < 7 ; i++) > { > glcdSendData(newArray[i]); > } > glcdGotoXY(3,0); > for (; i < 14 ; i++) > { > glcdSendData(newArray[i]); > } > } Kommt darauf an. Reine Spekulation: Handelt es sich um das "Standard"-LCD12864 mit ST7920? Dann (wie immer) lohnt sich ein tiefer Blick ins Datenblatt, das Teil verfügt über 16bit Breite Spalten im Grafikmodus. Bei den gotoxy... ist zu beachten, dass sich die unterer Hälfte meist linear an die obere anschließt, sprich logisch sind es eher 256x32 Pixel. Die oben erwähnte 7x15er ist eigentlich 7x16 und macht in sofern Sinn, dass man ein Zeichen ohne Umwege in einer Spalte platzieren kann. 11111100 11111110 00000011... sieht aus wie die 3 rechten oberen Zeilen der 0, die müssen dann auch so platziert werden 0x0F -> 00001111 0x1F -> 00011111 könnte links oben sein, also muss jetzt 16 bit Zeilenweise der Array[zeile+0] und der Array[zeile+8te] Wert aufs Display geschrieben werden. In welcher Reihenfolge müsste ich jetzt selbst erst ins Datenblatt gucken. Dass man bei so einer Schriftart auch ein normales Text-LCD mit 16x02 nehmen könnte (wenn das die einzige Grafikanzeige wird) ist denke klar. Sollen nun aber andere Schriftgrößen angezeigt werden wird es zunehmend schwieriger. Bei den angedachten 6x8 passen nämlich 2 2/3 Zeichen in eine 16 bit breite Spalte, daher muss man entweder diese Spalte im Speicher vorbereiten (+weitere wenn die Zeichen überlappen) oder sich den Speicherinhalt vom LCD zurücklesen, anpassen und wieder zurückschreiben. Gruß Dominik
Dominik schrieb: > Hallo, > das ist sicher richtig wenn man von potenter Steuerungshardware ausgeht. > Handelt es sich um einen kleinen µC will man sicher eher nicht 6x8=48 > Funktionsaufrufe pro Zeichen, da wird man den Abstraktionslayer doch > näher in Richtung Hardware legen wollen. > Der andere Quelltext im Thread erinnert auch schwer an einen 8bit AVR > o.ä. Das ist doch völlig Banane. Ich habe erst letztens einen Treiber für ein ST7735 gebaut auf nem STM mit 72MHz. Da kann es genauso zu langsam werden. Liegt aber nicht an der Funktion, sondern was man dem Compiler an Optimierungen ermöglicht. Mit O0, ohne LTO und inlining wird es natürlich arsch lahm, wenn man viele Funktionen hat. Aber deshalb drauf zu verzichten? Äh, ne...
Nico W. schrieb: > Das ist doch völlig Banane. Ich habe erst letztens einen Treiber für ein > ST7735 gebaut auf nem STM mit 72MHz. Da kann es genauso zu langsam > werden. Liegt aber nicht an der Funktion, sondern was man dem Compiler > an Optimierungen ermöglicht. Hallo, war keine Kritik, nur ein Vorschlag, sicherlich kann man das so machen, kommt wie gesagt auf das System an und was man erreichen will. Setzt man auf ein langsames Pferd (Atmega mit 8Mhz oder so), wird die Performance davon schon profitieren wenn man (bei oben spekuliertem Szenario) seine Grafikansteuerung auf die 16bit Felder abstimmt. Wenn ich einzelne Bits setze, kann der Compiler da auch nicht auf 16 bit Breite optimieren. Bleiben wir mal beim Beispiel mit dem AVR und dem 128*64er Display, wenn ich jetzt alle Pixel per Funktion setzen will (z.B. CLRSCR) brauche ich 8192 Aufrufe meiner setPixel(...)-Funktion, nehmen wir mal an, diese operiert auf einem internen Grafik-Speicher:
1 | uint8_t pixMap[16][64]; |
2 | void setPixel(uint8_t x, uint8_t y, uint8_t white) |
3 | {
|
4 | uint8_t column=x>>3; //Div 8 |
5 | uint8_t bit=x&0x07; //Modulo 8 |
6 | switch(white) |
7 | {
|
8 | case 1: |
9 | pixMap[column][y]|=(1<<bit); |
10 | break; |
11 | case 0: |
12 | pixMap[column][y]&=(uint8_t)(~(1<<bit)); |
13 | break; |
14 | }
|
15 | }
|
Diese Beispiel-Funktion (ohne Aufrufe) benötigt auf obigem AVR etwas über 50 Takte, macht 410.000 Takte nur für das setzen aller Pixel, also etwa 1/20 Sekunde... Kann je nach Anwendung genügen. Aber wahrscheinlich hat der Controller ja auch noch irgendeine Hauptaufgabe wenn es nicht unbedingt ein dedizierter LCD-Treiber ist. Es führen viele Wege nach Rom. Gruß Dominik
Dominik schrieb: > das ist sicher richtig wenn man von potenter Steuerungshardware ausgeht. > Handelt es sich um einen kleinen µC will man sicher eher nicht 6x8=48 > Funktionsaufrufe pro Zeichen, da wird man den Abstraktionslayer doch > näher in Richtung Hardware legen wollen. Wenn man selber potent genug ist, um sich seine Probleme selbst zu lösen, dann ist dein Vorschlag richtig. Wenn man hingegen schon an den Präliminarien scheitert, dann nicht. In letzterem Falle sollte man eben doch die 48 Aufrufe sich gönnen - einfach um wenigstens dazu in der Lage zu sein, das richtige Setzen von Pixeln zunächst zu lösen, bevor man sich an höhere Dinge wagt, wie z.B. das Verstehen und Anwenden von Fonts. Nebenbei ist der schiere Aufruf eher kein Thema. Beim Pixelsetzen muß man ja noch so einiges anderes machen, z.B. Abprüfen der Bounds (if x<0 or x>displaybreite or y<0 oe y>displayhöhe dann raus hier..) oder das Ausführen der Pixelmodi (if black then machblack else if white then.. else if invert then liespixel..xorpixel..setpixel..) - kurzum, die 48 Aufrufe lohnen sich, damit ein bissel Qualität und Funktionssicherheit hineinkommt. W.S.
W.S. schrieb: > Nebenbei ist der schiere Aufruf eher kein Thema. Beim Pixelsetzen muß > man ja noch so einiges anderes machen, z.B. Abprüfen der Bounds (if x<0 > or x>displaybreite or y<0 oe y>displayhöhe dann raus hier..) oder das > Ausführen der Pixelmodi (if black then machblack else if white then.. > else if invert then liespixel..xorpixel..setpixel..) - kurzum, die 48 > Aufrufe lohnen sich, damit ein bissel Qualität und Funktionssicherheit > hineinkommt. Wie gesagt, viele wegen führen nach Rom, aber wenn das anzunehmende Target ein 8bit µC ist, würde ich das nicht machen sondern bereits in den aufrufenden Funktionen die Bereichsüberschreitungen verhindern. Je nach uC kommt sonst neben Geschwindigkeitsproblemen auch gerne mal das Ende vom Flash sehr nahe :-) Im Falle der Programmierung einer Anwendersoftware unter einem gängigen Betriebssystem stimme ich dem natürlich zu, da wird man diese Überschreitungen meist auch zusätzlich noch zum debuggen catchen. Dominik schrieb: > uint8_t column=x>>3; //Div 8 > uint8_t bit=x&0x07; //Modulo 8 Sowas würde ich für eine solche Anwendung dann auch in "Schönschrift" programmieren. Sofern man die setPixel-Variante auf dem µC gehen will, sollte man aber zumindest clearScreen/setBackground/setPattern/etc. auf die logischen Spalten und Zeilen des Displays umsetzen, damit man dort wenigstens nicht jede Variable 8x anfassen muss. Gruß Dominik
Dominik schrieb: > Wie gesagt, viele wegen führen nach Rom, aber wenn das anzunehmende > Target ein 8bit µC ist, würde ich das nicht machen Ich auch nicht wirklich. Also was soll das Ganze? Mit einem Grafik-Display ist ein kleiner 8 Bitter recht schnell an seinen Grenzen. Ich hatte mal aus Wißbegierde ein ALPS LSU7S1011A (von Pollin) mit einem PIC16F871 in Assembler angesteuert. Ja, geht, geht auch schnell genug, aber ist dennoch ein einziger Krampf, weil eben der µC dafür zu klein war. Also, wenn wirklich Grafik ansteht, dann den Controller danach auswählen. Wenn die Grafik nur so etwa 128x64 oder gar nur 96x32 oder so beträgt, dann muß der Controller nur genügend RAM mitbringen, in diesem Fall so etwa 1K für den Display-RAM und nochwas obendrauf für den Rest des Ganzen. Die Geschwindigkeit reicht zumeist völlig aus. W.S.
8 bit und Display ist ein weites Feld. https://atmelcorporation.wordpress.com/2015/05/28/build-an-inexpensive-handheld-gaming-console-with-atmega328/ Auch ein kleiner 8-bit Arduino kann was. Obwohl ich einen STM32 mit TFT bevorzuge würde ich das pauschale Ablehnen eines Displays an einen 8-bitter nicht unterstützen. Der C64 war ja auch nicht ohne Grund trotz seiner 8-bit ein Grafikwunder zu seiner Zeit. Gruß, dasrotemopped.
dasrotemopped schrieb: > würde ich das pauschale > Ablehnen eines Displays an einen 8-bitter nicht unterstützen. Sehe ich auch so, kommt halt immer drauf an, was man machen will, und wie man es dann genau macht. Ich habe auch schon ein LCD-Display mit Schieberegister an einen Tiny45 gefriemelt, ob man sich dann einen Gefallen getan hat oder besser was größeres genommen hätte, muss man von Fall zu Fall mit sich selber ausmachen. Gruß Domihik
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.