Atmel AVR Mikrocontroller mit OpenSuse: Ansteuerung vonLCD-Displays

LCD-Displays gibt es in großer Mannigfaltigkeit. Üblich ist, dass die Displays bereits einen Controller enthalten, der die Pixel ansteuert. Auch in diesem Bereich hat eine Art Standardisierung stattgefunden, so dass nur gegen wenige Controllertypen programmiert werden muss. Ein sehr gebräuchlicher Controller ist der HD44780.

LCD-Display Seiko L2432 mit 2 Zeilen zu 24 Zeichen

Auf dem Display sitzt ein Controller HD44780, also absoluter „Standard“.
Das Display hat 2 Zeilen zu 24 Zeichen.


Vorderseite des Seiko L2432.

Unterseite des Seiko L2432, rechts der Controller HD44780. Ganz rechts der 14-polige Konnektor, an den ein Flachbandkabel angelötet wurde.

Das Display wird über einen Connector mit 14 Pins angeschlossen. Sogar die Pin-Belegung des Connectors ist quasi-standardisiert.

Pin Function
1 GND
2 V+, normalerweise +5V
3 VLC, Kontrastreglung
4 RS – Register Set
5 RW – Read/Write
6 E – Enable
7 DB0
8 DB1
9 DB2
10 DB3
11 DB4
12 DB5
13 DB6
14 DB7
15 (A – Anode for Backlight) optional
16 (K – Kathode for Backlight) optional

In Rot sind die für die 4-Bit-Ansteuerung notwendigen Pins gekennzeichnet. Diese müssen mit freien Ports des AVRs (bzw. V+ und GND) verbunden werden.

Neben der Datenleitungen (8 Datenbits D0..D7 bzw. 4 Datenbits D4..D7 im 4-Bit-Modus, Controllerauswahl, R/W, RS, Enable sowie GND und Vcc), muss unbedingt auch -wenn vorhanden- die Kontrastregelung angeschlossen werden. Das gezeigte Display benötigt beispielsweise eine Spannung, die irgendwo zwischen 0 und 5V liegt. Wird keine passende Regelspannung für den Kontrast eingestellt, ist absolut nichts zu sehen und man kann nicht erkennen, ob das Display überhaupt funktioniert! Die Kontrastspannung wird über einen Trimmer angeschlossen von typischerweise 10 KOhm, so dass man auf unterschiedliche Lichtverhältnisse reagieren kann.

Als Open Source gibt es eine Bibliothek für den AVR-Controller (LCD Library von Peter Fleury), welche LCDs ansteuern kann. Sie nutzt die 4-Bit-Ansteuerung (oder einen Memory-Mapped-Mode, der bei bestimmten AVRs möglich ist). Je nach Controller wird ein 8-Bit-Modus, ein 4-Bit-Modus oder beides unterstützt. Der 4-Bit-Modus hat den Vorteil, dass am AVR weniger Pins benötigt werden.

Hinweis: Im 4-Bit-Modus werden die Datenleitungen D4..D7 eines LCD-Moduls/Controllers genutzt. Auch wenn in der Peter-Fleury-Bibliothek immer von D0..D3 (=die logischen Datenleitungen des 4-Bit-Modes) die Rede ist, gemeint sind im 4-Bit-Modus immer D4..D7 (=die physikalischen Datenleitungen des LCD-Moduls).

Im folgenden ist die Nutzung der Funktionen dargestellt (Codeauszug, kompletten Source Code gibts weiter unten):

...
#include "lcd.h"
 
...
/* clear display and home cursor */
lcd_clrscr();
 
/* put string to display (line 1) with linefeed */
lcd_puts("LCD Test Line 1n");
 
/* cursor is now on second line, write second line */
lcd_puts("Line 2");
 
/* move cursor to position 8 on line 2 */
lcd_gotoxy(7,1);
 
/* write single char to display */
lcd_putc(':');
 
DO("wait for keynr");
/* wait until push button PD2 (INT0) is pressed */
wait_until_key_pressed();
DO("after keynr");
 
/*
 * Test 2: use lcd_command() to turn on cursor
 */
 
