GLCD
PowerLED
Der heiße Draht

Tutorial zum Ansteuern eines Grafikdisplays EW12A03GLY mit einem Atmel ATMega16

Von Grünewald, Harry
Info@HarryGr.de
Beschreibung

Grundlagen GLCD

Das Board

Die Software des Atmel

Die Software des PC

Download

Beschreibung

Es handelt sich hier um ein Tutorial zur Ansteuerung eines Grafik-LCD mit Hilfe eines Mikrocontrollers ATMega16.
Es wird ein Bild aus dem EEProm in einen Puffer geladen und dann auf das Display ausgegeben.
Die dafür entwickelte Platine enthält das Display, den Atmel, eine Spannungsversorgung, ein ISP-Interface, ein I2C-Interface und einige Taster.
Die Software wird in Assembler geschrieben und kann per ISP jederzeit geändert werden. Geplant ist, in einem erweiterten Tutorial, die Ansteuerung per I2C-Bus und die Implementierung der Taster zum Zeichnen eigener Bilder direkt auf dem Display sowie einer Textausgabe.

Grundlagen GLCD

Das Grafikdisplay EW12A03GLY von "Emerging Display" hat eine Auflösung von 122*32 Pixel. Diese werden von 2 Controller SED1520 angesteuert, welche sich die linke und die rechte Displayhälfte teilen. Jeder Controller bedient damit ein Feld von 61*32 Pixel. Die Daten werden dem Controller in 8-Bit breite Blöcke übergeben. Dieses Byte wird senkrecht auf dem Display ausgegeben, wobei das LSB oben liegt. Bei einer Display-Höhe von 32 Pixel ergeben sich vier "Zeilen", die so genannten Pages. Wenn man also den obersten linken Pixel setzen möchte, muss man ein Byte 0b00000001 an Page 0 und Spalte 0 des linken Controllers senden. Dabei werden immer auch die sieben darunter liegenden Pixel definiert. In unserem Beispiel zurückgesetzt. Wenn man also eine horizontale Linie zeichnen möchte, ohne dabei den Rest des Bildes zu verändern, muss man wissen was in den betroffenen Page-Spalten dargestellt wird, um diese Daten unverändert wieder zu senden. Da man bei diesem Display keine Daten auslesen kann, muss ein Bildpuffer im ATMega16 umgesetzt werden, in dem das dargestellte Bild 1:1 gespeichert ist.

Das Board

Allgemein

Auf dem Board sind alle für den Betrieb nötigen Komponenten enthalten. Das gesamte Board ist möglichst flexibel gehalten. So ist es möglich diverse Leuchtdioden, Widerstände und Kondensatoren in SMD- oder in Print-Technik auszuführen. Die Spannungsversorgung wird mit einem L200 realisiert. Dies ist ein einstellbarer Festspannungsregler, welcher uns die gewünschten 5V Betriebsspannung liefern wird. Man könnte auch einen anderen fest eingestellten Festspannungsregler verwenden, nur hatte ich den L200 gerade vorrätig und ich befand es für eine gute Gelegenheit ihn mal vorzustellen. Die Taster sowie die I2C-Schnittstelle werden in diesem Tutorial nicht verwendet und können weg gelassen werden. Auch der Reset-Taster ist nicht zwingend notwendig.

Stückliste

   
 SMD  Print  Wert  Beschreibung  Einheit
   X3  7-12V  Spannungsversorgung  
   LCD1    Grafik-LCD  
   R4  20k  Kontrasteinstellung  
   R2  680Ω    Festspannung
   R3  820Ω    Festspannung
   IC4  L200    Festspannung
   C1  470μF/50V    Gleichrichtung
   C2  100nF/50V    
   B1    Brückengleichrichtung  Gleichrichtung
 LED2  LED1    Betriebsspannung  
 R5  R11    Vorwiderstand LED  
   IC1  ATMega16    
 C5/C6  C3/C4  100nF    
   S6    Reset  
 R9/R10  R7/R8    Pullup  I2C
   X1/X2      I2C
 R1  R6  12Ω  Vorwiderstand Bel.  
   S1..S5    Taster  
   K1    ISP  

Die Anschlüsse

