
Hallo nochmal, Habr! Nachdem ich
den Artikel über die Verwaltung des LCD-Moduls mit einem Treiber übersetzt hatte, jedoch ohne meinen eigenen Video-RAM, entschied ich mich, eine weitere Veröffentlichung zum gleichen Thema zu übersetzen. Hier ist das Modul bereits einfacher, monochrom, aber es ist nicht weniger interessant, es wiederzubeleben.
LCD-Steuerung mit Treiber, jedoch ohne Controller
Das Display, mit dem der Autor arbeiten wird, stammt aus einer alten Bandbibliothek. Der Controller überlebte nicht, aber eine Suche nach irgendetwas im Zusammenhang mit „263645-001“ ergab, dass es ein FPGA gab. Es wird angenommen, dass solche LCD-Module direkt von Arduino usw. aus gesteuert werden. unmöglich, benötigen Sie eine Zwischenverbindung - den Controller der SEDxxxxx-Serie, der nicht mit dem Steckbrett „freundlich“ ist und mehr Eingänge als das Modul selbst hat. Aber das ist nicht so. Hier sind bis zu vier ähnliche Projekte:
Auf dem ATmega8515DaraufAuf BildAuf ESP32Und einige steuern im Allgemeinen 8-Bit-AVR-VGA-Monitore ...
Im Allgemeinen gelang es dem Autor, die Software unter der MIT-Lizenz ist
hier .
Standbild
Um sicherzustellen, dass alles funktioniert, müssen Sie zunächst versuchen, ein Einzelbit-Rasterbild aus dem Flash-Speicher des Mikrocontrollers auszugeben. Um eine negative Spannung zu erhalten, haben wir drei „Crones“ genommen. Die Spannung vom Teiler, der als Abstimmwiderstand verwendet wurde, wurde an den V0-Anschluss angelegt. Und hier auf dem Bildschirm ist Lenna:

Der Autor kann immer noch nicht verstehen, wie er es geschafft hat, das Bild umzudrehen (schauen Sie, auf welcher Seite sich das Kabel befindet). In jedem Fall gibt es dieses Beispiel auf der Projektseite von GitHub.
Textmodus
Das Video-ROM ist jedoch wenig nützlich, und im Arduino befinden sich keine 9600 Byte für Video-RAM. Der Textmodus hilft, bei dem der ROM des Zeichengenerators und der Video-RAM zusammen kleiner sind als der Video-RAM im Grafikmodus. Anhänger der Republik Kasachstan und der „Spezialist“ können in diesem Bereich endlos Speere brechen.

Ein kurzes Beispiel in der AVR-Assemblersprache:
... lpm r24, Z ;---------- (CL2 rising edge) out %[data_port], r24 ld r30, X+ swap r24; (CL2 rising edge) out %[data_port], r24 lpm r24, Z ;---------- (CL2 rising edge) out %[data_port], r24 ...
Erforderliche Hardware

Für das Modul F-51543NFU-LW-ADN / PWB51543C-2-V0 hat der Autor Folgendes beantragt:
Arduino auf AVR mit einer Taktfrequenz von 16 MHz (getestet auf Uno, Leonardo und einem Klon ähnlich ProMicro).
Quelle der negativen Spannung. Für den Autor ist dies ein nicht stabilisierter DC-DC-Wandler A0524S-1W mit Eingangs- und Ausgangsisolation. Konverter für den MC34063 sind ebenfalls geeignet (dieser Chip ist sehr leicht zu finden - zerlegen Sie einfach die billigste USB-Aufladung für einen Zigarettenanzünder) oder MAX749. Eine Stabilisierung ist nicht erforderlich, der Bereich der zulässigen Spannungen an diesem Eingang für das hier verwendete Modul ist ziemlich groß. Der Nennwert beträgt minus 24 V, das Maximum beträgt minus 30 relativ zum gemeinsamen Draht und 35 zwischen Vdd und Vee. Die Stromaufnahme beträgt 6 mA.
Zwei N-Kanal-MOS-Transistoren mit Logikpegelsteuerung. Der Autor hat IRL530n verwendet, der Bestand ist natürlich groß, aber er wird sicherlich nicht ausbrennen. Ein Transistor steuert die Hintergrundbeleuchtung, der andere eine negative Spannungsquelle.
250 kΩ Trimmwiderstand zur Spannungsversorgung des Eingangs V0. Stellen Sie den beweglichen Kontakt auf -16,8 V bei einer Temperatur von +25 ° C ein. Dies stammt aus einem Datenblatt, und daher ist eine solche Genauigkeit natürlich nicht erforderlich.
Mehrere 10-Kilo-Widerstände zum Herunterziehen.
Layout und Jumper.
Was würdest du jetzt tun? QR Uhr? Fragen Sie kote:

