Pfad: Home => AVR-Übersicht => Anwendungen => Rechteckgenerator = > Quellcode LCD-Routinen
Rechteckgenerator klein

Rechteckgenerator mit ATmega8 - Quellcode LCD-Routinen


;
; *******************************************************
; * Include-Routinen zur LCD-Ansteuerung, stellt die    *
; * Basisroutinen fuer die Initiierung einer LCD und die*
; * Textausgabe zur Verfuegung, ausgelegt fuer ein- und *
; * mehrzeilige LCDs, 8-bit-interface, HD44780-kompati- *
; * ble Displays                                        *
; * (C)2006 by g.schmidt, info!at!avr-asm-tutorial.net  *
; *******************************************************
;
;
; Charakteristiken der Hardware:
;
.EQU pLcdDataOut = PORTD ; Daten-Port mit dem LCD verbunden ist
.EQU pLcdDataIn  = PIND  ; dto., der Eingabe-Port
.EQU pLcdDataDir = DDRD  ; dto., Port-Richtung
.EQU pLcdEOut    = PORTB ; Kontroll-Port Bit E der LCD
.EQU pLcdEDir    = DDRB  ; dto., Richtungs-Bit
.EQU pLcdRsOut   = PORTB ; dto., Bit LCD-RS der LCD
.EQU pLcdRsDir   = DDRB  ; dto., Richtungs-Bit
.EQU bLcdEOut    = 0     ; Port-Bit E der LCD
.EQU bLcdRSOut   = 4     ; Port-Bit RS der LCD
;
; Weitere Bedingungen zum Assemblieren:
;
;   Typ       Name   Erlaeuterung
;   -----------------------------------------------------------
;   Konstante Clock  Prozessorfrequenz in Hz, Bereich 1..16 MHz
;             cLcdLw Anzahl Zeichen pro Zeile der LCD
;             cLcdLn Anzahl Zeilen der LCD (1 oder 2)
;   Register  rmp    Multi-Purpose Register (R16..R31)
;   -----------------------------------------------------------
;
; Stellt folgende Routinen zur Verfuegung:
;
;   Name      Parameter         Erfuellt folgende Aufgaben
;   ---------------------------------------------------------
;   LcdInit   Z:Text1 im Flash  Initiiert die LCD and zeigt
;               Speicher (null- den Text1 an auf den Z zeigt,
;               terminiert),    wartet fuer 1.5 Sekunden und
;               Zeilen durch
;                getrennt
;             X:Text2 im Flash  zeigt Text2 an, auf den X
;             Verwendet R25:R24 zeigt
;   LcdFlash  Z: Text im Flash  Zeigt den Text im Flash-
;                               speicher an, auf den Z zeigt
;   LcdHome   --                Setzt die Anzeigenposition
;                               den Beginn von Zeile 1
;   LcdChar   R0 = Zeichen      Schreibt das Zeichen in R0
;                               an die aktuelle LCD-Position
;   LcdLine1  Z:Text im SRAM    Zeigt den Text im SRAM auf
;                               Zeile 1 der LCD an
;   LcdLine2  Z:Text im SRAM    Zeigt den Text im SRAM auf
;                               Zeile 2 der LCD an
;   -----------------------------------------------------
;
; -----------------------------------------------
;  L C D   I N I T I I E R U N G   R O U T I N E
; -----------------------------------------------
;
LcdInit:
	cbi pLcdEOut,bLcdEOut ; loesche LCD Enable Bit
	sbi pLcdEDir,bLcdEOut ; E-Bit ist Ausgang
	sbi pLcdRsDir,bLcdRSOut ; dto., RS-Bit
	rcall Delay360ms ; warte auf die LCD-interne Initiierung
	ldi rmp,0xFF ; setze LCD-Datenport auf Ausgang
	out pLcdDataDir,rmp
	rcall Delay15ms ; warte 15 ms fuer interne Initiierung
.IF cLcdLn == 1
	ldi rmp,0x30 ; setze 8-Bit-Interface, einzeilige LCD
	.ELSE
	ldi rmp,0x38 ; setze 8-Bit-Interface, zweizeilige LCD
	.ENDIF
	rcall LcdStrobeC ; schreibe Kontrollwort an LCD
	rcall Delay40us ; warte 40 us
