Arduino NANO: LCD-Display EAT123A |
|
Schaltungsdiagramm
für das LCD-Display EAT123A am I2C-Bus des NANO-Boards
Das dem EAT123A
beigefügte Datenblatt ist ein miserabler Zusammenschnitt
des Datenblattes für dessen Treiberbaustein PCF 2116. Hier
das Datenblatt der Bausteine PCF 2114 und PCF 2116.
Datenblatt
PCF 2116 .. (EAT123A)
Bemerkungen:
1.
Die Wire-Bibliothek des Arduino NANO arbeitet mit 7Bit
Adressangaben für Slave-Bausteine. So muß die im
Datenblatt des EAT123 angegebene Adresse 0x74 um ein Bit
nach rechts geschoben werden, wodurch aus ihr die Adresse 0x3A
wird.
2.
Das in der Adresse des EAT123 angegebene Datenbit SA0
bezeichnet einen Pin am Treiberbaustein PCF 2116. Auf dieses Bit
wird in der Beschreibung nicht weiter eingegang. Nach der
handschriftlichen Adressangabe des Datenblattes muß dieses
Bit hardwarmäßig auf 0 gelegt sein.
3.
Die Angaben zu den Bits RS und R/W der Tabelle 'Instructions'
müssen vor der Angabe einer bestimmten Funktion aus dieser
Tabelle über ein 'control byte' gesetzt werden. Dieses baut
sich wie folgt auf .. C0, RS, R/W, x xxxx
.. Hierbei besitzt das Bit C0 folgende Bedeutung ..
C0=0 einziges Control-Byte, es folgen nur noch Daten-Bytes
C0=1 die nächsten zwei Bytes sind ein 1. ein Daten-Byte und
2. ein Control-Byte (s.read DDram)
4a
G=1: Aus dem beigefügten Datenblatt geht hervor,
dass das Display an nur einer Spannung (+5V) arbeitet. Aus
dieser Erkenntnis folgt, dass das in der Tabelle 'Instructions'
unter 'Function Set' angegebene Bit G auf 1 gesetzt sein muß,
damit das Display arbeitet. Bei G=0 fällt es aus.
4b.
DL=x: Im I2C-Modus werden grundsätzlich 8 Bit
übertragen. Daraus folgt, dass das unter 'Function Set'
angegebene Bit DL ohne Bedeutung ist.
|
Ausgabe-Programm
für das LCD-Display EAT123A
/*
LCD-Display
EAT123A-I2C
=======================
Die
Anzeige besitzt 3 Zeilen mit je 12 Zeichen, wobei im DDram pro
Zeile 19 Speicher bereitstehen.
Im
Programm erfolgte die Initialisierung als Display mit 4 Zeilen
(N=1, M=1), wobei die 4.Zeile ungenutzt
bleibt.
Beim Aufruf eines der Unterprogramme beginnt die Nummerierung
der Zeilen (z) sowie der Spalten
(s)
mit 1 (innerhalb der Unterprogramme lautet die Nummerierung
0,1,2 ..
*/
#include <Wire.h> // Einbinden der Wire-Bibliothek des Arduino NANO #define I2CadrLCD 0x3A // 7 Bit Basisadresse des EAT123A 0x3A = 011 1010 // oder byte I2CadrLCD = 0x74>>1 String TXTstrg1 = "3x12 Zeichen"; // auszugebende Teststrings String TXTstrg2 = "I2C Bus"; String TXTstrg3 = "2.56mm flach"; // Ausgabetest // die Wartezeiten dienen der Übersicht während der Ausgaben // Dieser Programmteil muß durch eigene Ausgaben ersetzt werden // ------------------------------------------------------------ void ausgabetest () { print_TXT(1,1,TXTstrg1); // TextString 1 ausgeben print_TXT(2,3,TXTstrg2); // TextString 2 ausgeben print_TXT(3,1,TXTstrg3); // TextString 3 ausgeben delay (2000); // 2 Sekunden warten clr_line(3); // Zeile 3 löschen clr_line(2); // Zeile 2 löschen delay (2000); // 2 Sekunden warten print_TXT(3,2,"Display"); // angegebenen Text in Zeile 3 ausgeben delay (2000); // 2 Sekunden warten print_TXT(3,9,"OK"); // zusätzlichen Text in Zeile 3 ausgeben delay (2000); // 2 Sekunden warten cursor_on (0); // Cursor ausschalten // ------------------------------------------- // Test, den DDram auslesen Serial.begin (9600); // .. nur für die Textausgabe bei read_DDram() delay (2000); // .. 2 Sekunden warten read_DDram (3); // .. z.B. Zeile 3 im DDram lesen // Ende des Programms nach einmaligem Durchlauf } // ====================================================================================================== // einmalig, die Startbedingungen des Programms einstellen void setup () { Wire.begin (); // Initialisierung der Wire-Bibliothek Wire.setClock (100000L); // I2C- Bus mit 100kHz init_LCD (); // Anzeige einrichten clear_display (); // Anzeige löschen ausgabetest (); // Aufruf des obigen Testprogramms } // wird die Funktion loop() entfernt, erscheint der Fehler: // Fehler beim Kompilieren für das Board Arduino Nano // -------------------------------------------------------- void loop() { // nix } // LCD Konfigurationsregister setzen // --------------------------------- void init_LCD () { Wire.beginTransmission (I2CadrLCD); Wire.write (0x00); // Kontrollbyte senden C0=0, RS=0, R/W=0, x xxxx Wire.write (0x2E); // Function Set: 0 0 1 DL=x N=1, M=1, G=1, 0 => 0x2E Wire.write (0x0F); // Display control: 0 0 0 0 - 1 D=1, C=1, B=1 => 0x0F Wire.write (0x06); // Entry mode set: 0 0 0 0 - 0 1 I/D=0, S=1 => 0x06 Wire.write (0x01); // Clear Display: 0 0 0 0 - 0 0 0 1 => 0x01 Wire.endTransmission (); delay (20); } // Anzeige löschen, DDram auf Adresse 0 // (Cursor auf Position z=1, s=1) // ------------------------------------ void clear_display () { Wire.beginTransmission (I2CadrLCD); Wire.write (0x00); // Kontrollbyte senden C0=0, RS=0, R/W=0, x xxxx Wire.write (0x02); // Return Home: 0 0 0 0 - 0 0 1 0 => 0x02 Wire.endTransmission (); } // Text ausgeben // Der Text wird in Zeile (z) und Spalte (s) ausgegeben // ---------------------------------------------------- void print_TXT (byte z, byte s, String TXTstrg) { set_DDram (z,s); // Ausgabeposition im DDram setzen byte tl = 12-s+1; // Textlänge (tl) = 12 Ausgabestellen - eingerückte Spalten if (TXTstrg.length() < tl) tl=TXTstrg.length(); // Ausgabetext ist kürzer als auszugebende Textlänge Wire.beginTransmission (I2CadrLCD); Wire.write (0x40); // Kontrollbyte senden C0=0, RS=1, R/W=0, x xxxx for (int b=0; b < tl; b++) { Wire.write (0x80 + TXTstrg[b]); // .. tl Zeichen des 0x80 Zeichensatzes ausgeben } Wire.endTransmission (); } // setzt die Ausgabeposition zeile= 1-3 und spalte= 1-12 im DDram // Im Programm beginnen die Zeilen und Spalten mit 0, 1, 2 .. // ungültige Werte werden ignoriert // -------------------------------------------------------------- void set_DDram (byte z,byte s) { byte pos; z=z-1; s=s-1; // 1,2,3 .. zurücksetzen auf 0,1,2 .. if (z>2 || s>11) return; // angegebene Zeile größer 2, Spalte gößer 11 Wire.beginTransmission (I2CadrLCD); Wire.write (0x00); // Kontrollbyte senden C0=0, RS=0, R/W=0, x xxxx if (z == 0) pos= 0x00+s; // Anfangsadresse Zeile 1 + Spalte if (z == 1) pos= 0x20+s; // Anfangsadresse Zeile 2 + Spalte if (z == 2) pos= 0x40+s; // Anfangsadresse Zeile 3 + Spalte Wire.write (0x80+pos); // DDram Adresse setzen: 1aaa aaaa Wire.endTransmission (); } // löscht die Zeile 1,2 od.3 mit Spaces // ungültige Zeilenangaben werden ignoriert // ------------------------------------------ void clr_line (byte z) { byte pos; z=z-1; if (z>2) return; Wire.beginTransmission (I2CadrLCD); Wire.write (0x00); // Kontrollbyte senden C0=0, RS=0, R/W=0, x xxxx if (z == 0) pos= 0x00; // Anfangsadressen der Zeilen im DDram if (z == 1) pos= 0x20; if (z == 2) pos= 0x40; Wire.write (0x80+pos); // Set DDram Adresse 1aaa aaaa Wire.endTransmission (); Wire.beginTransmission (I2CadrLCD); Wire.write (0x40); // Kontrollbyte senden C0=0, RS=1, R/W=0, x xxxx for (int b=0; b < 12; b++){ Wire.write (B10100000); // .. 12 x Space in Zeile ausgebn } Wire.endTransmission (); } // Cursor ausschalten on=0 / einschalten on=1 // ------------------------------------------ void cursor_on (byte on) { if (on == 0) on = 0x0E; // Display control: 0 0 0 0 - 1 D=1, C=1, B=0 => 0x0E else on = 0x0F; // Display control: 0 0 0 0 - 1 D=1, C=1, B=1 => 0x0F Wire.beginTransmission (I2CadrLCD); Wire.write (0x00); // Kontrollbyte senden C0=0, RS=0, R/W=0, x xxxx Wire.write (on); // Cursor aus oder ein Wire.endTransmission (); } // ====================================================================================================== // Diese Programmteile dürften für den Betrieb des LCD-Displays EAT123A von untergeodneter Bedeutung // sein, da die Anzeige nur 3 Zeilen und je 12 Zeichen besitzt. Sie können als Test für die Benutzung // des Bits C0 aufgefasst werden, sowie als Anhalt für den Befehl 'Wire.requestFrom(..)' // Damit die Ausgaben auf dem seriellen Monitor der Entwicklungsumgebung funktioniert muß vor dem // Aufruf von 'read_DDrami() die Zeile Serial.begin (9600); eingefügt sein. // das Busy-Flag (BF) lesen // die Schleife wird durchlaufen, solange das BF=1 ist. // die Rückgabe ist der Wert des Address-Counters // ---------------------------------------------------- byte readBF() { byte BF; Wire.beginTransmission (I2CadrLCD); Wire.write (0x20); // Kontrollbyte senden C0=0, RS=0, R/W=1, x xxxx do{ Wire.requestFrom(I2CadrLCD,1); // Schleife solange durchlaufen, bis das Bit DB7, BF = Wire.read(); // das Busy-Flag 0 ist } while(BF>>7 == 1); Wire.endTransmission (); return BF; // dann den Wert des address-counters zurückgeben } // liest den Inhalt der Zeile z des DDram // jede der Zeilen 1-3 besteht aus 20 Zeichen // von denen nur 12 angezeigt werden. // ------------------------------------------ void read_DDram(byte z) { byte pos; z=z-1; if (z == 0) pos= 0x00; // Anfangsadressen der Zeilen im DDram if (z == 1) pos= 0x20; if (z == 2) pos= 0x40; byte anz=20; // max.Anzahl der zu lesenden Bytes einer Zeile byte value[anz]; // Array für die gelesenen Werte char x=0; Wire.beginTransmission (I2CadrLCD); Wire.write (0x80); // Kontrollbyte senden C0=1, RS=0, R/W=0, x xxxx Wire.write (0x80+pos); // .. DDram-Adresse ab der gelesen werden soll Wire.write (0x60); // Kontrollbyte senden C0=0, RS=1, R/W=1, x xxxx Wire.endTransmission (); Wire.beginTransmission (I2CadrLCD); Wire.requestFrom (I2CadrLCD,anz); for (byte n= 0; n<anz; n++) { value[n] = Wire.read(); } Wire.endTransmission (); // --------------------------------------------------------------------------------------------------- // Ausgabe der gelesenen Werte auf dem seriellen Monitor Serial.print ("Zeile: "); Serial.println (z+1); // .. die Zeile for (byte n=0; n<anz; n++){ Serial.print ("Adresse: 0x"); Serial.print (n,HEX); // .. die Adresse des DDram Serial.print (" - Inhalt: 0x"); Serial.print (value[n],HEX); // .. deren Inhalt hexadezimal Serial.print (" - ASCII: "); if (value[n] == 0xA0) Serial.println("spc"); else {x = value[n]-128; Serial.println (x); // .. deren Inhalt als ASCII-Zeichen } } } |