Electronic Assembly DIP204- und DIP203-LCD mit BASCOM

Testausgaben EA DIP204-LCD

Richtig handlich sind sie ja, die vierzeiligen LC-Displays von Electronic Assembly, z.B. bei reichelt.de zu haben. Sie kommen ohne ausladende Platinen aus und lassen sich so gut in Frontplatten flacher Gehäuse unterbringen. Soweit die Vorteile. Dafür nimmt man den höheren Preis schon mal in Kauf. Enger wird es aber beim Betrieb unter BASCOM. Voll kompatibel mit dem von BASCOM standardmäßig unterstützten HD44780-Controller sind diese LCD nicht.

Electronic Assembly gibt in [1] die für BASCOM notwendigen Änderungen (einschließlich Schreibfehler) an der Standardkonfigurierung im 4-Bit-Modus an.

Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.5 , Rs = Portb.4
Config Lcdbus = 4
Config Lcd = 20 * 4a , Chipset = Ks077

Die blau gekennzeichnete Zeile ist anders als im Standard (Config Lcd = 20 * 4). Das "4a" stellt die Zeilenadressen richtig ein.
Der RW (Read/Write)-Pin des Displays liegt auf Masse, d.h. das Display empfängt nur Befehle des Controllers (Read-Modus). In den unten gezeigten Routinen LCDWrite bzw. LCDWriteNibble wird dem Display mit den Befehlen waitms eine Millisekunde Zeit zum Lesen und Verarbeiten der Controller-befehle gegeben.
Diese Anweisungen sind sowohl für das inzwischen abgekündigte 5V-LCD EA DIP204-4 (Controller KS0073) als auch für das neue 3,3V-LCD EA DIP203-4 (Controller SSD1803) gültig.

Wenn's mehr nicht ist, dann mal los - für das EA DIP204-4 ...

Zu früh gefreut. Es braucht schon noch etwas mehr, wie sich bei den Versuchen mit dem neuen Antennentuner zeigte. Hier zauberte das Display im Abstand von ca. 30 sec. eine Kopie der ersten, dann der zweiten Zeile in die vierte Zeile. Die Anzeige wurde von Timer-Interrupts für Taster und Drehencoder getriggert. Im Programm wurde die vierte Zeile überhaupt noch nicht angesprochen. Im Internet wurde ich dann fündig: Es ist noch eine spezielle Initialisierung des LCD notwendig, z.B. in [2] liebevoll beschrieben. Die hat es gebracht. Nachfolgend die wesentlichen Codeschnipsel aus der ATU-Software dazu. Wie es eleganter geht, beschreibe ich unten im Nachtrag.

$regfile = "m32def.dat"                           'ATMega32
$crystal = 16000000                               'Crystal 16,0 MHz
$hwstack = 100
$swstack = 100
$framesize = 100

Declare Sub LCDInit
Declare Sub LCDWrite(byVal bytChar As Byte)

'Configure PortB (LCD) ========================================================
'Special 20x4 Text LCD EA DIP204-4 LCD with KS00783 controller
LCD_D4 Alias PortB.3
LCD_D5 Alias PortB.5
LCD_D6 Alias PortB.4
LCD_D7 Alias PortB.2
LCD_E Alias PortB.1
LCD_RS Alias PortB.0
Config Lcdpin = Pin , Db7 = LCD_D7 , Db6 = LCD_D6 , Db5 = LCD_D5 , Db4 = LCD_D4 , E = LCD_E , Rs = LCD_RS
Config Lcdbus = 4
Config Lcd = 20 * 4A , Chipset = KS077

Call LCDInit                                      'Special init for DIP204-LCD
Cls
Cursor Off
Locate 1 , 1
LCD "Hello world ..."
Locate 2, 1
LCD "... hello again ..."
Locate 3, 1
LCD "Nobody answering?"
Locate 4, 1
LCD "Bye bye for now..."