/* turn on cursor */
lcd_command(LCD_DISP_ON_CURSOR);
...

Die Bibliothek muss im Makefile als zusätzliche Bibliothek eingetragen werden. Die Funktionsprototypen stehen alle im Header „lcd.h“, den man im eigenen Programm eintragen muss.


Seiko L2432 angeschlossen und erste Datenausgabe

Die Bibliothek ist auch konfigurierbar, es gibt z.B. Controller, die mehr als zwei Zeilen beherrschen, dies kann in der Bibliothek eingestellt werden. Die Spezifika des Displays (Anzahl Zeilen, Anzahl Zeichen, ..) und die Anschlussbelegung am AVR muss in „lcd.h“ eingetragen werden.

Im Code findet sich übrigens auch der Makroaufruf DO(„text“), dies ist ein Debug-Makro („DEBUG OUT“) von mir, welchen Daten via RS232 ausgibt. Damit kann man erkennen, was der Controller gerade tut. Wie die RS232-Schnittstelle angesprochen wird, wird weiter unten in meinem Text besprochen.

LCD-Displays Wintek WD-C2704M-1HNN mit 4 Zeilen zu 27 Zeichen

Das Display hat 4 Zeilen zu 27 Zeichen. Auf dem Display sitzen zwei Controller, kompatibel zum HD44780. Einer ist für die oberen zwei Zeilen, der andere für die unteren zwei Zeilen verantwortlich. Beide Controller teilen sich alle I/O-Leitungen. Statt einem E(nable)-Pin gibt es zwei Enable-Pins E1 und E2 für die Auswahl zwischen den beiden Controllern.

Die Bibliothek von Peter Fleury unterstützt allerdings nur Displays mit einem Controller. Ich habe das Problem dadurch gelöst, dass ich in alle Funktionen der Bibliothek wo notwendig zwischen beiden Controllern unterschieden habe. So wird z.B. aus der Funktion lcd_clrscr(void) eine Funktion lcd_clrscr(int controllerId), der die Werte LCD_CRTLR_1 und LCD_CRTLR_2 übergeben werden können.

Die Pin-Belegung des Moduls ist in folgender Tabelle dargestellt. Die oben erwähnte „Quasi-Standardisierung“ist hier leicht verändert, da 2 Enable-Pins existieren.

Pin Function
1 GND
2 V+, normalerweise +5V
3 VLC, Kontrastreglung (0..4V)
4 RS – Register Set
5 RW – Read/Write
6 E1 – Enable Controller 1
7 E2 – Enable Controller 2
8 DB0
9 DB1
10 DB2
11 DB3
12 DB4
13 DB5
14 DB6
15 DB7
16-21 Key Input for Input Keys

In Rot sind die für die 4-Bit-Ansteuerung notwendigen Pins gekennzeichnet. Diese müssen mit freien Ports des AVRs (bzw. V+ und GND) verbunden werden.

Im folgenden ist die Nutzung der modifizierten Funktionen dargestellt (Codeauszug, kompletten Source Code gibts weiter unten):

...
#include "lcd.h"
 
...
/* clear display and home cursor */
lcd_clrscr(LCD_CRTLR_1);
lcd_clrscr(LCD_CRTLR_2);
 
/* put string to display (line 1) with linefeed */
lcd_puts(LCD_CRTLR_1, "LCD Test Line 1n");
 
/* cursor is now on second line, write second line */
lcd_puts(LCD_CRTLR_1, "Line 2");
 
/* move cursor to position 8 on line 2 */
lcd_gotoxy(LCD_CRTLR_1, 7,1);
 
/* write single char to display */
lcd_putc(LCD_CRTLR_1,':');
 
DO("wait for keynr");
/* wait until push button PD2 (INT0) is pressed */
wait_until_key_pressed();
DO("after keynr");
 
/*
 * Test 2: use lcd_command() to turn on cursor
 */
 
/* turn on cursor */
lcd_command(LCD_CRTLR_1, LCD_DISP_ON_CURSOR);
...

Für LCDs mit nur einem Controller ist die Bibliothek natürlich so wie sie ist zu benutzen.