X3
X3 ist der Anschluss für die Spannungsversorgung. Die Eingangsspannung darf zwischen 7 über 12 Volt liegen. Ob Wechsel- oder Gleichspannung und die Polarität ist bei voller Beschaltung egal. Wer nur mit Gleichspannung arbeiten möchte kann den Brückengleichrichter B1 und den Glättungskondensator C1 weg lassen und entsprechend überbrücken. Dann ist aber besonders auf die Polarität zu achten, denn eine verpolter L200 ist ein toter L200
K1
Die ISP-Schnittstelle wird benötigt um den ATMega16 zu programmieren. Die Pinbelegung ist identisch mit der Pinbelegung des "ISP10PIN" auf dem Entwicklungsboard STK500 von Atmel.
Das STK500 und das GLCD-Board können also mit einem einfachen 10-adriges Flachkabel verbunden werden. Da der Festspannungsregler vom STK500 nicht rückgespeist werden darf, ist der Jumper "VTARGET" (des STK500) zu öffnen.
X1 / X2
Das I²C-Interface wird in diesem Tutorial nicht behandelt und kann zusammen mit R7 - R10 entfallen.

Schaltplan

Der Schaltplan wurde mit EAGLE von CadSoft entworfen und steht als *.sch zum download bereit.

Layout

Auch das Layout wurde mit EAGLE von Cadsoft entworfen. Es steht als *.jpg und als *.brd zum download bereit.

EAGLE - Bibliotheken

Einige Bauteile wurden von mir selbst entworfen, darunter auch das Display und die ISP-Schnitstelle. Die entsprechenden Bibliotheken liegen wie immer zum download bereit. Sollten noch weitere Bauteile fehlen schreibt mir einfach eine Mail an Info@HarryGr.de!

Hinweise

  • Das Display hat 4 Halblöcher zur Befestigung. Ursprünglich wollte ich mit M2-Abstandshaltern arbeiten, doch da diese sehr schwer in Kleinstmengen zu bekommen sind, schwebt mein Display noch immer einfach frei herum.
  • Der Festspannungsregler sollte gekühlt werden. Bei 12V stellen sich rechnerisch 95°C ein, was noch im Rahmen wäre aber doch schon sehr weh tun kann.

Die Software des Atmel

Das Display soll einen wieder verwendbaren Code bekommen und wird deshalb in einer separaten Datei gekapselt. Alle Befehle und Variablen bekommen den Suffix LCD_. Um sicher zu stellen das keine anderen Programmteile beeinträchtig werden, wird von allen verwendeten Variablen der Speicher auf den Stack gelegt, um sie, nach Beenden der Funktion, wieder herstellen zu können. Um Befehle an das Display zu senden, legt man HIGH an Pin A0, danach gibt man das Byte des Befehls am Datenport aus und zieht E1 und E2 kurz auf Masse. Das Datenbyte wird in unserem Fall im Register Temp erwartet.

LCDctrlout:
     cbi   LCD_cntr,A0
     out   LCD_data,Temp
     cbi   LCD_cntr,E1
     cbi   LCD_cntr,E2
     sbi   LCD_cntr,E1
     sbi   LCD_cntr,E2
ret

Daten werden auf ähnliche Weise gesendet. Der Unterschied ist nur, dass man vorher A0 setzten muss und dann nur eine Displayhälfte abspricht.

LCDdata1out:
     sbi   LCD_cntr,A0
     out   LCD_data,Temp
     cbi   LCD_cntr,E1
     sbi   LCD_cntr,E1
ret

LCDdata2out:
     sbi   LCD_cntr,A0
     out   LCD_data,Temp
     cbi   LCD_cntr,E2
     sbi   LCD_cntr,E2
ret

Das Display muss, bevor es verwendet werden kann, initialisiert werden. Dies geschieht durch den LCD_RESET-Befehl. Obwohl danach eine ganze Menge Einstellungen auf Standartwerte gesetzt sein sollten, wird immer wieder empfohlen alle Parameter zu initialisieren.

LCD_Startup:
     push  Temp
     rcall LCD_Portinit

     ldi   temp,LCD_RESET
     rcall LCDctrlout

     ldi   temp,LCD_SET_ADR
     rcall LCDctrlout

     ldi   temp,LCD_ADC+LCD_ADC_CW
     rcall LCDctrlout

     ldi   temp,LCD_DUTY +1
     rcall LCDctrlout

     ldi   temp,LCD_END
     rcall LCDctrlout

     ldi   temp,LCD_ON
     rcall LCDctrlout

     rcall LCD_Clear
     pop   temp
ret

Da man bei diesem Display keine Daten auslesen kann, muss ein Bildpuffer im ATMega16 umgesetzt werden, in dem das dargestellte Bild 1:1 gespeichert ist. Da das Display 122x32 Pixel hat, brauchen wir 488 Bytes Speicher. Dieser Speicher muss nicht remanent sein und könnte unter Umständen sehr oft beschrieben und gelesen werden. Deshalb wählen wir den SRAM des Controllers. Aus Kompatibilitätsgründen beginnen wir unseren Bildpuffer bei 0x0100. Er endet demnach bei 0x02E7. Der Speicher wird in vier Zeilen geteilt, ähnlich wie die Pages des Displays.

