
Bonjour encore, Habr! Ayant
traduit l' article sur la gestion du module LCD avec un pilote, mais sans ma propre RAM vidéo, j'ai décidé de traduire une autre publication sur le même sujet. Ici le module est déjà plus simple, monochrome, mais pour «faire revivre» il n'en est pas moins intéressant.
Contrôle LCD avec pilote, mais sans contrôleur
L'affichage avec lequel l'auteur va travailler provient d'une ancienne bibliothèque de bandes. Le contrôleur n'a pas survécu, mais une recherche de tout ce qui concerne «263645-001» a montré qu'il y avait un FPGA. On pense que contrôler directement ces modules LCD depuis Arduino, etc. impossible, vous avez besoin d'un lien intermédiaire - le contrôleur de la série SEDxxxxx, qui n'est pas «convivial» avec la carte d'expérimentation et qui a plus d'entrées que le module lui-même. Mais ce n'est pas le cas. Voici jusqu'à quatre projets similaires:
Sur l'ATmega8515DessusEn photoSur ESP32Et certains contrôlent généralement les moniteurs AVR VGA 8 bits ...
En général, l'auteur a réussi, le logiciel sous licence MIT est
ici .
Image fixe
Pour vous assurer que tout fonctionne, vous devez d'abord essayer de sortir une image raster à un bit à partir de la mémoire flash du microcontrôleur. Pour obtenir une tension négative, trois «Crones» ont été prélevés, la tension du diviseur, qui a été utilisée comme résistance d'accord, a été appliquée à la borne V0. Et ici sur l'écran est Lenna:

L'auteur ne comprend toujours pas comment il a réussi à retourner l'image (regardez de quel côté se trouve le câble). Dans tous les cas, il y a cet exemple sur la page du projet sur GitHub.
Mode texte
Mais la ROM vidéo est de peu d'utilité, et il n'y a pas 9600 octets pour la RAM vidéo dans l'Arduino. Le mode texte vient à la rescousse, dans lequel la ROM du générateur de caractères et la RAM vidéo combinée sont plus petites que la RAM vidéo en mode graphique. Les partisans de la République du Kazakhstan et le «spécialiste» peuvent briser les lances sans fin sur ce sujet.

Un petit exemple en langage assembleur AVR:
... 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 ...
Matériel requis

Pour le module F-51543NFU-LW-ADN / PWB51543C-2-V0, l'auteur a appliqué:
Arduino sur AVR avec une fréquence d'horloge de 16 MHz (testé sur Uno, Leonardo et un clone similaire à ProMicro).
Source de tension négative. Pour l'auteur, il s'agit d'un convertisseur DC-DC non stabilisé A0524S-1W avec isolation d'entrée et de sortie. Les convertisseurs pour le MC34063 conviennent également (cette puce est très facile à trouver - il suffit de démonter le chargeur USB le moins cher pour un allume-cigare) ou le MAX749. La stabilisation n'est pas requise, la plage de tensions admissibles à cette entrée pour le module utilisé ici est assez large. La valeur nominale est de moins 24 V, le maximum est de moins 30 par rapport au fil commun et de 35 entre Vdd et Vee. La consommation de courant est de 6 mA.
Deux transistors MOS à canal N avec contrôle de niveau logique. L'auteur a utilisé IRL530n, le stock, bien sûr, est grand, mais il ne brûlera certainement pas. Un transistor contrôle le rétro-éclairage, l'autre une source de tension négative.
Résistance de coupure de 250 kΩ pour fournir la tension à l'entrée V0. Réglez de sorte que -16,8 V à une température de +25 ° C sur le contact mobile. Cela provient d'une fiche technique, et donc, bien sûr, une telle précision n'est pas nécessaire.
Plusieurs résistances de 10 kilos pour la descente.
Disposition et cavaliers.
Que feriez-vous maintenant? Montre QR? Demandez à Kote:

