Hallo allerseits! Ich habe für das DOGXL-Display ein Fontgenerator programmiert, welcher beliebige Fonts in beliebigen Größen generieren kann. Features: - Schwarzweiß und Graustufenfonts - Schwarzweißfonts in sparsamer 8bit-Speicherart generierbar. - Vorschau eines beliebigen Textes möglich. Viel Spaß beim probieren! Meldet bitte grobe Fehler in diesem Thread! Ich könnte mir vorstellen, dass der Fontgenerator auch für das DOGL-Display funktioniert (im S/W 8-Bit Modus). (Mod: in Forum Codesammlung verschoben)
:
Verschoben durch Moderator
Vielen Vielen Dank! Genau das, worauf ich ewig gewartet habe! Das bringt mein Projekt wesentlich weiter voran! Wenn interesse besteht helfe ich auch bei der Weiterentwicklung des Tools! Die erstellung des Fonts ist noch etwas umständlich, wie ich so finde! Mit freundlichen Grüßen, Andreas Müller
Habe soweit das ganze mal Implementiert und jetzt erschreckend festgestellt, dass ich den Font in Hex bräuchte, statt in Dezimal angaben. Könnten sie mir den Source Code zukommen lassen, damit ich das umschreiben könnte? Zudem wäre es von Vorteil, wenn man die Column Read und Page Read Funktionen umbenennen könnte. Auch eine Variablen / Namensvergabe für den Font wäre von Vorteil! Vielen Dank! Mit freundlichen Grüßen, Andreas Müller
Habe das Tool jetzt nur mal kurz angetestet (also ohne das Ergebnis auf dem Target zu prüfen). Gefällt mir ganz gut, vor allem das Vorschaufenster ist hilfreich. Da Tool macht genau das (und nicht mehr!) was es soll: Font auswählen, in der Vorschau prüfen ob die Darstellung auf dem Display passt, Auswählen welche Zeichen generiert werden sollen, generieren. Ok, die GUI sieht gefrickelt und wenig intuitiv aus, aber mit 2 min rumspielen kann man die Funktionsweise auch so kapieren. Leider habe ich mein aktuelles Projekt schon mit einem anderen Tool (auch gut, aber viel mühseliger!!) aufgebaut.
>Könnten sie mir den Source Code zukommen lassen, damit ich das umschreiben könnte? Ich habe mich einfach mal rangesetzt und die Vorschläge umgebaut. Ich denke mal, dass das am einfachsten ist. Mein Code ist nicht gerade schön dokumentiert, ich glaube das ist nicht jedermanns Sache... Das Program ist jetzt etwas intuitiver und das Vorschaufenster aktualisiert sich sofort, wenn man z.B. die Graustufen ändert. PS: Grunsätzlich habe ich nichts gegen ein "Du" im Forum :-) >Zudem wäre es von Vorteil, wenn man die Column Read und Page Read Funktionen umbenennen könnte. Was meinst Du/meinen Sie damit genau? Wenn es um die von mir im Info vorgeschlagenen "write_zeichen_8bit" bzw "write_zeichen_4bit" Funktionen geht, so handelt es sich hier eher um Vorschläge, wie man es machen könnte. Ich würde grundsätzlich nicht empfehlen, meine Vorschläge "blind" zu übernehmen, ich könnte mir vorstellen, dass es auch bessere Wege gibt.
Hallo Martin, dickes Lob, sieht gut aus ;) Hab nur mal kurz damit gespielt. Solche Beiträge sind ein sehr wohltuender Ausgleich zu manchen Anderen. avr PS: Du solltest das Programm evtl. bei den Tutorials verlinken.
Hallo Martin, auch von mir ein dickes Lob! Das ist genau das, was ich brauche! Nur leider wirds aus Zeitmangel noch etwas dauern, bis ich den Font einbauen kann. Leider funktioniert in der neuen Version die Anzeige für den Platzverbrauch nicht mehr. Vielleicht kannst du das noch fixen. Ich versteh auch noch nicht, was die Regler für die Graustufen-Grenzen bewirken sollen. Wenn ich sie verschiebe (und danach auf "berechnen" klicke) ändert sich am generierten Array irgendwie nichts. Und wenn ich mir noch was wünschen darf: Ich muss die Zugriffs-Funktionen sowieso neu implementieren, weil ich in Assembler schreibe (hab auch ein anderes Display). Ich fänds komfortabler, wenn es ein zweites Array gäbe, in dem die Offsets der Buchstaben gespeichert sind. Ist sicher nur persönliche Vorliebe, aber der Speicherverbrauch ist bei mir egal. Viele Grüße, Sebastian
"PS: Du solltest das Programm evtl. bei den Tutorials verlinken." Wie meinst du das? Beziehst du dich auf die Artikel-Seiten? "auch von mir ein dickes Lob!" Danke! Das motiviert zum Weitertüfteln. "Leider funktioniert in der neuen Version die Anzeige für den Platzverbrauch nicht mehr." Danke für den Hinweis, habe wohl verwesehentlich das Element gelöscht. "Ich versteh auch noch nicht, was die Regler für die Graustufen-Grenzen bewirken sollen. Wenn ich sie verschiebe (und danach auf "berechnen" klicke) ändert sich am generierten Array irgendwie nichts." Eigentlich sollten in der V2 bzw V3 das automatisch geändert werden (ohne dass man weiter klicken muss). Nimm mal eine eher große Schriftart (16 oder so), dann sieht man es, wenn man die Regler ändert. "Und wenn ich mir noch was wünschen darf: Ich muss die Zugriffs-Funktionen sowieso neu implementieren, weil ich in Assembler schreibe (hab auch ein anderes Display). Ich fänds komfortabler, wenn es ein zweites Array gäbe, in dem die Offsets der Buchstaben gespeichert sind. Ist sicher nur persönliche Vorliebe, aber der Speicherverbrauch ist bei mir egal." In der aktuellen Version habe ich nun eine solche Funktion eingefügt (Siehe "Sondereinstellungen").
Wow, das ging schnell! Der Platzverbrauch funktioniert jetzt wieder. Mit den Graustufen bin ich mir jetzt nicht sicher. An der Schrift ändert sich tatsächlich was, wenn ich die Regler verschiebe. Ist mir vorher garnicht aufgefallen. Aber müsste sich nicht eigentlich auch das generierte Array ändern, wenn ich die Schieber verstelle? Da tut sich nämlich augenscheinlich garnichts. Das mit dem Extra-Array hast du leider falsch verstanden (habs auch etwas vage ausgedrückt). Ich finds etwas aufwändig, sich über die länge von jedem einzelnen Buchstaben zum Start des gesuchten Buchstaben durchzuhangeln. Deswegen wollte ich in einem Extra Array die Indizes der jeweils ersten Bytes der Zeichen. Wenn ich dann ASCII-Zeichen 65 will schau ich in das look-up-array an Position 65. Da steht dann z.B. 1234, womit ich weiß, dass Zeichen 65 an position 1234 des großen Array anfängt. Ich weiß nicht, wie viel Arbeit das für dich ist. Ich brauch das nicht unbedingt. Aber nachdem der Speicher für mich egal ist investier ich lieber Flash als Rechenzeit und programmieraufwand ;) Viele Grüße, Sebastian
"Mit den Graustufen bin ich mir jetzt nicht sicher. An der Schrift ändert sich tatsächlich was, wenn ich die Regler verschiebe. Ist mir vorher garnicht aufgefallen. Aber müsste sich nicht eigentlich auch das generierte Array ändern, wenn ich die Schieber verstelle? Da tut sich nämlich augenscheinlich garnichts." Hm, da war in der Tat ein blöder Fehler verbaut. Jetzt werden die Werte aktualisiert, wenn man die Schieberegler ändert und den Font neu berechnen lässt. Schau mal in die angehängte Version, da ist jetzt auch so eine Schlüsseltabelle drin, ich glaube es ist das was du meinst.
Du bist der Beste! Genau so hab ich mir das gedacht. Vielen Dank! Und wie du schon sagst ändern sich jetzt auch die Daten der Ausgabe, wenn man die Schieber verstellt. Eine kleinigkeit ist mir gerade noch aufgefallen: Die Zeichen 0-32 haben als "Höhe unter Textoberkante" alle -4 bzw. 0x0FFFFFFFC. Ist jetzt nichts was mich wirklich stört, aber wirkt nicht besonders sinnvoll.
Nach etwas rumprobieren scheint das Problem mit der negativen Höhe erst ab Schriftgröße 13 aufzutreten. Bis 12 scheint alles in Ordnung zu sein. Hab aber natürlich auch nur stichproben machen können. Andere Abhängigkeiten hab ich nicht gefunden.
Die Zeichen 0-32 existieren doch gar nicht recht (bzw sind Befehle), oder? Somit könnte man mit der Zeichengenerierung sowieso erst bei 33 anfangen, da alles andere nur Platzverschwendung ist? Oder habe ich da gerade ein Denkfehler?
Stimmt schon. Drum sag ich ja auch, dass es mich nicht wirklich stört. Wobei der Tabulator eigentlich schon ein darstellbares Zeichen ist. Halt als Whitespace. 0x7F (DEL) erzeugt übrigens den gleichen Fehler. Scheinen also wirklich alle Steuerzeichen zu sein. Wollte es nur anmerken. Wenns dich nicht stört, dann lass es drin. Sebastian
Ich glaube, ich werde es erstmal so lassen, wie es ist. Ich habe gerade herausgefunden, dass auch die Zeichen jenseits der 127 funktionieren (Siehe z.B. in der unteren Tabelle auf dieser Seite: http://www.torsten-horn.de/techdocs/ascii.htm). In meinem konkreten Fall brauchte ich das °-Zeichen, welches sich auch im C-Code durch '°' abrufen lässt. Ich spiele mit dem Gedanken, ein ähnliches Programm für Grafiken zu machen. Besteht Interesse, und wenn ja, für bestimmte Funktionen? Dachte da an das Importieren von BMPs, welche wieder als SW oder Graustufenbilder geladen werden können.
Kleines Update: Ich habe einen Fehler entdeckt: Bei machen Schriftarten konnte es vorkommen, dass die Schrift oben abgeschnitten war. In der Version im Anhang ist der Fehler berichtigt.
Die Arbeit mit den Bildern kannst du dir vermutlich sparen. Da gibts schon ein recht gutes von Läubi: www.mikrocontroller.net/topic/92623 Das kann dann zum Beispiel auch dithern. Solange du nichts ganz spezielles brauchst wird sichs nicht lohnen selbst was zu schreiben. Bei den Zeichen ab 128 wär jetzt halt noch die Frage, welcher Zeichensatz das genau ist. ISO 8859-1 und -15 sind fast identisch, aber halt nur fast. Und Unicode ist bis Zeichen 255 identisch zu ISO 8859-1, danach aber nicht mehr. Von den anderen ISO 8859-Teilen kämen theoretisch auch noch ein paar in Frage, ist aber unwahrscheinlich. Unterm Strich ists nicht so wichtig. Wollte eigentlich nur auf die fehlende Information aufmerksam machen ;) Viele Grüße, Sebastian
@Martin Ohne mir die Software genauer angeschaut zu haben muß ich sagen : Schön :-) Hatte vor zwei Jahren mal etwas ähnliches programmiert, aber nicht hier rein gestellt weil ich noch einige Features einbauen wollte die aber dann liegen geblieben sind. Mit dem Tool lässt sich ein Windows-Font auswählen. Zusätzlich zur Grau-Wert-Schwelle (da die Fonts ja meistens über Antialiasing "abgerundet" sind) konnte man noch oben/unten/links/rechts was abschneiden um überflüssige Leerzeilen rauszunehmen. Gleichzeitig gibts dazu auch immer ne Vorschau um zu sehen ob die Buchstaben noch "brauchbar" sind. Bei den Fonts hab ich nur von ASCII 32 bis ASCII 128 (also 96 Zeichen) berücksichtigt. Zusätzlich lassen sich noch Bitmaps selbst Zeichnen die dann auch in dem Gesamt Array abgespeichert werden. Allerdings wird das ganze nicht so einfach abgespeichert. Es wird Pixel für Pixel (bit-weise) hintereinander weggeschrieben. Wenn ein Buchstabe also beispielsweise 5x5 Pixel groß ist werden daraus 25 Bit. Eine zweite Tabelle enthält dann die Start-bit-adressen und die Größe der jeweiligen Bitmap. Also schon recht platzsparend, aber auch (gerade auf einem AVR) nicht sehr effektiv, denn bitoperationen (<< und >>) brauchen ja gerade mit variablen Shifts relativ lange, und je nach Font sind ja viele dieser Operationen nötig. Und da ich bisher noch keine Optimierung beim Zeichnen gemacht hatte (bei mir Funktionierte das was anders, weil kein "normales" Display verwendet hab, und die Bit-Operationen nicht im AVR liefen) Vllt stell ich das Tool auch nochmal bereit.
Also von mir auch noch einmal ein riesen Danke an den Ersteller der Software! Das Funktioniert echt prima das ganze! Hab schon verschiedene Schriftarten im EEPROM meines AVRs und klappt sehr super! Was meinst Du/meinen Sie damit genau? Wenn es um die von mir im Info vorgeschlagenen "write_zeichen_8bit" bzw "write_zeichen_4bit" Funktionen geht, so handelt es sich hier eher um Vorschläge, wie man es machen könnte. Ich würde grundsätzlich nicht empfehlen, meine Vorschläge "blind" zu übernehmen, ich könnte mir vorstellen, dass es auch bessere Wege gibt. Ich beziehe mich auf die beiden Funktionen: -set_page_address(ypos+i+offset); -set_column_address(xpos); Wenn man das als Textbox hätte, in die man den Funktionsnamen eintragen könnte, den man bisher verwendet wäre auch die Codeerstellung völlig ausreichend! Habe die Zeichen-Parse Funktionen angepasst, ist also nicht höchste Prio! Nochmals vielen Dank für das sehr sehr hilfreiche Tool! MFG Andi
Ha stimmt, da sind ja noch die Unterfunktionen, auf die ich nicht näher eingegangen bin. Hier sind die fehlenden Funktionen: void set_column_address(uint8_t column) { write_command(0b00000000|(column%16)); write_command(0b00010000|(column/16)); } void set_page_address(uint8_t page) { write_command(0b01100000|page); } void write_data(uint8_t data) { EA_PORT&=~(1<<EA_CS); EA_PORT|=(1<<EA_CD); //Data spi_send_and_receive(data); EA_PORT|=(1<<EA_CS); } void write_command(uint8_t cmd) { EA_PORT&=~(1<<EA_CS); EA_PORT&=~(1<<EA_CD); //Command spi_send_and_receive(cmd); EA_PORT|=(1<<EA_CS); } Was die Namen angeht, so glaube ich, dass es im Texteditor mit der Ersetzten-Funktion fast genauso schnell geändert wird als mit dem Eingabefeld. Falls ich nochmal etwas ändere im Programm, so könnte ich dann diese Felder noch nachrüsten.
Für meinen Fall hab ich wie gesagt die einfache Methode mit dem ersetzen gemacht. Funktioniert ja auch einwandfrei, wäre halt von Vorteil, wenn man so nen Code Parser implementiert hat. Ist aber nur meckern auf hohem Niveau. Ansonsten ist das ganze echt super! Hab schon 3 verschiedene Schriften drinne und auch nur je die Zeichen die ich benötige. Sehr effektiv und Platzsparend! Mit freundlichem Gruß, Andreas Müller
Eine Frage hätte ich noch selbst, jetzt da hier mehrere Leute sind, die das Display benutzen: Ich hatte bislang immer eine Soft-SPI benutzt, die das Display ansteuert. Ich würde gerne auf die SPI-Funktion des Atmega wechseln und habe auch eine grundsätzlich funktionstüchtige SPI-Ansteuerfunktion genommen (die bei anderen Projekten funktioniert). Hier jedoch tut sich gar nichts, ich glaube, dass der uC in der Schleife für das Abfragen des SPI Interrupt-Flags hängen bleibt. Bei mir ist Miso aktuell offen (ohne irgendein definiertes Potential). Könnte es daran liegen? Ein Test mit 10k gegen GND hat jedoch nicht funktioniert. Und sehe ich es richtig, dass CPOL´und CPHA gesetzt sein muss? Falls jemand SPI nutzt würde ich ihn/sie bitten, die Einstellungen bzw. Funktionen hier zu posten.
Hi
>Und sehe ich es richtig, dass CPOL´und CPHA gesetzt sein muss?
Nein. Die DOG-Displays laufen im SPI-Mode 0 (CPOL = 0, CPHA = 0).
MfG Spess
Hallo Spess53, wenn ich mir das DB vom DOGXL anschaue würde ich sagen: mode 3. CPOL=1, CPHA=1. Gruß Holger S.
Hi Dann mache ich etwas falsch. Bei mir laufen alle Dogdisplays (M132,L/M128,S102 und XL160) im SPI-Mode 0. Und das funktioniert z.B. auch mit TLC5925 und ENC28J60 , die nur Mode 0 können, am gleichen Bus. MfG Spess
Kannst du deine weiteren Einstellungen posten? Und was hast du mit MISO gemacht?
Hi >Kannst du deine weiteren Einstellungen posten? Und was hast du mit MISO >gemacht? SPE und MSTR in SPCR setzen. Wenn es schnell sein soll, noch SPI2X in SPSR. MISO wird beim gesetzten MSTR-Bit automatisch Input. Du kannst aber mit PORTB4 den internen Pull-Up-Widerstand einschalten. MfG Spess
Hm, ich bekomme es noch immer nicht zum laufen. Dies ist meine (nicht funktionierende) SPI-Ansteuerung:
1 | #define SPI_DDR DDRB
|
2 | #define SPI_PORT PORTB
|
3 | #define SPI_MOSI PB3
|
4 | #define SPI_MISO PB4
|
5 | #define SPI_SCK PB5
|
6 | |
7 | void SPI_Master_Init(void); |
8 | void SPI_Master_WriteByte(uint8_t data); |
9 | void SPI_Master_Wait(void); |
10 | |
11 | void inline SPI_Master_Init() |
12 | {
|
13 | //MOSI, SCK auf Output und MISO auf Input laut Datenblatt und den Rest unangetastet lassen
|
14 | SPI_DDR |= (1 << SPI_MOSI) | (1 << SPI_SCK); |
15 | SPI_DDR &= ~(1 << SPI_MISO); |
16 | SPI_PORT |=(1 << SPI_SCK); |
17 | //SPI auf enable und Mastermode auswählen
|
18 | SPCR = (1 << SPE) | ( 1 << MSTR); |
19 | //SPI mit halber CPU-Frequenz (aktuell nicht aktiviert)
|
20 | //SPSR = (1 << SPI2X);
|
21 | }
|
22 | |
23 | void SPI_Master_WriteByte(uint8_t data) |
24 | {
|
25 | SPDR = data; |
26 | SPI_Master_Wait(); |
27 | }
|
28 | |
29 | void SPI_Master_Wait() |
30 | {
|
31 | //es wird so lange gewartet, bis die SPI-Transmission fertig ist
|
32 | while (!(SPSR & (1<<SPIF))); |
33 | }
|
Ich habe das gefühlt, dass er in der while-Schleife hängen bleibt. Dies ist meine Software-SPI, welche funktioniert:
1 | #define DDR_SPI DDRB
|
2 | #define PORT_SPI PORTB
|
3 | #define MISO PB4
|
4 | #define MOSI PB3
|
5 | #define SCK PB5
|
6 | |
7 | void spi_init(void); |
8 | void spi_send_and_receive (char); |
9 | |
10 | void spi_init() |
11 | {
|
12 | DDR_SPI |= (1<<SCK)|(1<<MOSI); |
13 | PORT_SPI |= (1<<SCK); // idle = high |
14 | }
|
15 | |
16 | |
17 | void spi_send_and_receive (char data) |
18 | {
|
19 | for(uint8_t i=0; i<8; i++) |
20 | {
|
21 | if((data&0b10000000)==0) PORT_SPI &=~(1<<MOSI); |
22 | else PORT_SPI |=(1<<MOSI); |
23 | PORT_SPI &=~(1<<SCK); |
24 | asm volatile("nop"); |
25 | asm volatile("nop"); |
26 | asm volatile("nop"); |
27 | PORT_SPI |=(1<<SCK); |
28 | data*=2; |
29 | }
|
30 | }
|
Der uC ist ein Atmega168
Hm, es bleibt merkwürdig. In meiner Schaltung ist es so, dass an PB2/SS ein Taster angeschlossen ist, welcher den Pegel an PB2 von +3.3V (über Pull-UP Widerstand) auf GND zieht, wenn man drückt. Wenn ich nun die von Bernhard vorgeschlagene Zeile entferne und den Taster beim Starten der Schaltung drücke (d.h. PB2 auf GND ziehe), so funktioniert der SPI. Alternativ geht es auch, wenn ich PB2 als Ausgang definiere. Im anderen Fall, PB2 ist Eingang und ich drücke den Taster nicht (PB2=3.3V), so kommt der genannte Fehler. Nebenbemerkung: Die Initialisierung des SPI ist das allererste, das in meinem Programm passiert. Dann folgt ein Display-Reset und ein bisschen warten (für das Display), und dann geht es mit dem Einrichten des Displays (dafür SPI-Verbindung) weiter.
Hi >Hm, es bleibt merkwürdig. In meiner Schaltung ist es so, dass an PB2/SS >ein Taster angeschlossen ist, welcher den Pegel an PB2 von +3.3V (über >Pull-UP Widerstand) auf GND zieht, wenn man drückt. Lies dir mal den Abschnitt: 'SS Pin Functionality' im Datanblatt durch. MfG Spess
Mist, damit habe ich also nur noch die SOFT-SPI Variante übrig in meinem System. Aber vielen Dank für den Hinweis auf diesen Abschnitt!
Hi >Mist, damit habe ich also nur noch die SOFT-SPI Variante übrig in meinem >System. Aber vielen Dank für den Hinweis auf diesen Abschnitt! Kommt auf deinen Controller an. Bei etlichen AVRs (ATMega48/88168/328, ATMega164/.../1284, ...) ist es möglich die UART im SPI-Mode zu betreiben. Funktioniert auch definitiv. MfG Spess
Ein Nachtrag wegen einer Frage: Sonderzeichen wie 'ä' usw. sind möglich, wenn man entsprechende Zahlen jenseits des ASCII-Bereiches wählt. Hierzu müssen die Nummern aus der 3. Tabelle der folgenden Seite gewählt werden: http://www.torsten-horn.de/techdocs/ascii.htm Natürlich erweitert sich dann der Font jenseits der 127, d.h. ein weiterer Font müsste vom Offset her entsprechend später beginnen.
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.