Mit LCD_Clear werden der Buffer und das Display sicher gelöscht, da sich anderenfalls noch Datenmüll im RAM des Displays und des Controllers befinden könnte.

LCD_Clear:
     push  Temp
     push  Temp2
     clr   Temp2     ;Leer für den Speicher

     ldi   ZH,HIGH(LCD_Zeile1)
     ldi   ZL,LOW(LCD_Zeile1)
     ldi   Temp,122     ;Counter

     st    Z+,Temp2
     dec   Temp
     brne  PC-2

     ldi   ZH,HIGH(LCD_Zeile2)
     ldi   ZL,LOW(LCD_Zeile2)
     ldi   Temp,122     ;Counter

     st    Z+,Temp2
     dec   Temp
     brne  PC-2

     ldi   ZH,HIGH(LCD_Zeile3)
     ldi   ZL,LOW(LCD_Zeile3)
     ldi   Temp,122     ;Counter

     st    Z+,Temp2
     dec   Temp
     brne  PC-2

     ldi   ZH,HIGH(LCD_Zeile4)
     ldi   ZL,LOW(LCD_Zeile4)
     ldi   Temp,122     ;Counter

     st    Z+,Temp2
     dec   Temp
     brne  PC-2

     pop   Temp2
     pop   Temp

     rcall LCD_Ausgeben     ;Leeren RAM auf das Display ausgeben
ret

Mit LCD_Ausgeben wird der gesamte Bildpuffer auf das Display ausgegeben.

LCD_Ausgeben:
     push  Temp
     push  Temp2

     ldi   temp,LCD_PAGE + 0     ;Zeile 1 des LCD
     rcall LCDctrlout
     ldi   temp,LCD_SET_ADR     ;erstes Zeichen
     rcall LCDctrlout
     ldi   XH,HIGH(LCD_Zeile2)     ;Zeile 1 im SRAM
     ldi   XL,LOW(LCD_Zeile2)     ;(es wird Rückwärts gezählt!)

     ldi   Temp2,61     ;Counter

     ld    Temp,-X     ;Zeile 1 Rechts ausgeben
     rcall LCDdata2out
     dec   Temp2
     brne  PC-3

     ldi   Temp2,61     ;Counter

     ld    Temp,-X     ;Zeile 1 Links ausgeben
     rcall LCDdata1out
     dec   Temp2
     brne  PC-3

     ldi   temp,LCD_PAGE + 1
     rcall LCDctrlout
     ldi   temp,LCD_SET_ADR
     rcall LCDctrlout
     ldi   XH,HIGH(LCD_Zeile3)
     ldi   XL,LOW(LCD_Zeile3)

     ldi   Temp2,61     ;Counter

     ld    Temp,-X     ;Zeile 2 Rechts
     rcall LCDdata2out
     dec   Temp2
     brne  PC-3

     ldi   Temp2,61     ;Counter

     ld    Temp,-X     ;Zeile 2 Links
     rcall LCDdata1out
     dec   Temp2
     brne  PC-3

     ldi   temp,LCD_PAGE + 2
     rcall LCDctrlout
     ldi   temp,LCD_SET_ADR
     rcall LCDctrlout
     ldi   XH,HIGH(LCD_Zeile4)
     ldi   XL,LOW(LCD_Zeile4)

     ldi   Temp2,61     ;Counter

     ld    Temp,-X     ;Zeile 3 Rechts
     rcall LCDdata2out
     dec   Temp2
     brne  PC-3

     ldi   Temp2,61     ;Counter

     ld    Temp,-X     ;Zeile 3 Links
     rcall LCDdata1out
     dec   Temp2
     brne  PC-3

     ldi   temp,LCD_PAGE + 3
     rcall LCDctrlout
     ldi   temp,LCD_SET_ADR
     rcall LCDctrlout
     ldi   XH,HIGH(LCD_NachBuffer)
     ldi   XL,LOW(LCD_NachBuffer)

     ldi   Temp2,61     ;Counter

     ld    Temp,-X     ;Zeile 4 Rechts
     rcall LCDdata2out
     dec   Temp2
     brne  PC-3

     ldi   Temp2,61     ;Counter

     ld    Temp,-X     ;Zeile 4 Links
     rcall LCDdata1out
     dec   Temp2
     brne  PC-3

     pop   Temp2
     pop   Temp
ret

Zu guter Letzt eine Funktion die den SRAM füllt, und zwar mit Daten aus dem EEProm. Man hätte die Daten auch direkt aus dem EEProm auf das Display ausgeben können, doch um späteren Funktionen eine brauchbare Basis zu liefern, puffern wir das Bild. Im EEProm sind die Daten genau so arrangiert wie im SRAM, können also 1:1 übernommen werden. Das Bild beginnt bei 0x00.