Im Bild ist der Anschluss des LCDs an das einfache AVR-Board zu erkennen.
Experimentalaufbau – die Display-Schutzfolie wurde auf dem Display belassen, daher die schlechte Ablesbarkeit.

Hier der Source-Code zum Display:  lcd_2controller.zip

Erschöpfende Infos zur LCD-Ansteuerung unter http://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD

Atmel AVR Mikrocontroller mit OpenSuse: Die Hardware

Die benötigte Hardware ist ein AVR Controller mit etwas zusätzlicher Beschaltung. Die kann man mutig selbst erstellen oder fertig kaufen. In den folgenden Abbildungen dargestellt sind drei Boards, ein einfaches, bei eBay fertig für ca. 15€ erstanden und ein komplexeres, von www.pollin.de für ebenfalls ca. 15€, zum Selbstaufbauen und schließlich ein fertig aufgebautes Board für ca. 50 Euro.

Für die ISP-Programmierung benötigt man ein RS232-Kabel, auf dem 1:1 die Anschlüsse 3,4,5,6,7,8,9 durchgeführt sind.

Anforderungen an den PC, mit dem die AVR-Programme erstellt werden, sind niedrig. Ein 600Mhz-Notebook ist dicke ausreichend. Unabdingbar ist die RS232-Schnittstelle, wenn seriell übertragen werden soll. Da man beim Herumbasteln theoretisch die RS232-Schnittstelle durch Fehlbeschaltung und Unachtsamkeit zerstören kann, sollte man zur Sicherheit nicht seinen besten Rechner für solche Hardware-Aktionen nutzen.

Der AVR Controller kommt mit einigen Milliampere Strom aus, so dass ein einfaches Steckernetzteil mit 9V Gleichspannung ausreicht. Ein komplettes einfaches AVR Board braucht auch nur einige Dutzend mA. Manchmal kann man auch Wechselspannung einspeisen, denn viele Boards besitzen eine eigene Gleichrichtung und Stabilisierung. Vorübergehend langt sogar eine 9V-Batterie.


Einfaches AVR-Board mit ATmega8. 4 Schalter und 8 Dioden dienen als Input- und Output-„Geräte“. Oben links wird die Stromversorgung angeschlossen, in der Mitte oben erkennt man den RESET-Taster. Das ISP-Programmierkabel ist oben rechts angeschlossen. Auf der mittleren braunen Buchsenleiste sind die IO-Pins des Controllers nach außen geführt.

