init_lcd ;(this initialises a 2 row lcd)
bcf TRISA,0 ;PORTA bit 0 as an output (lcd RS pin)
bcf TRISA,1 ;PORTA bit 1 as an output (lcd R/W pin)
bcf TRISA,2 ;PORTA bit 2 as an output (lcd E pin)
bcf lcd_rs
bcf lcd_rw
bcf lcd_en
movlw b'00110000' ;Instruction - function set. First of 3
call lcd_write
call Delay5 ;wait MORE THAN 4.1mS
movlw b'00110000' ;Instruction - function set. Second of 3
call lcd_write
movlw .33 ;wait MORE THAN 100uS [(33 x 3) +1 +1 + (1 x 2)] - measured 102uS on scope
movwf counta ;1 cycle
decfsz counta ;1 cycle until true then a 2 cycle
goto $-2 ;2 cycle instruction
movlw b'00110000' ;Instruction - function set. Third of 3
call lcd_write
movlw b'00111000' ;8 bit data / 2 line display / 5x8 character font
call lcd_write
call busy
movlw b'00001111' ;instruction bit / display on / cursor position on / blinking cursor on
call lcd_write
call busy
movlw b'00000001'
call lcd_write
call busy
movlw b'00000110' ;increment cursor position by 1 / don't shift display
call lcd_write
call busy
return ;return from initialization routine
lcd_write
movwf lcd_data ;data to port
bsf lcd_en ;sets LCD enable pin high
bcf lcd_en ;data is latched into lcd on high to low transition of E
return
busy
bsf TRISC,7 ;was output when sending init data, now input to read busy flag
bsf lcd_rw ;set high to read data from lcd
bsf lcd_en ;enable
btfsc lcd_busy ;is the busy flag low?
goto $-2 ;no, go back and keep checking until it is
bcf lcd_en ;busy flag now clear
bcf lcd_rw ;set lcd back to write mode
bcf TRISC,7 ;port bit as an output again
return
Delay30
movlw .30 ;delay 30mS
goto d0
Delay5
movlw .5 ;delay 5ms
d0 movwf count1
d1 movlw 0xC7
movwf counta
movlw 0x01
movwf countb
Delay_0
decfsz counta
goto $+6
decfsz countb
goto Delay_0
decfsz count1
goto d1
retlw .0 ;return from the delay routine