.IF cLcdLn == 1
	ldi rmp,0x30 ; setze 8-Bit-Interface, einzeilige LCD
	.ELSE
	ldi rmp,0x38 ; setze 8-Bit-Interface, zweizeilige LCD
	.ENDIF
	rcall LcdStrobeC ; schreibe Kontrollwort an LCD
	rcall Delay40us ; warte 40 us
.IF cLcdLn == 1
	ldi rmp,0x30 ; setze 8-Bit-Interface, einzeilige LCD
	.ELSE
	ldi rmp,0x38 ; setze 8-Bit-Interface, zweizeilige LCD
	.ENDIF
	rcall LcdStrobeC ; schreibe Kontrollwort an LCD
	rcall Delay40us ; warte 40 us
	ldi rmp,0x08 ; Display abschalten
	rcall LcdStrobeC ; schreibe Kontrollwort an LCD
	rcall Delay40us ; warte 40 us
	ldi rmp,0x01 ; Display loeschen
	rcall LcdStrobeC ; schreibe Kontrollwort an LCD
	rcall Delay1m64s ; warte 1.64 ms
	ldi rmp,0x06 ; Increment ein, Shift aus
	rcall LcdStrobeC ; schreibe Kontrollwort an LCD
	ldi rmp,0x0C ; activiere Display, kein Cursor, kein Blinken
	rcall LcdStrobeC ; schreibe Kontrollwort an LCD
	rcall LcdHome ; setze Cursorposition auf Anfang Zeile 1
	rcall LcdFlash ; Schreibe Text im Flash ab Z auf Display
	rjmp Delay2s5 ; warte fuer 2.5 Sekunden
;
; -------------------------------------------------
;   L C D   S C H R E I B - S U B R O U T I N E N
; -------------------------------------------------
;
; Schreibe Text ab Position Z im Flash auf Display
;
LcdFlash:
	lpm ; lese naechstes Zeichen aus dem Flashspeicher
	tst R0 ; Ende des Textes erreicht?
	breq LcdFlash2
.IF cLcdLn>1
	ldi rmp,0x0D ; Wagenruecklauf-Zeichen?
	cp rmp,R0
	brne LcdFlash1 ; zeige Zeichen an
	ldi rmp,0xC0 ; Adresse von Zeile 2
	rcall LcdStrobeC ; an Kontrollport der LCD
	rcall Delay40us ; 40 us Verzoegerung
	adiw ZL,1 ; naechstes Zeichen
	rjmp LcdFlash ; und weiter
LcdFlash1:
.ENDIF
	out pLcdDataOut,R0 ; Zeichen in R0 an Datenport
	sbi pLcdRsOut,bLcdRSOut ; setze RS-Bit
	rcall LcdStrobeE ; E-Bit pulsen
	cbi pLcdRsOut,bLcdRSOut ; loesche RS-Bit
	rcall Delay40us ; 40 us Verzoegerung
	adiw ZL,1
	rjmp LcdFlash ; naechtes Zeichen
LcdFlash2:
	ret
;
; Setzt die LCD-Ausgabeposition auf den Anfang von Zeile 1
;
LcdHome:
	ldi rmp,0x02 ; setze Kontrollwort fuer Home
	rcall LcdStrobeC ; schreibe Kontrollwort
	rjmp Delay1m64s ; warte 1,64 ms
;
; gibt das Zeichen in rmp als Kontrollwort aus und pulst das E-Bit
;
LcdStrobeC:
	out pLcdDataOut,rmp ; schreibe Kontrollwort auf Datenport
	cbi pLcdRsOut,bLcdRSOut ; loesche RS-Bit
;
; Pulst E-Bit mit korrekter Dauer
;
LcdStrobeE:
	sbi pLcdEOut,bLcdEOut ; setze E-Bit Eins
	nop ; warte mindestens 1 Zyklus
.IF Clock>2 ; mehr als 2 MHz Takt
	nop ; zwei NOP
	.ENDIF
