Ansteuerung eines alphanumerischen LC-Display (mit PIC-Mikrocontroller, Elektronik)
5. Software (in C mit CC5X
5.1. Benötigte Konstanten und Portdefinition
Konstanten:
#define LCD_CLR 0x01 // Display loeschen
#define LCD_ON_C 0x0E // Cursor home
#define LCD_FUNCTION_SET 0x28 // 4 Bit, 2 Zeilen, 5x7
#define LCD_DISP_ON 0x0C // Display Ein
#define LCD_DISP_OFF 0x08 // Display Aus
#define LCD_ENTRY_INC 0x06
Portdefinition:
Im Allgemeinen wird bei jeder Anwendung das LC-Display an einem beliebigen Port
angeschlossen. Damit dies in der Software nur an einer Stelle berücksichtigt werden
muss befindet sich in der Software eine Portdefinition. Diese besteht aus den folgenden
Parametern:
- LCD_DATA: Dieser Parameter gibt den Port für den Datenbus an. (zum
Beispiel Port A, Port B,..). Achtung: Es wird der 4-bit-Datenbus
verwendet, welcher aus dem höheren Nibble des verwendeten
Ports besteht.
- LCD_DATA_TRIS: Dieser Parameter ist für die Initialisierung des Ports für den
Datenbus zuständig. Achtung: Wird für den Parameter LCD_DATA der PORTA verwendet, so muss der
Parameter LCD_DATA_TRIS den Parameter TRISA beinhalten!
- LCD_CTRL: Dieser Parameter gibt den Port für die Steuerleitungen an. (z.B.
Port A, Port B,..)
- LCD_CTRL_TRIS: Dieser Parameter ist für die Initialisierung des Ports für die
Steuerleitungen zuständig. Achtung: Wird für den Parameter LCD_CTRL der PORTA verwendet, so muss
der Parameter LCD_CTRL_TRIS den Parameter TRISA beinhalten!
- LCD_RS: Dieser Parameter gibt den Portpin der Steuerleitung Register-Select an.
- LCD_RW: Dieser Parameter gibt den Portpin der Steuerleitung Read-Write an.
- LCD_E: Dieser Parameter gibt den Portpin der Steuerleitung Enable an.
Eine mögliche Portdefinition ist:
#pragma char LCD_DATA @ PORTB
#pragma char LCD_DATA_TRIS @ TRISB
#pragma char LCD_CTRL @ PORTB
#pragma char LCD_CTRL_TRIS @ TRISB
bit LCD_RS @ LCD_CTRL.1;
bit LCD_RW @ LCD_CTRL.2;
bit LCD_E @ LCD_CTRL.3;
5.2. Initialisierung (Unterprogramm "INIT")
Dieses Unterprogramm dient zur Initialisierung des Mikrocontrollers. Bei diesem
Beispiel ist hier, für die Ansteuerung des LC-Displays, nur die Definition der
verwendeten Portpins als Ausgang notwendig.
5.3. Unterprogramme für die LCD-Ansteuerung
Zur Ansteuerung eines alphanumerischen LC-Displays sind 5 Unterprogramme notwendig:
- Zuerst muss das LC-Display initialisiert werden. Das Unterprogramm LCD_INIT
übernimmt diese Aufgabe
- Befehle an das LC-Display werden mit dem Unterprogramm LCD_BEFEHL erzeugt,
während die am LC-Display anzuzeigenden Zeichen mit dem Unterprogramm
LCD_ZEICHEN erzeugt werden
- Das LC-Display benötigt etwas Zeit zur Abarbeitung der Anweisungen und setzt
dabei ein so genanntes Busy-Flag. Das Unterprogramm LCD_BUSY überprüft dieses
Flag, und wartet solange bis das LC-Display für eine Anweisung bereit ist
- Während der Initialisierung des LC-Displays benötigt das LC-Display verschiedene
Zeitverzögerungen. Diese werden mit dem Unterprogramm VERZ100US erzeugt,
wobei die Verzögerungszeit über einem Parameter eingestellt werden kann.
Mit einem weiteren (optionalen) Unterprogramm kann eine ganze Zeichenkette am LC-Display
ausgegeben werden. Dieses Unterprogramm heißt LCD_STRING.
Nun aber zu den einzelnen Unterprogrammen im Detail:
5.3.1. Unterprogramm LCD_INIT
Aufgabe:
Dieses Unterprogramm initialisiert das LC-Display (siehe auch Abschnitt
3. Befehle zur Ansteuerung eines LC-Display)
Vorgehensweise:
- Die Steuerleitungen des LC-Displays (E, RS, R/W) auf Low legen
- 15 ms warten
- Befehl: 8-bit-Interface an LCD
- 4,1 ms warten
- Wiederholung des Befehls: 8-bit-Interface an LCD
- 0,1 ms warten
- Wiederholung des Befehls: 8-bit-Interface an LCD
- Warten, bis LCD für weitere Anweisungen bereit ist
- Befehl: 4-bit-Interface an LCD; Achtung: ab nun müssen Befehle an das LCD mit
dem Unterprogramm LCDBEFEHL erfolgen
- Befehl: Display löschen und Cursor home
- Befehl: 4 Bit, 2 Zeilen, 5x7
- Befehl: Display aus, Cursor aus, Blinken aus
- Befehl: Shift aus
- Befehl: Display ein
5.3.2. Unterprogramm LCD_BEFEHL
Aufgaben:
Dieses Unterprogramm sendet einen Befehl nibbleweise an das LC-Display.
Vorgehensweise:
- Warten bis das LC-Display für einen Befehl bereit ist. (Dazu ist das Unterprogramm
LCD_BUSY zuständig).
- Für die Kommunikation mit dem LC-Display steht "nur" ein 4-Bit-Datenbus zur
Verfügung. Der 8-bit-Befehl wird daher nibbleweise an das LC-Display übertragen.
Zuerst wird das höherwertigere Nibble auf den 4-Bit-Datenbus gelegt. Dabei dürfen
nur die für den Datenbus definierten Leitungen verändert werden. Die restlichen vier
Portpins dürfen nicht verändert werden.
- Read-Write-Steuerleitung löschen, da es sich hier um eine Schreibanweisung
handelt.
- Register-Select-Steuerleitung löschen, da es sich hier um einen Befehl handelt.
- Eine fallende Flanke auf der Enable-Steuerleitung durch Toggeln erzeugen. (Das
LC-Display liest nun das höherwertigere Befehlsnibble ein)
- Nun das niederwertigere Befehlsnibble auf den 4-Bit-Datenbus legen. Auch hier
dürfen nur die für den Datenbus definierten Leitungen verändert werden. Die
restlichen vier Portpins dürfen nicht verändert werden.
- Eine fallende Flanke auf der Enable-Steuerleitung durch Toggeln erzeugen. (Das
LC-Display liest nun das niederwertigere Befehlsnibble ein).
Anmerkung:
Dieses Unterprogramm unterscheidet sich zum Unterprogramm LCD_ZEICHEN nur
dadurch, dass hier die Register-Select-Steuerleitung gelöscht ist, da mit diesem
Unterprogramm Befehle an das LC-Display übertragen werden.
5.3.3. Unterprogramm LCD_ZEICHEN
Aufgaben:
Dieses Unterprogramm sendet ein Zeichen, welches am LC-Display ausgegeben wird,
nibbleweise an das LC-Display.
Vorgehensweise:
- Warten bis das LC-Display für ein Zeichen bereit ist. (Dazu ist das Unterprogramm
LCD_BUSY zuständig)
- Für die Kommunikation mit dem LC-Display steht "nur" ein 4-bit-Datenbus zur
Verfügung. Der 8-bit-Wert wird daher nibbleweise an das LC-Display übertragen
- Zuerst wird das höherwertigere Nibble auf den 4-Bit-Datenbus gelegt. Dabei dürfen
nur die für den Datenbus definierten Leitungen verändert werden. Die restlichen vier
Portpins dürfen nicht verändert werden.
- Read-Write-Steuerleitung löschen, da es sich hier um eine Schreibanweisung
handelt.
- Register-Select-Steuerleitung setzen, da es sich hier um ein Zeichen handelt,
welches am LC-Display ausgegeben werden soll.
- Eine fallende Flanke auf der Enable-Steuerleitung durch Toggeln erzeugen. (Das
LC-Display liest nun das höherwertige Zeichennibble ein)
- Nun das niederwertigere Zeichennibble auf den 4-Bit-Datenbus legen. Auch hier
dürfen nur die für den Datenbus definierten Leitungen verändert werden. Die
restlichen vier Portpins dürfen nicht verändert werden.
- Eine fallende Flanke auf der Enable-Steuerleitung durch Toggeln erzeugen. (Das
LC-Display liest nun das niederwertigere Zeichennibble ein)
Anmerkung:
Dieses Unterprogramm unterscheidet sich zum Unterprogramm LCD_BEFEHL nur
dadurch, dass hier die Register-Select-Steuerleitung gesetzt ist, da mit diesem
Unterprogramm am LC-Display auszugebende Zeichen an das LC-Display
übertragen werden.
5.3.4. Unterprogramm LCD_BUSY
Aufgabe:
Dieses Unterprogramm prüft das Busy-Flag des LC-Displays, und verlässt es erst wenn
das Busy-Flag low ist, also wenn das LC-Display bereit für einen Befehl oder für ein
auszugebendes Zeichen ist.
Vorgehensweise:
- Der Datenport muss als Eingang definiert werden, da nun der Zustand
(insbesondere der Zustand des Busy-Flags) des LC-Displays gelesen wird.
- Register-Select-Steuerleitung löschen, da es sich hier um einen Befehl handelt.
- Read-Write-Steuerleitung setzen, da es sich hier um eine Leseanweisung handelt.
- Eine fallende Flanke auf der Enable-Steuerleitung durch Toggeln erzeugen. (Das
LC-Display gibt nun das höherwertigere Nibble auf den 4-Bit-Datenbus.)
- Den 4-Bit-Wert vom Datenbus einlesen und im Hilfsregister temp1 sichern.
- Eine weiter fallende Flanke auf der Enable-Steuerleitung durch Toggeln erzeugen.
(Das LC-Display gibt nun das niederwertigere Nibble auf den 4-Bit-Datenbus
- Den 4-Bit-Wert vom Datenbus einlesen und mit dem Hilfsregister temp2 zu einem
8-Bit-Wert verschmelzen.
- Das Busy-Flag (Bit 7 von temp2) überprüfen. Ist dieses Flag gesetzt, die soeben
durchgeführten Schritte so oft wiederholen bis das LC-Display das Busy-Flag löscht.
- Ist das Busy-Flag low, (also gelöscht) die Read-Write-Steuerleitung wieder
zurücksetzen und den Datenport wieder als Ausgang definieren.
5.3.5. Unterprogramm LCD_STRING
Aufgabe:
Dieses Unterprogramm sendet einen String Zeichen für Zeichen an das LC-Display.
Vorgehensweise:
- Der Zeiger (engl. Pointer) *pString zeigt auf das erste Zeichen der übergebenen
Zeichenkette. Den Inhalt dieses Zeigers in die Variable zeichen kopieren.
- Mit einer Schleife den Inhalt von zeichen an das LC-Display übergeben und die
restliche Zeichenkette mit Hilfe des Zeigers Zeichen für Zeichen einlesen und am
LC-Display ausgeben.
Anmerkung:
Eine Zeichenkette (engl. String) wird in C mit einem so genannten Nullbyte abgeschlossen.
5.3.6. Unterprogramm VERZ100US
Aufgabe:
Dieses Unterprogramm erzeugt eine Zeitverzögerung. Der Übergabeparameter VerzZeit
gibt dabei an, wie oft eine Zeitverzögerung von 100µs erfolgen soll. Der
mögliche Zeitverzögerungsbereich liegt hier daher im Bereich von 100µs und 25,5ms
(=255 x 100us).

Autor: Buchgeher Stefan
Erstellt: 19. Februar 2004
Letzte Änderung: 23. Februar 2011