Kote bietet an, eine Simulation eines gängigen LCD mit einem Controller zu implementieren. Damit ein anderes „Denken“, das mit dem nur großen Display des HD44780 funktioniert, an dieses Arduino angeschlossen werden kann.
Schriftart - auch im RAM
Wir nehmen ein Beispiel mit EGA und VGA - dort wurde im Textmodus genau das getan. Nur hier gab es insgesamt 64 Zeichen, aber im Gegensatz zum Grafikmodus gelangte zumindest alles in den Arbeitsspeicher. Der Hauptzyklus der Ereignisse hat sich zwar verlangsamt, aber Sie können Kachelgrafiken ausprobieren:

Grafikmodus und Halbton
In Arduino auf AVR gibt es nicht so viel RAM, und das ist der Punkt. Auch in Mega. 320x240 sogar mit einem Bit pro Pixel - es sind bereits 9600 Bytes. Nur vier Halbtöne benötigen doppelt so viel. Mit externem RAM, z. B. 23LC512 im SQI-Modus, können Sie versuchen, etwas Ähnliches wie DMA zu implementieren. Es ist jedoch einfacher und rentabler, alles auf ESP32 neu zu erstellen, wo mehr statisches RAM vorhanden ist und DMA einfacher ist.
Wenn Sie ein solches Display nur über USB an einen PC anschließen möchten, können Sie versuchen, ATmega32u4 dafür zu verwenden. Selbst für Helligkeitsabstufungen stehen genügend Ressourcen zur Verfügung (mit FRC, wie in meiner vorherigen Übersetzung beschrieben). Aber nicht mit dem als Schnittstellenkonverter verwendeten „Mega“, sondern mit einem PC, der das LCD selbst im laufenden Betrieb mit einer Geschwindigkeit von 5,4 Megabit pro Sekunde scannt.
Als das Modul noch in der Bandbibliothek stand, gab es eine grafische Benutzeroberfläche und Helligkeitsabstufungen - alles war vorhanden.
Updates werden sein. In der Zwischenzeit ...