'==============================================================================
Sub LCDInit
   'Special Init for EA DIP204-LCD

   Call LCDWrite(&B00101100)
   Call LCDWrite(&B00001001)
   Call LCDWrite(&B00101000)
   Call LCDWrite(&B00000110)
   Call LCDWrite(&B00001100)

End Sub

'==============================================================================
Sub LCDWrite(byVal bytChar As Byte)
   'Write initialization character bytChar to EA DIP204-LCD

   If bytChar.4 = 1 Then LCD_D4 = 1 Else LCD_D4 = 0       'Set high nibble
   If bytChar.5 = 1 Then LCD_D5 = 1 Else LCD_D5 = 0
   If bytChar.6 = 1 Then LCD_D6 = 1 Else LCD_D6 = 0
   If bytChar.7 = 1 Then LCD_D7 = 1 Else LCD_D7 = 0
   LCD_E = 1                                              'Send high nibble
   Waitms 1
   LCD_E = 0
   Waitms 1

   If bytChar.0 = 1 Then LCD_D4 = 1 Else LCD_D4 = 0       'Set low nibble
   If bytChar.1 = 1 Then LCD_D5 = 1 Else LCD_D5 = 0
   If bytChar.2 = 1 Then LCD_D6 = 1 Else LCD_D6 = 0
   If bytChar.3 = 1 Then LCD_D7 = 1 Else LCD_D7 = 0
   LCD_E = 1                                              'Send low nibble
   Waitms 1
   LCD_E = 0
   Waitms 1

End Sub

End

Die Sub LCDInit ist nicht mit dem BASCOM-Standard "Initlcd" zu verwechseln.

In Sub LCDWrite werden die einzelnen LCD-Eingänge / Controller-Pins angesprochen, z.B. "LCD_D4" = LCD Pin DB4, in "Config LCDPin..." an PortB.3 gelegt. Praktisch ist es, hierfür Alias-Namen zu setzen, z.B. mit " LCD_D4 Alias PortB.3". Anschlussänderungen müssen dann nur noch an einer Stelle, im Alias-Statement, korrigiert werden.

Damit funktionierte das DIP204 wieder wie ein herkömmliches LCD mit Standard-Controller. Exotische ASCII-Zeichen wurden allerdings nicht ausprobiert, siehe dazu [2].

Nachtrag vom 24.04.2018:

Die o.a. Lösung aus dem Web war damals hilfreich bei der raschen Zähmung des widerspenstigen LCD EA DIP204-4. Inzwischen ist mir eine elegantere Lösung eingefallen.

Sub LCDInit
'Special Init for EA DIP204-LCD (KS0073 controller)

   Call LCDWriteInstruction(&B00101100)           'Function set RE=1, 4 bit mode
   Call LCDWriteInstruction(&B00001001)           'Extended function set, 4 lines, 5dot
   Call LCDWriteInstruction(&B00101000)           'Function set RE=0, 4 bit mode
   Call LCDWriteInstruction(&B00000110)           'Entry mode set cursor auto-increment
   Call LCDWriteInstruction(&B00001100)           'Display on, cursor off, blink off

End Sub

Die Funktionsargumente sind die gleichen wie oben. Das Schreiben der 4 Bit-Nibbles für den 4 Bit-Mode geht allerdings viel einfacher.

Sub LCDWriteInstruction(byVal bytLCDChar As Byte)
'Send instruction to 4 bit mode LCD. First high nibble, then low nibble

   Call LCDWriteNibble(bytLCDChar)                'High nibble
   Waitms 1                                       'Wait for LCD to execute
   Shift bytLCDChar , Left , 4                    'Shift low nibble up 4 bits
   Call LCDWriteNibble(bytLCDChar)                'Low nibble is now at high position

End Sub

