;LCD-Routinen für WD-C2704M - Text-Punktmatrix-LCD ;mit 2 Controllern HD44780. 4 Zeilen je 27 Zeichen ;Version mit frei definierbaren Steuerleitungen. ;Diese Routinensammlung baut auf Beispielen von Andreas Schwarz ;und T.S. auf und ist von ...HanneS... zusammengestellt worden. ; hannes.lux@gmx.de / www.hannes.de.md ;============================================================================ ;Diese Sammlung enthält folgende Routinen: ;---------------------------------------------------------------------------- ; lcd_init ;initialisiert und löscht beide Controller des LCD ;---------------------------------------------------------------------------- ; lcd_clear ;löscht das LCD ;---------------------------------------------------------------------------- ; lcd_command ;übergibt das Byte im Register "wl" als Kommando ;an das LCD ;---------------------------------------------------------------------------- ; lcd_data ;übergibt das Byte im Register "wl" zur Textausgabe ;---------------------------------------------------------------------------- ; locate ;Macro zum Einstellen der Ausgabeposition. ;Aufruf: locate Zeile,Spalte ;Zeile: 0-3, Spalte: 0-26 ;============================================================================ ;Die Datei "LCDprint.inc" stellt einige Ausgaberoutinen zur Verfügung, die ;die Ausgabe von Texten und Zahlen erleichtert. Zusammen mit "locate" wird ;die Ausgabe von Menütexten, Zahlen usw. ähnlich einfach wie in BASIC. ;============================================================================ ;Vor Schreibzugriffen wird das Busy-Flag des LCD ausgelesen und ;auf LCD-Bereitschaft gewartet. ;Für die Auswahl des zuständigen Controllers werden die zwei Bits ;"lcdcontroller1" und "lcdcontroller2" im Register "FLAGS" ;des Hauptprogramms genutzt. Sie müssen dort deklariert werden. ;Die Übergabe der Daten erfolgt über das Register "wl", das im Hauptprogramm ;zu deklarieren ist. Weiterhin muss das Register "wh" deklariert sein. ;============================================================================ ;Anschlussbelegung: ;Die 4 Datenleitungen sollten in einem Nibble liegen. ;Dies kann ein unteres oder oberes Nibble sein. ;Die Auswahl geschieht mit "lcddatmsk" ;Die Steuerleitungen des LCD können über alle ;verfügbaren Ports frei gewählt werden, was diesen ;Treiber sehr flexibel macht. ;---------------------------------------------------------------------------- .equ lcdport=portc ;Port, an dem die 4 Datenleitungen des LCD ;angeschlossen sind. .equ lcddatmsk=$0f ;Maske auf LCD-Datenpins. ;$0f - LCD ist an Bit 0...3 des Ports angeschlossen. ;$f0 - LCD ist an Bit 4...7 des Ports angeschlossen. ;---------------------------------------------------------------------------- .equ rsport=portd ;Port, an dem RS angeschlossen ist .equ rs=5 ;Pin, an dem RS angeschlossen ist ;---------------------------------------------------------------------------- .equ enable1port=portd ;Port Anschluss Enable des ersten Controllers. .equ enable1=6 ;Pin Anschluss Enable des ersten Controllers. ;---------------------------------------------------------------------------- .equ enable2port=portd ;Port Anschluss Enable des zweiten Controllers. .equ enable2=7 ;Pin Anschluss Enable des zweiten Controllers. ;---------------------------------------------------------------------------- .equ rwport=portd ;Port, an dem R/W angeschlossen ist .equ rw=0 ;Pin, an dem R/W angeschlossen ist ;============================================================================ ;============================================================================= ; locate Zeile,Spalte ;Setzt die Ausgabeposition des LCD auf ;Zeile (0...3) und Spalte (0...26). ;Dabei wird auch der für die Ausgabe zuständige ;Controller ausgewählt. ;----------------------------------------------------------------------------- .macro locate ;Zeile (0...3), Spalte (0...27) ;Positionierung der Ausgabeposition ;Beide Controller erstmal aus: cbr flags,(1<15ms warten, nachdem Vcc > 4,5V ist powerupwait: ;hier 250ms warten, dafür keine Spannungsprüfung rcall delay5ms dec xl brne powerupwait pop xl ;alten Inhalt zurück holen cbi rwport,rw ;Steuerleitungen auf cbi rsport,rs ;L-Pegel legen ;Startsequenz in wl,lcdport ;ganzen Port einlesen cbr wl,lcddatmsk ;Platz für Datenbits löschen ldi wh,0b00110011 ;benötigte Datenbits in beide Nibbles andi wh,lcddatmsk ;nur das genutzte Nibble or wl,wh ;übernehmen out lcdport,wl ;und wieder ausgeben ;dreimal ausgeben rcall lcd_impuls ;1. Ausgabe (von 3) rcall delay5ms ;>4,1ms warten rcall lcd_impuls ;2 rcall delay5ms ;>0,1ms warten rcall lcd_impuls ;und 3! rcall delay5ms ;Ab hier BUSY prüfen ;4-Bit-Modus aktivieren in wl,lcdport ;ganzen Port einlesen cbr wl,lcddatmsk ;Platz für Datenbits löschen ldi wh,0b00100010 ;benötigte Datenbits in beide Nibbles andi wh,lcddatmsk ;nur das genutzte Nibble or wl,wh ;übernehmen out lcdport,wl ;und wieder ausgeben rcall lcd_impuls rcall delay5ms ;ab jetzt 4-Bit-Zugriff mit Busy-Abfrage ldi wl,0b00101000 ;4bit-Modus einstellen rcall lcd_command ldi wl,0b00001100 ;Display ein, Cursor aus rcall lcd_command ldi wl,0b00000100 ;Entry-Mode rcall lcd_command ;(Code geht weiter...) ;============================================================================ ; Aufrufbare Routine, löscht das LCD ;---------------------------------------------------------------------------- lcd_clear: ;Sendet den Befehl zur Löschung des Displays sbr flags,(1<