Und dies ist keine Fotomontage, sondern das Ergebnis der Steuerung von einem PC aus. Und wir werden von Hackaday.io zu GitHub wechseln - es gibt noch viele interessante Dinge in README.md.
Signale zur Steuerung solcher Module
FLM - First Line Marker - First Line Marker, kann auch als FRAME, VSYNC usw. bezeichnet werden.
CL1 - Zeilenverriegelungsimpuls - Schreibstringimpuls, kann auch aufgerufen werden. LOAD, HSYNC usw.
CL2 - Pixelverschiebungstakt - Pixeländerungsimpuls, kann auch aufgerufen werden. CP (Pixel ändern) usw.
M - Wechselsignal, aufgrund dessen die Pixel durch Wechselspannung gesteuert werden, kann auch als BIAS (Offset) usw. bezeichnet werden.
D0-D3 ist ein paralleler Vier-Bit-Datenbus.
Kabel für Common Wire, Hintergrundbeleuchtung (z. B. VLED ±), Modulleistung (VEE und V0)
Datenblätter nicht vernachlässigen. Das Modul benötigt möglicherweise eine andere negative Spannung oder es kann sich als positiv herausstellen oder der Wandler kann eingebaut sein. Die Logik kann sich beispielsweise unterscheiden, wenn bei einer Einheit auf CL1 keine Reaktion auf CL2 erfolgt. Möglicherweise gibt es eine andere Hintergrundbeleuchtung (CCFL (der Wechselrichter ist ein „Biss“) anstelle von LEDs) oder die Pinbelegung ist nicht auf der Platine angegeben. Ohne Datenblatt ist dies nicht erkennbar. Sie können nichts zufällig verbinden.
Was gibt es zu tun?
Übertragen Sie die Zeichenfolge in Stücken von vier Bits. Die Aufzeichnung erfolgt bei Abnahme auf der Leitung CL2. Nachdem Sie die Zeile passiert haben, schreiben Sie sie in die Rezession der CL1-Zeile (ja, schließlich befindet sich ein wenig RAM im Modul in einer Zeile). Die nächste Zeile wird automatisch ausgewählt. Kehren Sie nach dem Senden des gesamten Frames mit dem FLM-Signal zum Anfang zurück. In einem Datenblatt zu LC79401 gibt es ein Beispiel. Nehmen Sie mit ausreichender Geschwindigkeit auf und legen Sie gleichmäßig Impulse an CL1 an. Der Controller zögerte ein wenig - der Bildschirm blinzelte hässlich.
Ändern Sie nach jedem Frame den Logikpegel am Eingang M in die entgegengesetzte Richtung, so dass die Pixel durch Wechselspannung gesteuert werden. Andernfalls verschlechtert sich die Anzeige:
Sie können dem Mikrocontroller diesen Vorgang nicht anvertrauen, sondern einen zählbaren Auslöser setzen. Der Eintritt in FLM, der Ausgang in M - ist im Allgemeinen verständlich.
Ein Beispiel für die Ausgabe von Bildern aus dem Flash-Speicher (siehe Anfang des Artikels) heißt in diesem Repository clglcd_simple.
Wie bereits erwähnt, ist es unmöglich, dasselbe mit RAM in Arduino auf AVR zu tun - es wird daher nicht ausreichen ...
Und wieder - Textmodus
Laut Datenblatt können Sie Daten auf einem Vier-Bit-Bus übertragen und CL2 mit einer Frequenz von bis zu 6 MHz „ziehen“. Daher können Sie die Leitung schnell und schnell übertragen, dann löst der Mikrocontroller andere Aufgaben ein wenig, und wenn der Timer dies „sagt“, „zieht“ er CL1 und wiederholt den Zyklus.
Bei der Erzeugung von Zeichen für eine horizontale Auflösung von 320 Pixel kann dies alles in 20 μs erfolgen (320 Pixel / 4 Bit = 80 Impulse, CL2 „ziehen“ mit einer Frequenz von 4 MHz). Für die restlichen Aufgaben verbleiben 39,5 μs. CL1 "ruckelt" alle 59,5 μs und erhält eine Bildrate von 70 Hz. Nun, es wird mehr Verfahren zur Behandlung von Unterbrechungen usw. geben. Im Allgemeinen ist der Mikrocontroller in 45% der Fälle damit beschäftigt, die Anzeige zu steuern. "Ganz" 45 oder "Gesamt" 45? Wahrscheinlich das zweite: Das Überschreiben von Daten im Video-RAM kann schnell genug sein.
Möchten Sie, dass der Mikrocontroller weniger Zeit für die Verwaltung des Indikators und mehr für andere Aufgaben benötigt? Sie können die Bildrate auf 50 Hz reduzieren und den Mikrocontroller auf 20 MHz übertakten. Bei jeder dieser Methoden finden mehr Taktzyklen zwischen Interruptroutinen statt.
Ein Ausgangsvergleichstimer schaltet die CL2-Leitung alle vier Taktimpulse mit einem Tastverhältnis von 50%. Gleichzeitig kommen die Daten an den Ausgängen des PORTB-Ports an, der mit dem Vier-Bit-Datenbus des Moduls verbunden ist, so dass ihre Änderung in dem Moment erfolgt, in dem der Pegel auf CL2 ansteigt, und zum Zeitpunkt des Abfalls unverändert bleiben. Dies ist natürlich nicht ohne Assembler möglich:
... lpm r24, Z ;---------- (CL2 rising edge) out %[data_port], r24 ld r30, X+ swap r24; (CL2 rising edge) out %[data_port], r24 lpm r24, Z ;---------- (CL2 rising edge) out %[data_port], r24 ...
8 Zyklen - und vier Knabbereien werden übertragen. Und was genau zu übertragen ist, hängt davon ab, welches Symbol sich in der entsprechenden Video-RAM-Zelle befindet, welche diesem Symbol entsprechenden Pixel vom Zeichengenerator-ROM übertragen werden sollen und was in den entsprechenden Zellen dieses ROM gespeichert ist.
Das Unbequemste dabei ist die Notwendigkeit, den Timer nach genau 80 Impulsen anzuhalten. Einige Timer, wie z. B. Timer4 in 32u4, können dies nicht.
Um das an die CL1-Leitung gelieferte Signal zu erhalten, hat der Autor einen anderen Ausgang des Mikrocontrollers angelegt, der sowohl für den Timer als auch für die schnelle PWM vorgesehen ist. Welche davon hier angewendet wird, ist verständlich. Es wechselt alle 952 Takte. Oder wenn Sie nach dem Taktteiler um 8 zählen, werden alle 119 Impulse ausgegeben. Zu diesem Zeitpunkt startet die Interrupt-Verarbeitungsroutine und zwingt den Mikrocontroller, neue Daten an die Steuerleitung zu senden, die während des nächsten Impulses an CL1 benötigt werden. Nun, der Pegel auf der M-Linie ändert sich mit der halben Frequenz. Und das LCD verschlechtert sich nicht. Alle Signale zusammen sehen folgendermaßen aus:

Der Zeichengenerator besteht aus 256 Zeichen - genug für 866, KOI-8R oder 1251. 40 x N Zeichen werden im Video-RAM abgelegt, wobei N die Anzahl der Zeilen in Abhängigkeit von der Höhe des Zeichens ist. Die Breite des Symbols beträgt immer 8 Pixel, und die Höhe kann 6, 8, 10, 12, 15, 16 betragen. Je kleiner es ist, desto weniger ROM wird für den Zeichengenerator und mehr Video-RAM benötigt. Bei einer 8x8-Schriftart (40 Zeichen pro 30 Zeilen) benötigen Sie 1200 Byte RAM und 2048 Byte ROM. Bei einer 8x16-Schriftart (sieht auf diesem Modul am besten aus) benötigt RAM 600 Byte und ROM 4096. Vom Übersetzer: Sie können die Schriftart in Form von 8x8 speichern und sie per Software zweimal vertikal skalieren und 600 Byte RAM und 2048 ROM kosten. Um mehrere Schriftarten im ROM zu speichern, müssen Sie die Startadresse der Schriftart nicht konstant, sondern in einer Variablen halten. Es funktioniert jedoch nicht, den Text in mehreren Schriftarten gleichzeitig zu drucken, es sei denn, Sie ändern diese Adresse im laufenden Betrieb direkt während der Übertragung von Pixeln auf die Anzeige.
Die Schriftart wird folgendermaßen gespeichert: zuerst die obersten Zeilen aller 256 Zeichen, dann eine Zeile darunter und so weiter. Im Ordner misc des Repositorys befindet sich ein Python-Skript, das die TTF-Schriftart automatisch in die Header-Datei clglcd_font.h mit dem PROGMEM-Array im erforderlichen Format konvertiert. Klassische Pixel-Schriftarten für CC-BY-SA 4.0 finden Sie
hier .
Und noch einmal - nehmen Sie ein Beispiel mit EGA und VGA
Aber diesmal mit Details. Der Zeichengenerator im RAM bietet, wie oben angegeben, insgesamt 64 Zeichen. Sie können durch Zahlen von 0 bis n oder von 255 bis 255 identifiziert werden. Sie werden auf die gleiche Weise gespeichert: die obersten Zeilen aller Zeichen, dann die folgenden und so weiter. Nur all dies wird unter Berücksichtigung der Tatsache ausgerichtet, dass die Zeichen nicht 256, sondern 64 sind. Für Zeichen mit einer Größe von 8 x 16 Pixel sind 16 * 64 = 1024 Bytes erforderlich. Das Repository enthält ein Beispiel für die Arbeit mit dem Zeichengenerator im RAM.
Wenn beide Zeichengeneratoren gleichzeitig verwendet werden - 256 Zeichen im ROM und 64 Zeichen im RAM - müssen Sie akzeptieren, dass nicht nur weniger RAM vorhanden ist, sondern auch die Datenübertragungsgeschwindigkeit der Zeilen im Modul abnimmt. Statt 8 Taktzyklen benötigen zwei Halbbytes 12. Das heißt, nicht 20 Mikrosekunden, sondern 30, und statt 45% der Zeit für die LCD-Steuerung werden 60 benötigt.
Halbton-Grafikmodus
Wie oben angegeben, arbeitet der Mikrocontroller in diesem Fall einfach als Schnittstellenkonverter. Sie benötigen ATmega32u4, und was zu tun ist, wird
hier beschrieben. Bitte beachten Sie, dass das Modul durch das Einfrieren des Programms auf dem PC beschädigt werden kann.
Was ist diese Vierdrahtschleife? Vom Widerstandssensor stellt sich heraus.
Wo verbinden?
Wie oben angegeben, ist eine negative Spannung erforderlich, die in den ersten Experimenten von drei "Crones" entfernt werden kann und dann den Konverter beispielsweise am MAX749 zusammenbaut. Die Leistungssteuersignale sowie das DISPOFF-Signal (dies ist ein inverses Signal, das Modul wird um eins eingeschaltet) ziehen die Widerstände herunter. Während des Flashens und Zurücksetzens des Mikrocontrollers ist das Auftreten logischer Einheiten dort nicht akzeptabel.
Legen Sie eine negative Spannung nach Spannung + 5 V und eine logische Einheit an die DISPOFF-Leitung an, wenn bereits Daten auf den Steuerleitungen vorhanden sind: mindestens eine Einheit auf dem Datenbus, Einheit auf CL1. Andernfalls kann das Modul ausfallen.
Die Eingänge D0-D3 können mit den Ausgängen desselben Ports des Mikrocontrollers verbunden werden, z. B. Px4-Px7, während die Ausgänge Px0-Px3 nicht als GPIO verwendet werden können. Sie können ihnen andere Funktionen zuweisen, z. B. sie als Ausgänge von Timern, seriellen Schnittstellen usw. verwenden. Wenn Sie sie als Eingänge verwenden, seien Sie vorsichtig: Die eingebauten Pull-up-Widerstände können beliebig umschalten, wenn sie nicht deaktiviert sind (PUD - Pull-up-Deaktivierung).
Eingang M - zum Ausgang des Vergleichstimers oder der PWM.
Eingang CL1 - an einen anderen Ausgang desselben Timers.
Eingang CL2 - zum Ausgang eines anderen Vergleichstimers.
FLM - an jeden digitalen Ausgang.
DISPOFF - an jeden anderen digitalen Ausgang.
Der Rest hängt davon ab, wie Sie das Modul einschalten. Der Autor zieht es vor, die Hintergrundbeleuchtung und Vee getrennt zu steuern.
Verwendung der Firmware
Fügen Sie die Dateien clglcd.h und clglcd.cpp in die Skizze ein
Erstellen Sie eine Sicherungskopie der Datei clglcd_config.h und bearbeiten Sie sie unter Berücksichtigung der Verbindung sowie der Funktionen, die Sie benötigen: einen Zeichengenerator im RAM usw. Achtung, der Code gibt nicht die Namen der Arduino-Pins an, sondern die Namen der Mikrocontroller-Pins gemäß Datenblatt. Die Namen der Ausgänge der Vergleichsbändiger werden wie folgt entschlüsselt: Zum Beispiel ist 2, B OC2B, was auf dem Arduino Uno PD3 entspricht. Die Beispiele zeigen die Verbindungsoptionen, die der Autor erworben hat.
Generieren Sie die Schriftartdatei clglcd_font.h mit einem Python-Skript im Ordner misc (siehe oben).
In den Beispielen erfahren Sie, wie Sie die Anzeige initialisieren, ein- und ausschalten. Fügen Sie in das Bildschirmarray den Text ein, den Sie zur Überprüfung anzeigen möchten.
Kompilieren und füllen Sie die Skizze. Überprüfen Sie mit einem Logikanalysator, ob die richtigen Signale auf dem Display angezeigt werden, und mit einem Voltmeter, ob alle Versorgungsspannungen normal sind. Erst dann das Display anschließen.
Fügen Sie der Skizze einen Code hinzu, der etwas bewirkt, z. B. Text an einer seriellen Schnittstelle empfängt und anzeigt.
Unterbrechungen anzeigen
Die Anzeige muss ständig aktualisiert werden, wie dies bei Interrupt-Behandlungsverfahren der Fall ist. Wenn Unterbrechungen länger als 30 Mikrosekunden anhalten, blinkt die Anzeige, und wenn mehr als 60 Mikrosekunden mit einem Gerät auf der FLM-Leitung vergehen, kann dies fehlschlagen. Wenn Sie Interrupts für längere Zeit stoppen müssen, schalten Sie zuerst das Display mit dem DISPOFF-Signal aus (ich wiederhole, dies ist ein inverses Signal, das Modul wird um eins eingeschaltet). Wenn es sich jedes Mal für zwei Sekunden ausschaltet, wenn Sie Daten von einem Feuchtigkeits- und Temperatursensor verarbeiten müssen, wird es natürlich nur wenigen Leuten gefallen, aber es ist besser, als das Modul zu ruinieren. Besser noch, laden Sie den Rest auf einen separaten Mikrocontroller. Der Informationsaustausch durch denselben Mikrocontroller mit Geräten, die mit dem 1-Draht-Protokoll und Adress-LEDs arbeiten, ist besonders inakzeptabel. Arduino Pro Micro-Klone sind günstig genug, um zwei zu kaufen.
Kommunikation
Die durch Hardware implementierten Schnittstellen funktionieren jedoch einwandfrei: serielle Schnittstellen, I
2 C-Bus, SPI im Master-Modus. Im Slave - nur wenn der Master ein periodisches „Roll-Off“ des Slaves um 25-35 μs zulässt. Natürlich hängt es immer noch davon ab, wie viele „Beine“ nach dem Anschließen des Displays nicht besetzt sind.
USB auf 32u4 funktioniert einwandfrei, wenn Sie den Verwaltungsendpunkt nicht zu oft abfragen (langsamer Interrupt-Routinecode). Der CDC-Treiber und seine APIs waren schnell genug.
Dann wird in der Datei README.md auf GitHub die Liste ähnlicher Projekte wiederholt, genau wie auf der Projektseite auf Hackaday.io
Vielen Dank für Ihre Aufmerksamkeit!