Kote propose d'implémenter une simulation de certains LCD courants avec un contrôleur. Pour qu'une autre «réflexion» qui fonctionne avec l'écran du HD44780, seulement grand, puisse être connectée à cet Arduino.
Police - également en RAM
Nous prenons un exemple avec EGA et VGA - là, lorsque vous travaillez en mode texte, c'est exactement ce que vous avez fait. Seulement ici, il y avait 64 caractères au total, mais au moins tout est entré dans la RAM, contrairement au mode graphique. Certes, le cycle principal des événements a ralenti, mais vous pouvez essayer les graphiques en mosaïque:

Mode graphique et demi-teintes
Dans Arduino sur AVR, il n'y a pas tellement de RAM, et c'est le point. Même en Mega. 320x240 même avec un bit par pixel - c'est déjà 9600 octets. Seulement quatre demi-teintes exigeront deux fois plus. Avec la RAM externe, par exemple, 23LC512 en mode SQI, vous pouvez essayer d'implémenter quelque chose de similaire au DMA, mais il est plus simple et plus rentable de tout refaire sur ESP32, où il y a plus de RAM statique et le DMA est plus facile.
Si vous souhaitez simplement connecter un tel écran à un PC via USB, vous pouvez essayer d'utiliser ATmega32u4 pour cela - il y aura suffisamment de ressources même pour les gradations de luminosité (en utilisant FRC, ce que cela est décrit dans ma traduction précédente). Mais pas avec le «méga» utilisé comme convertisseur d'interface, mais avec un PC qui va lui-même scanner l'écran LCD à la volée à une vitesse de 5,4 mégabits par seconde.
Lorsque le module était toujours dans la bibliothèque de bandes, il y avait une interface graphique et des gradations de luminosité - tout était là.
Les mises à jour seront. En attendant ...