.IF Clock>4 ; mehr als 4 MHz Takt
	nop ; drei NOP
	.ENDIF
.IF Clock>6 ; mehr als 6 MHz Takt
	nop ; vier NOP
	.ENDIF
.IF Clock>8 ; mehr als 8 MHz Takt
	nop ; fuenf NOP
	.ENDIF
.IF Clock>10 ; mehr als 10 MHz Takt
	nop ; sechs NOP
	.ENDIF
.IF Clock>12 ; mehr als 12 MHz Takt
	nop ; sieben NOP
	.ENDIF
.IF Clock>14 ; mehr als 14 MHz Takt
	nop ; acht NOP
	.ENDIF
	cbi pLcdEOut,bLcdEOut ; loesche E-Bit
	rjmp Delay40us ; Verzoegerung 40 us
;
; Zeige Zeichen in R0 an
;
LcdChar:
	out pLcdDataOut,R0 ; Ausgabe des Zeichens in R0
	sbi pLcdRsOut,bLcdRSOut ; setze RS-Bit
	rjmp LcdStrobeE ; pulse E-Bit
;
; Zeigt den Text ab Z im SRAM auf Zeile 1 der LCD an
;
LcdLine1:
	ldi rmp,0x80 ; setze Cursor auf Zeile 1
	rcall LcdStrobeC
	ldi rmp,cLcdLw
LcdLine1a:
	ld R0,Z+ ; lese naechstes Zeichen aus SRAM
	rcall LcdChar
	dec rmp
	brne LcdLine1a
	ret
;
; Zeigt den Text ab Z im SRAM auf Zeile 2 der LCD an
;
LcdLine2:
	ldi rmp,0xC0 ; setze Cursor auf Zeile 2
	rcall LcdStrobeC
	ldi rmp,cLcdLw
LcdLine2a:
	ld R0,Z+ ; lese naechstes Zeichen aus SRAM
	rcall LcdChar
	dec rmp
	brne LcdLine2a
	ret
;
; -------------------------------------------------------------
;  V E R Z O E G E R U N G S R O U T I N E N   F U E R   L C D
; -------------------------------------------------------------
;
.SET clockus = clock/1000000
.IF clockus == 0 ; Clock kleiner als 1 MHz
	.SET clockus = 1
	.ENDIF
;
; Verzoegerung fuer 2.5 Sekunden
;
Delay2s5:
	push rmp
	ldi rmp,2500/15+1 ; Anzahl 15ms-Verzoegerungen
Delay2s5a:
	rcall Delay15ms
	dec rmp
	brne Delay2s5a
	pop rmp
	ret
;
; Verzoegerung fuer 360 Millisekunden
;
Delay360ms:
	push rmp
	ldi rmp,360/15+1 ; Anzahl der 15ms-Verzoegerungen
Delay360ms1:
	rcall Delay15ms
	dec rmp
	brne Delay360ms1
	pop rmp
	ret
;
; Verzoegerung fuer 15 Millisekunden
;
Delay15ms:
	push ZH ; sichere Z
	push ZL
	ldi ZH,HIGH((15000*clockus-16)/4)
	ldi ZL,LOW((15000*clockus-16)/4)
Delay15ms1:
	sbiw ZL,1
	brne Delay15ms1
	pop ZL
	pop ZH
	ret
;
; Verzoegerung fuer 1.64 Millisekunden
;
Delay1m64s:
	push ZH ; sichere Z
	push ZL
	ldi ZH,HIGH((1640*clockus-16)/4)
	ldi ZL,LOW((1640*clockus-16)/4)
Delay1m64s1:
	sbiw ZL,1
	brne Delay1m64s1
	pop ZL
	pop ZH
	ret
;
; Verzoegerung 40 Mikrosekunden
;
Delay40us:
	push rmp
	ldi rmp,(40*clockus-11)/3
Delay40us1:
	dec rmp
	brne Delay40us1
	pop rmp
	ret
;
; Ende der LCD-Routinen
;

©2006 by http://www.avr-asm-tutorial.net