Das Pollin Board ( http://www.pollin.de). On-Board sind die RS232-Umsetzung für die ISP-Programmierung, so dass oben links direkt der Computer angeschlossen werden kann. Unten links ist ein eigenständiger RS232-Anschluss vorhanden. Das Board erlaubt, diverse Typen der AVR-Controller (ATMega, ATtiny) in die Fassungen einzusetzen. Drei Taster und zwei LEDs sind die On-board I/O-Geräte. Ein Steckplatz für ein EEPROM 24Cxx ist vorhanden, des weiteren zwei Steckplätze für ISP und JTAG Programmierung und auf der 40-poligen Steckerleiste sind zahlreiche Pins der Controller herausgeführt. 2 Jumperleisten erlauben die flexible Anpassung des Boards. Dieses Board gibt es mittlerweile in mehreren Varianten und es gibt auch Erweiterungsboards dazu.

Das LAB-MEGA Board von Rakers (http://www.rakers.de) Dieses Board ist mit SMD-Elementen aufgebaut und besitzt daher geringe Abmessungen. Es nutzt den ATmega128, der satte 53 I/O Pins und 128KB Flash Speicher bietet. Auf der Karte findet sich neben den „üblichen“ Dingen wie Spannungsversorgung, ISP/JTAG Interfaces auch eine USB Schnittstelle, ein I2C Expander, eine Echtzeituhr (PCF8583) sowie 2 RS232 Interfaces. Zahlreiche Pins sind auf einer 64-poligen Messerleiste VC64 herausgeführt. Die SMD Bauweise erschwert (ohne geeignetes Werkzeug) leider das Auswechseln defekter Bauteile und auch die Fehlersuche. Zu diesem Board gibt es Erweiterungsboards von Rakers.

ISP-Adapter

Es gibt unterschiedliche Adapter, für RS232, Parallel, USB, …

Serieller ISP-Adapter

Ich verwende einen selbstgebastelten. Bauanleitungen dazu gibt es zahlreich im Internet. Mein Adapter passt z.B. direkt an obiges Pollin-Board.


ISP-Adapter Schaltplan.

Die Schaltung passt komplett auf einer passend gemachten Lochrasterplatine
in einen RS232-Stecker hinein. Hier ist der Stecker ohne Gehäuse dargestellt.

Es gibt übrigens auch Boards mit einer 6-poligen Buchse statt der oben dargestellten 10-poligen. Dies gilt z.B. für das LAB-MEGA Board von Dr. Rakers.
Für solche Boards habe ich mir einen Adapter gelötet, der auf der einen Seite eine 10-polige Buchse und auf der anderen Seite einen 6-poligen Stecker hat.
Das Pin Mapping ist wie folgt:

10-polige Buchse (wie z.B. auf Pollin Board oder Ulrich Radigs Boards)  6-polige Buchse (z.B. Rakers LAB-MEGA)
9 – MISO 1
5 – /RESET 5
6 – GND 6
7 – SCK 3
1 – MOSI 4

Schließlichgibt es noch eine verwirrende Besonderheit beim ATmega128: Dort wird die ISP-Programmierung nicht über die auch vorhandenen Pins MOSI+MISO vorgenommen sondern über zwei „neue“ Pins namens PDI und PDO (nicht zu Verwechseln mit den Port-Pins PD1 und PD0 !!!).
Auch hier das Mapping:

ISP Pin Bezeichnung AT mega 128 Port-Pin am AT mega128
MOSI PDI PE0 (Port E, Pin 0)
MISO PDO PE1 (Port E, Pin 1)

Nutzung eines USB Programmers von Atmel

Mangels serieller Schnittstellen an neueren PCs (besonders bei Notebooks) bietet sich eher die Nutzung eines solchen Programmers an.


Der AVR ISP mkII von Atmel

Das Innere des Programmers – wesentlich komplexer als der triviale RS232 Programmer

Falls bei Nutzung des USB-Programmers der Programmer nicht gefunden wird, sind eventuell die Regeln für den Zugriff auf USB nicht ausreichend. Dazu die Datei /etc/udev/rules.d/15-usbavr.rules neu anlegen und dort  hineinschreiben:

# Atmel AVR ISP mkII SUBSYSTEM==“usb“, SYSFS{idVendor}==“03eb“, SYSFS{idProduct}==“2104″, GROUP=“users“, MODE=“0660″

Kein serieller Port mehr am PC?

Die Nutzung der seriellen Schnittstelle für ISP-Programmierung ist ein sehr simpler Ansatz. RS232 kann auch zur bequemen Ausgabe z.B. von Fehlermeldungen, verwendet werden.

Leider haben viele neuere PCs keine serielle Schnittstelle mehr.
Manche Motherboards haben noch einen „seriellen Header“, der eine serielle Schnittstelle darstellt. Wenn man so etwas auf dem Motherboard hat, kann man sich einen Slot-Adapter kaufen und die Schnittstelle nutzen.

Wenn man nicht mal einen seriellen Header auf dem Mainboard hat, kann man einen USB<->Seriell-Adapter nutzen. Es gibt für unter 10 Euro Kabel, die als Adapter zwischen RS232 und USB dienen können. Unter Linux klinkt sich eine solches Kabel in den Gerätebaum z.B. als „/dev/ttyUSB0“ ein und kann dann genauso wie eine „echte“ serielle Schnittstelle genutzt werden.

Bei meinem OpenSuse 11.2 sieht die Einbindung (mittels dmesg ausgegeben) wie folgt aus:

 ...  [ 3529.694778] usbserial: USB Serial Driver core
 [ 3529.705376] USB Serial support registered for ch341-uart
 [ 3529.705409] ch341 6-1:1.0: ch341-uart converter detected
 [ 3529.718371] usb 6-1: ch341-uart converter now attached to ttyUSB0
 [ 3529.718650] usbcore: registered new interface driver ch341