Forum: Projekte & Code Ultra-einfacher Lowcost LCD Controller 320x240 im Textmodus


von Stefan K. (nukeman)


Angehängte Dateien:

Lesenswert?

Hallo Mikrocontroller-Gemeinde,

heute wollte ich mal ein kleines Projekt vorstellen, was für viele
vielleicht interessant ist, weil man mit sehr wenig Aufwand schnell
ein Grafik-Display zu einer Art HD44780-Ersatz, aber mit deutlich
geringerem Pincount erstellen kann.

Da ich hier im Forum schon sehr viel Wissen und Software
bekommen habe ( insbesondere von Benedikt K., Peter Dannegger
und Wigbert Picht ), habe ich mich dazu entschieden das Projekt
hier auch frei zu veröffentlichen um mal etwas zurück zu geben.

Es ist im Wesentlichen eine Portierung,Vereinfachung und Erweiterung
von Benedikts Beitrag "Einfacher Low Cost LCD Controller für 320x240 LCD im Textmodus"
für den Tiny25.

Die Besonderheit ist der minimale Footprint des Prozessors mit
min. 1k3 Flash und 128 Bytes RAM, sowie 5(6) IO-Pins  (ATTiny25)
d.h. kaum ext. Komponenten erforderlich, minimaler Verdrahtungs-
aufwand zum Display und zur Anbindung an den Host-Prozessor + extrem
kostengünstiger Prozessor mit 96ct @ Reichelt (15.03.2013).
Um auf die geringe IO-Pinzahl zu kommen, wurde der Trick angewendet,
dass die 4 Datenleitungen D3..D0 den gleichen Wert bekommen,
also nur einen Pin am Prozessor belegen.

Idealer Ersatz für HD44780-Displays, wenn wenig Pins zur Verfügung
stehen und vielleicht ein paar Zeichen mehr angezeigt werden sollen,
oder eine besonders große Anzeige gewünscht wird.
Den Tiny kann man zur Not freischwebend mit auf die Display-Platine
tackern. Was fehlt ist Display On/Off und Erstellen/Kontrollieren der
LCD-Spannung. Dies lässt sich aber meist recht einfach ext. realisieren.

Die Beispiel-Software steuert ein 320x240 LCD an, und zeigt auf diesem
durch Skalierung eines 6x8 Fonts 13x5 Zeichen an. Auch andere Font-
Größen, Auflösungen und Display-Dimensionen lassen sich nach einfacher
Programm-Änderung realisieren, z.B. 640x200 usw.

Leider ist die Konfiguration nicht ganz so komfortabel wie beim
Original-Programm, man muss selbst mit Font und Blockgröße rechnen
und schauen, ob am Ende der Zeile ggf. noch Leer-Takte eingefügt werden
müssen.

Im Beispiel habe ich einen Font von 6x8 Pixel und ein 320x240-Display
mit  4-Bit Ansteuerung. Bei 13 Zeichen ist die X-Breite im Display
13 Zeichen x6 Fontbreite x4 Pixel = 312 Pixel im Display. Es fehlen da
also noch 2 4px-Takte um die Zeile komplett auszufüllen.

Die Y-Skalierierung kann man eigentlich immer so einrichten, dass es
aufgeht und keine Extra-Leerzeilen eingefügt werden müssen.
Hier ist sie 5 Zeilen x8 Fonthöhe x6 Skalierung = 240 Pixel im Display.

Bitte auch auf den RAM-Verbrauch achten, der Tiny25 hat nur 128 Bytes,
so dass die Auflösung auch dadurch begrenzt ist. Außerdem werden noch
ein paar Bytes für Call- und Interrupt-Stack gebraucht. Die maximale
Speichergröße für's Display-RAM habe ich nicht ausgerechnet, müsste
knapp unter 120 Bytes liegen.

Die Maschine läuft immer unter Vollgas und erreicht im Beispiel bei
16.5MHz eine Bildwiederholfreq von fast 117Hz. Wenn das für das Display
zu schnell ist, muss man mit niedrigeren CPU-Frequenzen experimentieren.

Der ASCII-Zeichensatz ist etwas reduziert auf die Zeichen 0x20..0xAF,
den Kram dahinter braucht sowieso keiner. Per UART können im laufenden
Betrieb 8 User-Zeichen als ASCII 0x85..0x8B im Flash verändert werden.
Das Flashen sieht man allerdings, weil in der Zeit das Display nicht
betreut wird.

