;
; *******************************************************
; * Include routines for the LCD display, provides the *
; * basic routines for initiation of an LCD display and *
; * for displaying text on it, written for single- and *
; * two-line LCDs, 8-bit-interface, HD44780-compatible *
; * display *
; * (C)2006 by g.schmidt, info!at!avr-asm-tutorial.net *
; *******************************************************
;
;
; Characteristics of the hardware:
;
.EQU pLcdDataOut = PORTD ; Data Port that the LCD is connected to
.EQU pLcdDataIn = PIND ; dto., the input port
.EQU pLcdDataDir = DDRD ; dto., direction port
.EQU pLcdEOut = PORTB ; Control Port for the LCD bit E
.EQU pLcdEDir = DDRB ; Control Port direction for the LCD bit E
.EQU pLcdRsOut = PORTB ; dto., for LCD-RS
.EQU pLcdRsDir = DDRB ; dto., direction port
.EQU bLcdEOut = 0 ; Portbit Control bit E of the LCD
.EQU bLcdRSOut = 4 ; Portbit Control bit RS of the LCD
;
; Further required for assembling:
;
; Type Name Explanations
; --------------------------------------------------------------
; Constant Clock Processor frequency in cs/s, range 1..16 Mcs/s
; cLcdLw Number of characters per line of the LCD
; cLcdLn Number of lines of the LCD (1 or 2)
; Register rmp Multi-purpose register (R16..R31)
; --------------------------------------------------------------
;
; Provided routines:
;
; Name Parameters Provided task
; ------------------------------------------------------
; LcdInit Z:Text1 in flash Inits the LCD and displays
; memory (null- the text1 that Z points to,
; terminated), waits for 1.5 seconds and
; lines separate
; by char
; X:Text2 in flash displays the text2 that X
; Uses: R25:R24 points to
; LcdFlash Z: Text in flash Displays the text in flash
; memory that Z points to
; LcdHome -- Sets display position to
; start of line 1
; LcdChar R0 = character Displays the character in
; R0 on the current position
; LcdLine1 Z:Text in SRAM Displays the text in SRAM
; on line 1 of the LCD
; LcdLine2 Z:Text in SRAM Displays the text in SRAM
; on line 2 of the LCD
; -----------------------------------------------------
;
; -----------------------------------------------
; L C D I N I T I A T I O N R O U T I N E
; -----------------------------------------------
;
LcdInit:
cbi pLcdEOut,bLcdEOut ; clear LCD enable bit
sbi pLcdEDir,bLcdEOut ; set E bit to be output
sbi pLcdRsDir,bLcdRSOut ; dto., RS bit
rcall Delay360ms ; wait for LCD's internal init
ldi rmp,0xFF ; set LCD data port to be output
out pLcdDataDir,rmp
rcall Delay15ms ; wait 15 ms for internal display init
ldi rmp,0x38 ; set 8-bit-interface, 2 line LCD
rcall LcdStrobeC ; put contrl word out without busy
rcall Delay40us ; wait 40 us
ldi rmp,0x38 ; set again 8-bit-interface
rcall LcdStrobeC ; put contrl word out without busy
rcall Delay40us ; wait 40 us
ldi rmp,0x38 ; set 8-bit-interface and two lines
rcall LcdStrobeC ; put control word out without busy
rcall Delay40us ; wait 40 us
ldi rmp,0x08 ; set display off
rcall LcdStrobeC ; put contrl word out without busy
rcall Delay40us ; wait 40 us
ldi rmp,0x01 ; Display clear
rcall LcdStrobeC ; put contrl word out without busy
rcall Delay1m64s ; wait 1.64 ms
ldi rmp,0x06 ; Increment on, shift off
rcall LcdStrobeC ; put control word out without busy
ldi rmp,0x0C ; activate display, no cursor, no blinking
rcall LcdStrobeC ; put control word out without busy
rcall LcdHome ; set cursor position to home
rcall LcdFlash ; display text from Z in flash
rjmp Delay2s5 ; delay for 2.5 seconds
;
; -----------------------------------------------
; L C D W R I T E S U B R O U T I N E S
; -----------------------------------------------
;
; Display text at flash position Z on the display
;
LcdFlash:
lpm ; read the next char from flash memory
tst R0 ; reached the end of the string?
breq LcdFlash2
.IF cLcdLn>1
ldi rmp,0x0D ; carriage return?
cp rmp,R0
brne LcdFlash1 ; display character
ldi rmp,0xC0 ; line 2 address
rcall LcdStrobeC ; strobe control word
rcall Delay40us
adiw ZL,1 ; next char
rjmp LcdFlash ; go on
LcdFlash1:
.ENDIF
out pLcdDataOut,R0 ; character to output port
sbi pLcdRsOut,bLcdRSOut ; set RS
rcall LcdStrobeE ; strobe E
cbi pLcdRsOut,bLcdRSOut ; clear RS
rcall Delay40us
adiw ZL,1
rjmp LcdFlash ; next character
LcdFlash2:
ret
;
; Set the LCD output position to the beginning of line 1
;
LcdHome:
ldi rmp,0x02 ; set control to home
rcall LcdStrobeC ; strobe control word
rjmp Delay1m64s
;
; outputs rmp to lcd control and strobes E
;
LcdStrobeC:
out pLcdDataOut,rmp ; write control word to data port
cbi pLcdRsOut,bLcdRSOut ; clear RS
;
; Strobes E for the correct time
;
LcdStrobeE:
sbi pLcdEOut,bLcdEOut ; set E to one
nop ; wait at least 1 clock
.IF Clock>2 ; more than 2 Mcs/s
nop ; two nop
.ENDIF
.IF Clock>4 ; more than 4 Mcs/s
nop ; three nop
.ENDIF
.IF Clock>6 ; more than 6 Mcs/s
nop ; four nop
.ENDIF
.IF Clock>8 ; more than 8 Mcs/s
nop ; five nop
.ENDIF
.IF Clock>10 ; more than 10 Mcs/s
nop ; six nop
.ENDIF
.IF Clock>12 ; more than 12 Mcs/s
nop ; seven nop
.ENDIF
.IF Clock>14 ; more than 14 Mcs/s
nop ; eight nop
.ENDIF
cbi pLcdEOut,bLcdEOut ; clear E to zero
rjmp Delay40us
;
; Display the character in R0
;
LcdChar:
out pLcdDataOut,R0 ; output the character in R0
sbi pLcdRsOut,bLcdRSOut ; set RS
rjmp LcdStrobeE ; strobe E
;
; Displays the text at Z in SRAM on line 1 of the LCD
;
LcdLine1:
ldi rmp,0x80 ; set cursor to line 1
rcall LcdStrobeC
ldi rmp,cLcdLw
LcdLine1a:
ld R0,Z+ ; read next char
rcall LcdChar
dec rmp
brne LcdLine1a
ret
;
; Displays the text at Z in SRAM on line 2 of the LCD
;
LcdLine2:
ldi rmp,0xC0 ; set cursor to line 2
rcall LcdStrobeC
ldi rmp,cLcdLw
LcdLine2a:
ld R0,Z+ ; read next char
rcall LcdChar
dec rmp
brne LcdLine2a
ret
;
; -----------------------------------------------
; D E L A Y R O U T I N E S F O R L C D
; -----------------------------------------------
;
.SET clockus = clock/1000000
.IF clockus == 0 ; clock smaller than 1 Mcs/s
.SET clockus = 1
.ENDIF
;
; Delay for 2.5 seconds
;
Delay2s5:
push rmp
ldi rmp,2500/15+1 ; number of 15ms-delays
Delay2s5a:
rcall Delay15ms
dec rmp
brne Delay2s5a
pop rmp
ret
;
; Delay for 360 milliseconds
;
Delay360ms:
push rmp
ldi rmp,360/15+1 ; number of 15ms delays
Delay360ms1:
rcall Delay15ms
dec rmp
brne Delay360ms1
pop rmp
ret
;
; Delay for 15 milliseconds
;
Delay15ms:
push ZH ; save 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
;
; Delay for 1.64 milliseconds
;
Delay1m64s:
push ZH ; save 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
;
; Delay 40 microseconds
;
Delay40us:
push rmp
ldi rmp,(40*clockus-11)/3
Delay40us1:
dec rmp
brne Delay40us1
pop rmp
ret
;
; End of the LCD-Routines
;