Et ce n'est pas un montage photo, mais le résultat d'un contrôle depuis un PC. Et nous passerons de Hackaday.io à GitHub - il y a encore beaucoup de choses intéressantes dans README.md.
Signaux pour contrôler ces modules
FLM - First Line Marker - marqueur de première ligne, peut également être appelé FRAME, VSYNC, etc.
CL1 - Impulsion de verrouillage de ligne - impulsion de chaîne d'écriture, peut également être appelée. CHARGE, HSYNC, etc.
CL2 - Horloge de décalage de pixel - impulsion de changement de pixel, peut également être appelée. CP (changement de pixel), etc.
M - signal alternatif, grâce auquel les pixels sont contrôlés par une tension alternative, peut également être appelé BIAS (offset), etc.
D0-D3 est un bus de données parallèle à quatre bits.
Fils pour fil commun, alimentation du rétroéclairage (par exemple VLED ±), alimentation du module (VEE et V0)
Ne négligez pas les fiches techniques. Le module peut nécessiter une autre tension négative, ou il peut s'avérer positif, ou le convertisseur peut être intégré. La logique peut différer, par exemple, avec une unité sur CL1, il n'y aura pas de réaction sur CL2. Il peut y avoir un rétro-éclairage différent (CCFL (attention, l'onduleur est une "morsure") au lieu des LED), ou il n'y a pas de brochage sur la carte, alors vous ne le saurez pas sans fiche technique. Vous ne pouvez rien connecter au hasard.
Que faire
Transmettez la chaîne en morceaux de quatre bits, l'enregistrement s'effectue sur le déclin sur la ligne CL2. Après avoir passé la ligne, notez la récession sur la ligne CL1 (oui, après tout, un peu de RAM dans le module est sur une seule ligne). La ligne suivante sera sélectionnée automatiquement. Après avoir transmis la trame entière, revenez au début en utilisant le signal FLM. Dans une fiche technique sur LC79401, il y a un exemple. Enregistrez à une vitesse suffisante, appliquez régulièrement des impulsions à CL1. Le contrôleur hésita un peu - l'écran cligna moche.
Après chaque image, changez le niveau logique à l'entrée M à l'opposé, de sorte que les pixels soient contrôlés par une tension alternative. Sinon, l'affichage se détériore:
Vous ne pouvez pas confier cette opération au microcontrôleur, mais mettez un déclencheur dénombrable. L'entrée à FLM, la sortie à M - en général, est compréhensible.
Un exemple de sortie d'images à partir de la mémoire flash (voir le début de l'article) est appelé clglcd_simple dans ce référentiel.
Comme déjà mentionné, il est impossible de faire de même avec la RAM en Arduino sur AVR - ce ne sera donc pas suffisant ...
Et encore - mode texte
Selon la fiche technique, vous pouvez transmettre des données sur un bus à quatre bits et «tirer» CL2 avec une fréquence allant jusqu'à 6 MHz. Par conséquent, vous pouvez rapidement et rapidement transférer la ligne, puis le microcontrôleur résout un peu les autres tâches, et comme le temporisateur le «dit», il «tire» CL1 et répète le cycle.
Lors de la génération de caractères pour une résolution horizontale de 320 pixels, tout cela peut se faire en 20 μs (320 pixels / 4 bits = 80 impulsions, CL2 "pull" avec une fréquence de 4 MHz). Pour les tâches restantes, il reste 39,5 μs. CL1 "jerk" toutes les 59,5 μs et obtenez une fréquence d'images de 70 Hz. Eh bien, il y aura plus de procédures pour gérer les interruptions et ainsi de suite, en général, le microcontrôleur sera occupé à contrôler l'affichage 45% du temps. «Entier» 45 ou «total» 45? Probablement la seconde: l'écrasement des données dans la RAM vidéo peut être assez rapide.
Voulez-vous que le microcontrôleur passe moins de temps à gérer l'indicateur, et plus sur d'autres tâches? Vous pouvez réduire la fréquence d'images à 50 Hz, vous pouvez overclocker le microcontrôleur à 20 MHz. Avec l'une de ces méthodes, davantage de cycles d'horloge auront lieu entre les routines d'interruption.
Un temporisateur de comparaison de sortie commute la ligne CL2 toutes les quatre impulsions d'horloge avec un rapport cyclique de 50%. Dans le même temps, les données vont aux sorties du port PORTB, connectées au bus de données à quatre bits du module de telle manière qu'elles changent au moment où le niveau monte à CL2, et au moment de la baisse elles restent inchangées. Bien sûr, cela ne peut se faire sans assembleur:
... 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 cycles - et quatre grignotages sont transmis. Et quoi transmettre exactement dépend du symbole qui se trouve dans la cellule RAM vidéo correspondante, des pixels correspondant à ce symbole qui doivent être transférés de la ROM du générateur de caractères et de ce qui est stocké dans les cellules correspondantes de cette ROM.
La chose la plus gênante ici est la nécessité d'arrêter la minuterie après exactement 80 impulsions. Certains temporisateurs, comme Timer4 en 32u4, ne le peuvent pas.
Pour obtenir le signal fourni à la ligne CL1, l'auteur a appliqué une sortie différente du microcontrôleur, destinée à la fois au temporisateur et au PWM rapide. Ce qui est appliqué ici est compréhensible. Il commute toutes les 952 mesures. Ou si vous comptez après le diviseur d'horloge par 8 - il se produit toutes les 119 impulsions. À ce stade, le sous-programme de traitement d'interruption démarre et force le microcontrôleur à soumettre à CL1 de nouvelles données qui seront nécessaires lors de la prochaine impulsion. Eh bien, le niveau sur la ligne M change avec la moitié de la fréquence. Et l'écran LCD ne se détériore pas. Tous les signaux ressemblent à ceci:

Le générateur de caractères se compose de 256 caractères - assez pour 866, KOI-8R ou 1251. 40xN caractères sont placés dans la RAM vidéo, où N est le nombre de lignes en fonction de la hauteur du caractère. La largeur du symbole est toujours de 8 pixels et la hauteur peut être de 6, 8, 10, 12, 15, 16. Plus il est petit, moins il faut de ROM pour le générateur de caractères et plus de RAM vidéo. Avec une police 8x8 (40 caractères pour 30 lignes), vous avez besoin de 1200 octets de RAM et 2048 octets de ROM. Avec une police 8x16 (cela semble mieux sur ce module), la RAM a besoin de 600 octets et la ROM 4096. Du traducteur: vous pouvez stocker la police sous la forme 8x8, la redimensionner verticalement deux fois par logiciel et coûter 600 octets de RAM et 2048 ROM. Pour stocker plusieurs polices dans la ROM, vous devez conserver l'adresse de début de police non pas dans une constante, mais dans une variable, mais cela ne fonctionnera pas pour imprimer le texte dans plusieurs polices à la fois, sauf, bien sûr, si vous modifiez cette adresse à la volée par la procédure de traitement d'interruption directement pendant le transfert des pixels à l'écran.
La police est stockée comme ceci: d'abord les premières lignes des 256 caractères, puis une ligne en dessous, etc. Il existe un script Python dans le dossier misc du référentiel, qui convertit automatiquement la police TTF en fichier d'en-tête clglcd_font.h avec le tableau PROGMEM au format requis. Les polices pixel classiques pour CC-BY-SA 4.0 peuvent être trouvées
ici .
Et encore - prenez un exemple avec EGA et VGA
Mais cette fois avec des détails. Le générateur de caractères dans la RAM, comme indiqué ci-dessus, contient un total de 64 caractères, ils peuvent être identifiés par des nombres de 0 à n ou de 255-n à 255. Ils sont stockés de la même manière: les premières lignes de tous les caractères, puis les suivantes, et ainsi de suite. Seul tout cela est aligné en tenant compte du fait que les caractères ne sont pas 256, mais 64. Pour les caractères de taille 8x16 pixels, 16 * 64 = 1024 octets sont requis. Le référentiel a un exemple de travail avec le générateur de caractères en RAM.
Si les deux générateurs de caractères sont utilisés en même temps - 256 caractères en ROM et 64 caractères en RAM, vous devrez accepter que non seulement il y aura moins de RAM, mais aussi que la vitesse de transfert des données des lignes du module diminuera - au lieu de 8 cycles d'horloge, deux quartets auront besoin de 12, c'est-à-dire, non pas 20 microsecondes, mais 30, et au lieu de 45% du temps pour le contrôle LCD, cela prendra 60.
Mode graphique en demi-teintes
Comme indiqué ci-dessus, dans ce cas, le microcontrôleur fonctionne simplement comme un convertisseur d'interface. Vous aurez besoin d'ATmega32u4, et ce qu'il faut faire est décrit
ici . Veuillez noter que le module peut être endommagé en raison du gel du programme sur le PC.
Alors, quelle est cette boucle à quatre fils - à partir du capteur résistif, il s'avère.
Où se connecter
Comme indiqué ci-dessus, une tension négative est requise, qui dans les premières expériences peut être retirée de trois «Crones», puis assembler le convertisseur, par exemple, sur le MAX749. Les signaux de contrôle de puissance, ainsi que le signal DISPOFF (c'est un signal inverse, le module est allumé à un), abaissent les résistances. Lors du flashage et de la réinitialisation du microcontrôleur, l'apparition d'unités logiques y est inacceptable.
Appliquer une tension négative après tension + 5 V et une unité logique à la ligne DISPOFF - lorsque des données sont déjà présentes sur les lignes de contrôle: au moins une unité sur le bus de données, une unité sur CL1. Sinon, le module peut échouer.
Les entrées D0-D3 peuvent être connectées aux sorties du même port du microcontrôleur, par exemple Px4-Px7, tandis que les sorties Px0-Px3 ne peuvent pas être utilisées comme GPIO. Vous pouvez leur affecter d'autres fonctions, par exemple, les utiliser comme sorties de temporisations, interfaces série, etc. Si vous les utilisez comme entrées, soyez prudent: les résistances de pull-up intégrées peuvent commuter arbitrairement si elles ne sont pas désactivées (PUD - pull-up disable).
Entrée M - à la sortie du temporisateur de comparaison ou PWM.
Entrée CL1 - vers une autre sortie du même temporisateur.
Entrée CL2 - à la sortie d'un autre temporisateur de comparaison.
FLM - vers n'importe quelle sortie numérique.
DISPOFF - vers toute autre sortie numérique.
Le reste dépend de la façon dont vous allumez le module. L'auteur préfère contrôler le rétro-éclairage et le Vee séparément.
Comment utiliser le firmware
Placez les fichiers clglcd.h et clglcd.cpp dans l'esquisse
Faites une copie de sauvegarde du fichier clglcd_config.h et éditez-le en tenant compte de ce qui est connecté, ainsi que des fonctions dont vous avez besoin: un générateur de caractères en RAM, etc. Attention, le code n'indique pas les noms des broches Arduino, mais les noms des broches du microcontrôleur selon la fiche technique. Les noms des sorties des dompteurs de comparaison sont déchiffrés comme suit: par exemple, 2, B est OC2B, ce qui sur l'Arduino Uno correspond à PD3. Les exemples montrent les options de connexion obtenues par l'auteur.
Générez le fichier de police clglcd_font.h avec un script Python dans le dossier misc (voir ci-dessus).
Voir dans les exemples comment initialiser, allumer et éteindre l'écran. Mettez dans le tableau d'écran le texte que vous souhaitez afficher pour vérification.
Compilez et remplissez l'esquisse. Vérifiez avec un analyseur logique que les signaux corrects iront à l'écran et avec un voltmètre que toutes les tensions d'alimentation sont normales. Ensuite, connectez l'écran.
Ajoutez un code à l'esquisse qui fera quelque chose, par exemple, recevra du texte sur un port série et l'affichera.
Afficher les interruptions
L'affichage doit être constamment mis à jour, ce que font les procédures de gestion des interruptions. Si les interruptions s'arrêtent pendant plus de 30 microsecondes, l'affichage clignote et si plus de 60 microsecondes pour une unité sur la ligne FLM, il peut échouer. Si vous devez arrêter les interruptions pendant une longue période, éteignez d'abord l'affichage avec le signal DISPOFF (je le répète, c'est un signal inverse, le module est allumé à un). Bien sûr, s'il s'éteint pendant deux secondes à chaque fois que vous avez besoin de traiter les données d'un capteur d'humidité et de température, peu de gens l'aimeront, mais c'est mieux que de ruiner le module. Mieux encore, chargez le reste sur un microcontrôleur séparé. L'échange d'informations par le même microcontrôleur avec des appareils fonctionnant sur le protocole 1 fil et des LED d'adresse est particulièrement inacceptable. Les clones Arduino Pro Micro sont assez peu coûteux pour en acheter deux.
La communication
Mais les interfaces matériellement implémentées fonctionneront parfaitement: ports série, bus I
2 C, SPI en mode maître. Dans l'esclave - uniquement si le maître permet un «roll-off» périodique de l'esclave de 25 à 35 μs. Bien sûr, cela dépend toujours du nombre de «jambes» qui restent inoccupées après avoir connecté l'écran.
L'USB sur 32u4 fonctionne très bien si vous n'interrogez pas trop souvent le point de terminaison de gestion (code de routine d'interruption lente). Le pilote CDC et ses API étaient assez rapides.
Ensuite, dans le fichier README.md sur GitHub, la liste des projets similaires est répétée, la même que sur la page du projet sur Hackaday.io
Merci de votre attention!