Wenn das Signal "M" gebraucht wird, muss der Reset-Pin dafür "geopfert"
werden. Man kann dann (vorher!) immer noch einen Bootloader
installieren, so dass man noch was ändern kann ohne einen HV-Programmer
zu bemühen. (Ich empfehle den FBOOT von P. Dannegger. Vielen Dank an
dieser Stelle dafür!).

Die Empfangsdaten werden am UART-RX-Pin mit 19k2 eingelesen. Genaueres
zum Protokoll findet sich im Source-Code.
Die fertige HEX-Datei im Beispiel beinhaltet schon den FBoot21 von P.
Dannegger mit RX=PB2 und TX=PB0.
Außerdem liegt ein Windows-Konsolen-Programm dabei, womit man das
Display kurz antesten und auch testweise die User-Zeichen neu
programmieren kann.

Viel Spaß damit!

Gruß,
Stefan

: Verschoben durch User
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Das sieht sehr nett aus - könnte für ein altes Display eines Palm 
Handheld genau das richtige sein. Da ich hier Tiny45 und 85 liegen habe, 
bin ich gerade dabei, deinen Code mit conditionals auf die Dingerchen 
anzupassen, da ist auch ein bisschen mehr RAM und Flash drin, so das man 
evtl. ein paar Beschränkungen aufheben kann. Spitzenarbeit, vielen Dank 
dafür!

von Harald P. (haraldp)


Lesenswert?

Die Idee der 1-Bit-Ansteuerung des Graphik-Displays scheint genial zu 
sein. Ich habe nur nicht verstanden, wie sie funktioniert. Ich dachte 
bisher, daß mit dem Clk-Signal alle 4Bit (D0..3) vom Display auf einmal 
eingetaktet werden. Daß es auch bitseriell funktioniert, ist mir neu. 
Oder habe ich etwas übersehen?
Harald

von Malte S. (maltest)


Lesenswert?

Das fragte ich mich auch, bis der Groschen fiel:
1 Takt = 4 Pixel. Effektive Auflösung = 320 / 4 = 80
Bei proportionaler Streckung in der Vertikalen fällt das kaum auf :)

Naja, wer lesen kann, ist klar im Vorteil:

Stefan K. schrieb:
> Im Beispiel habe ich einen Font von 6x8 Pixel und ein 320x240-Display
> mit  4-Bit Ansteuerung. Bei 13 Zeichen ist die X-Breite im Display
> 13 Zeichen x6 Fontbreite x4 Pixel = 312 Pixel im Display. Es fehlen da
> also noch 2 4px-Takte um die Zeile komplett auszufüllen.

- diesen Absatz habe ich aber auch erst jetzt "inhaltlich gefunden".

von Stefan K. (nukeman)


Lesenswert?

Danke für eure positiven Kommentare und die richtige Erklärung von 
Malte.

Momentan experimentiere ich mit einem "M-losen" Display und habe
auf den Reset-Pin statt "M" einen 2. Datenkanal gelegt. So lässt sich
die effektive Auflösung bei z.B. 320x240-Displays auf 160x240 steigern
(mit Programm-Änderung natürlich).

Dx = D3 + D2
Dy = D1 + D0

Oder wenn man ein 8-Bit Display hat geht auch Dx = D8..D4, Dy=D3..D0,
womit man wieder bei 4px wäre.

Noch ein Hinweis bevor hier ein Suppenhaar-Kasper zuschlägt:
Beim hochgeladenen Programm ist das "M"-Signal je nach Betriebszustand
und Ansteuerung nicht 100% DC-frei, weil die Flanken durch Interrupts
und RX-Behandlung leicht verzögert werden können.

Ich denke, durch die statistisch gleichberechtigten Störungen in High-
und Lowphase ist das nicht ganz so schlimm. Würde jedenfalls nicht
darauf warten wollen, dass ein LCD daran kaputt geht. Es wäre noch
Platz im Programm, um M aus einem Interrupt zu generieren oder in der
main-loop an einem Timer zu synchronisieren.

Beim Flashen von User-Zeichen gibt es längere Zeit überhaupt kein
M-Signal, sollte man also besser nicht zyklisch machen.

Stefan

PS: Weil so viele das 2.Bild angeklickt haben: Nein, es ist mir noch
nicht gelungen mit einem Hack auf einem S/W Display "Rot"
darzustellen :D
Es soll nur die User-Zeichen markieren, die man umdefinieren kann.
PPS: der höchste darstellbare ASCII-Code ist 0x9F, nicht 0xAF

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.