LCD_vom_EEPROM:
     push  Temp
     push  Temp2
     push  r19
     push  r20
     push  r21
     clr   r20
     clr   r19

     ldi   ZH,HIGH(LCD_Zeile1)
     ldi   ZL,LOW(LCD_Zeile1)
     ldi   Temp2,122     ;Counter

     rcall EEPROM_read
     st    Z+,Temp
     ldi   r21,1
     clr   Temp
     add   r19,r21
     adc   r20,Temp
     dec   Temp2
     brne  PC-7

     ldi   ZH,HIGH(LCD_Zeile2)
     ldi   ZL,LOW(LCD_Zeile2)
     ldi   Temp2,122     ;Counter

     rcall EEPROM_read
     st    Z+,Temp
     ldi   r21,1
     clr   Temp
     add   r19,r21
     adc   r20,Temp
     dec   Temp2
     brne  PC-7

     ldi   ZH,HIGH(LCD_Zeile3)
     ldi   ZL,LOW(LCD_Zeile3)
     ldi   Temp2,122     ;Counter

     rcall EEPROM_read
     st    Z+,Temp
     ldi   r21,1
     clr   Temp
     add   r19,r21
     adc   r20,Temp
     dec   Temp2
     brne  PC-7

     ldi   ZH,HIGH(LCD_Zeile4)
     ldi   ZL,LOW(LCD_Zeile4)
     ldi   Temp2,122     ;Counter

     rcall EEPROM_read
     st    Z+,Temp
     ldi   r21,1
     clr   Temp
     add   r19,r21
     adc   r20,Temp
     dec   Temp2
     brne  PC-7

     pop   r21
     pop   r20
     pop   r19
     pop   Temp2
     pop   Temp
     rcall LCD_Ausgeben
ret

Die Software des PC

Es werden mehrere Programme auf dem PC benötigt:

  • Grafikprogramm
    um ein Bild zu erstellen, welches auf dem Display ausgegeben wird
  • Programmer und Flasher
    um den Quellcode zu bearbeiten und auf den Atmel zu übertragen
  • Konverter
    um das Bild in ein Format zu wandeln, welches sich in den EEProm laden lässt
  • Optional das CAD-Programm EAGLE von CadSoft

Grafikprogramm

Es können so ziemlich alle erhältlichen Grafikprogramme verwendet werden, sogar das hypergeile "MS Paint". Wichtig ist nur, dass man eine Bitmap (BMP) mit einer Auflösung von 122*32 Pixel und 1 Bit Farbtiefe speichern kann.

Konverter

Der Konverter wird benötigt um das Bild so zu übersetzten dass es der EEProm aufnehmen kann. Bei dem Entwicklungsboard STK500 von Atmel wird die Programmiersoftware "AVR-Studio" mitgeliefert welche die Flash-Software "STK500" beinhaltet. Mit ihr können textbasierte *.Hex-Files in den EEProm übertragen werden, welche eine spezielle Anordnung der Daten zwischen Adressen und Prüfsummen erwartet. Um solch ein Hex-File zu erzeugen wurde ein spezieller Konverter programmiert, welcher im Zuge dieses Tutorials zur Verfügung gestellt wird.

Programmer

Ich verwende das AVR-Studio von Atmel. Da ich keine Erfahrung mit anderen Programmern habe, kann ich auch nicht sagen ob andere verwendet werden können. Auf jeden Fall wird hier in Assembler programmiert.

Flasher

Auch hier benutze ich das original STK500 von Atmel. Und auch hier möchte bitte jeder selber prüfen ob sein Flasher meine Daten übertragen kann. Insbesondere das File welches das Bild enthält sollte auf Kompatibilität geprüft werden.
Das Board wird per "In-System Programming" geflasht. Das heißt, dass der Atmel im Board (also im System) sitzen bleiben kann, während er geflasht wird. Der Atmel soll mit 8MHz internem RC-Takt laufen. Dies wird per Fuse-Bits eingestellt und kann nur außerhalb des Systems geschehen, denn vom LCD-Board erhält er keinen Takt und wenn er auf einen externen Takt eingestellt ist macht er schlichtweg gar nichts.

Download

Das auf www.HarryGr.de zur Verfügung gestellte ZIP-File enthält folgende Teile:
  • ASM
    Assembler-Code und Hexfile, welche das Programm enthalten
  • EAGLE
    Der Schaltplan, das Layout, ein Bild vom Layout und ein paar Bibliotheken
  • Konverter
    Ein kleines, sehr einfaches Programm zum umwandeln eines Bildes in ein Hex-File, ein Bild sowie das bereits gewandelte Bild

Home
Kontakt
Elektronik
Software
Bilder
Modellbau
Gästebuch
Alle Rechte vorbehalten.