Im ersten Call werden die obersten 4 Bits (high nibble) aus bytLCDChar extrahiert und auf die LCD-Ports DB4 bis DB7 gelegt. Nach dem Wait zur Ausführung im LCD werden die 4 untersten Bits (low nibble) aus bytLCDChar per Shift nach oben verfrachtet. Der zweite Call legt diese in gleicher Weise auf die LCD-Ports DB4 bis DB7. Die 8 Bit-Instruktion wurde damit mit zwei aufeinander folgenden Nibbles an das LCD gegeben.

Sub LCDWriteNibble(byVal bytLCDChar As Byte)
'Write 4 high bits (high nibble) of byte bytLCDChar to 4 bit mode LCD

   LCD_D4 = bytLCDChar.4                          'LCD port DB4
   LCD_D5 = bytLCDChar.5                          '.
   LCD_D6 = bytLCDChar.6                          '.
   LCD_D7 = bytLCDChar.7                          'LCD port DB7
   LCD_E = 1                                      'Enable, send high nibble
   Waitms 1                                       'Wait for LCD to execute
   LCD_E = 0

End Sub

Freundlicherweise lässt sich mit dieser ursprünglich für das EA DIP204-4 konzipierten Initialisierung auch das EA DIP203-4 dazu überreden, anschließlich wie ein HD44780-Standard-LCD in BASCOM angesprochen zu werden. Ausprobiert am Antennentuner 2017. Falls das wider Erwarten nicht funktionieren sollte, könnten die jeweiligen "Waitms" erhöht werden.
Beispiel für eine Beschaltung im 4 Bit-Modus mit 5V ⇒ 3,3V Levelshifter hier.

Etwas überraschend war es schon, dass die oben gezeigte Initialisierung, zunächst für das EA DIP204-4 vorgesehen, nun auch problemlos beim EA DIP203-4 funktionierte. Zunächst habe ich in der Annahme, hier einen gänzlich anderen LCD-Controller (SSD1803 statt KS0073) vor mir zu haben, den C-Code aus den Electronic Assembly Application Notes [3] nach BASCOM-AVR übersetzt. Der neue Code ging auch, allerdings mit ein paar kleinen Macken:

  • Die Initialisierung war als wirrer Zeichensalat auf dem Display zu sehen.
    Das konnte mit einem  Steuerbefehl zum Ausschalten der Anzeige am Anfang der Prozedur behoben werden.
  • Das BASCOM "Deflcdchar" zur Definition der Zeichen für eine Balkenanzeige (bar graph), OK für das EA DIP204-4, zeigte beim EA DIP203-4 falsche Zeichen an. Mit Ersetzen durch die Zeichencodes nach Datenblatt ließ sich auch das beheben.

Weiter im irrigen Glauben, zwei verschiedene Inits vorhalten zu müssen, wurde dann eine Umschaltung zwischen EA DIP204-4 (Altgeräte) und EA DIP203-4 (neue Generation) vorgesehen. Die offenbarte dann, dass das EA DIP203-4 auch in der Stellung "EA DIP204-4" klaglos seiner Aufgabe nachkam. Eine Weile programmiert für nix, aber wieder was dazu gelernt...

Apropos Zeichensatz im Datenblatt. Für das EA DIP203 und 204 sind im Datenblatt z.B. für das Sonderzeichen "|" (ein senkrechter Strich) angegeben:

  • Upper 4 bit: HHLH.
  • Lower 4 bit: HLHL.

Ergibt zusammen HHLH_HLHL = 1101_1010 = hex DA = dez. 218. Mit dem BASCOM "chr", also
"LCD chr(218)", malt das LCD einen senkrechten Strich "|" für eine Balkenanzeige.

 

Referenzen
[1] http://www.lcd-module.de/FAQs/dip-serie/tmega/-attiny.html
[2] http://crycode.de/avr/allg/30-anschluss-eines-text-lcd
[3] http://www.lcd-module.de/fileadmin/downloads/development%20service/DIP20...

Einordung: