;LCD-P.asm
;
;This program is to display an 20x4 LCD module
;by Truly (HD44780 compatible)
;
;8-bit interfacing
;
;Pin Connection from LCD to 16F877
;LCD (pin#) 16F877 (pin#)
;DB7 (14) -----RD7(40)
;DB6 (13) ----RD6(39)
;DB5 (12) ----RD5(38)
;DB4 (11) ----RD4(37)
;DB3 (10) ----RD3(36)
;DB2 (9)---- RD2(35)
;DB1 (8) ----RD1(34)
;DB0 (7) ----RD0(33)
;E (6) ------RB0(28)
;RW (5) -----RB1(29)
;RS (4) -----RB2(27)
;Vo (3) -----+5V
;Vdd (2) ----+5V
;Vss (1) -----GND
;
;Example code to display:
; PIC
; AND
; LCD
; DISPLAY
;
list P = 16F877a, R=DEC;
#include <P16f877a.INC>
errorlevel -302
;*****
__CONFIG h'3F31'
;Config register bits
; CP1 CP0 DBG NIL WRT CPD LVP BOR CP1 CP0 POR WDT OS1 OS0
; 1 1 1 1 1 1 0 0 1 1 0 0 0 1
STATUS EQU 0x03
PORTD EQU 0x08
TRISD EQU 0x88
PORTB EQU 0x06
TRISB EQU 0x86
RS EQU 0x00 ;RB0
E EQU 0x01 ;RB1
RW EQU 0x02 ;RB2
;RAM arEA
CBLOCK 0x20
Kount120us ;Delay count (number of instr cycles for delay)
Kount100us
Kount1ms
Kount10ms
Kount1s
Kount10s
Kount1m
ENDC
org 0x0000 ;line 1
;The following lines accommodate bootloader
goto START ;line 1 ($0000)
org 0x0005
START
BANKSEL TRISD; 1 for input, 0 for output
movlw 0x00
movwf TRISD
movwf TRISB ;RB<7:0> are all outputs
banksel PORTB
clrf PORTB
clrf PORTB ;Here RW is pulled down to ground
;LCD routine starts
call delay10ms
call delay10ms
;give LCD module to reset automatically
;Fundtion for 8-bit, 2-line display, and 5x8 dot matrix
movlw 0x38
call instw
;Display On, CUrsor On, No blinking
movlw 0x0E ;0F would blink
call instw
;DDRAM address increment by one & cursor shift to right
movlw 0x06
call instw
;DISPLAY CLEAR
movlw 0x01
call instw
;Set DDRAM ADDRES
movlw 0x80 ;00
call instw
;WRITE DATA in the 1st position of line 1
movlw 0x50 ;P
call dataw
movlw 0x49 ;I
call dataw
movlw 0x43 ;C
call dataw
;Set DDRAM address for the 1st position of line 2 (40h)
movlw 0xC0 ;B'11000000'
call instw ;RS=0
;Write A, N, D
movlw 0x41 ;A
call dataw
movlw 0x4E
call dataw ;N
movlw 0x44
call dataw
;Now let's move the cursor to the home position (position 1 of line #1)
;and set the DDRAM address to 0. This is done by the "return home"
instruction.
movlw 0x02
call instw
IDLE nop
goto IDLE
;====SUBROUTINES =====
;subroutine instw (instruction write)
;instruction to be written is stored in W before the call
instw movwf PORTD
call delay1ms ;delay may not be needed
bcf PORTB, RS
call delay1ms
bsf PORTB, E
call delay1ms
bcf PORTB,E
call delay10ms
return
;subroutine dataw (data write)
dataw movwf PORTD
call delay1ms ;delay may not be needed
bsf PORTB, RS
call delay1ms
bsf PORTB, E
call delay1ms
bcf PORTB, E ;Transitional E signal
call delay10ms
return
;
;==========================================================
;DELAY SUBROUTINES
Delay120us
banksel Kount120us
movlw H'C5' ;D'197'
movwf Kount120us
R120us
decfsz Kount120us
goto R120us
return
;
delay100us
banksel Kount100us
movlw H'A4'
movwf Kount100us
R100us
decfsz Kount100us
goto R100us
return
;
;1ms delay
delay1ms
banksel Kount1ms
movlw 0x0A ;10
movwf Kount1ms
R1ms call delay100us
decfsz Kount1ms
goto R1ms
return
;
;10ms delay
; call 100 times of 100 us delay (with some time discrepancy)
delay10ms
banksel Kount10ms
movlw H'64' ;100
movwf Kount10ms
R10ms call delay100us
decfsz Kount10ms
goto R10ms
return
;;
;1 sec delay
;call 100 times of 10ms delay
Delay1s
banksel Kount1s
movlw H'64'
movwf Kount1s
R1s call delay10ms
decfsz Kount1s
goto R1s
return
;;
;10 s delay
;call 10 tiems of 1 s delay
Delay10s
banksel Kount10s
movlw H'0A' ;10
movwf Kount10s
R10s call Delay1s
decfsz Kount10s
goto R10s
return
;
;1 min delay
;call 60 times of 1 sec delay
Delay1m
banksel Kount1m
END