![]() NEW! 416028 |
; (This code is not mine, except for the delays, I just added this comments)
;
;Connection is like this:
;
; PIC LCD
; -------------
; RBO E
; RB1 RS
; RB2 RW
; RB3 --
; RB4 D4
; RB5 D5
; RB6 D6
; RB7 D7
;
; (RB0-RB7: PIC PINS 6-13 RESPECTIVELY)
; (E, RS, RW, D4-D7: LCD PINS 6, 4, 7, 10-14 RESPECTIVELY)
;
; MAKE SURE YOU CONNECT THE CONTRAST POT (10K) TO PIN 3
; POWER IS 1: GND, 2: +5V
;
;
; the subroutine DELAY seems to be the same as DELAY_MS, at least it works if you change all 'delay' to 'delay_ms'
; here's the Q&D delay I use (1ms for 4MHz XT):
;
;
; delays
cblock 0x0D
d1
d2
bit_tmp
msres
endc
delay_ms
movwf msres
dl3 decfsz msres, f
goto dl
return
dl ;993 cycles
movlw 0xC6
movwf d1
movlw 0x01
movwf d2
delay_ms_0
decfsz d1, f
goto $+2
decfsz d2, f
goto delay_ms_0
;3 cycles
nop
goto dl3
;lcd routines
cblock 0x2A
lcd_shadow,lcd_tmp,lcda,lcd_char
endc
#define lcd_port PORTB
#define lcd_enable lcd_shadow,0
#define lcd_rs lcd_shadow,1
#define lcd_rw lcd_shadow,2
;------------------------------
lcd_uport macro
movf lcd_shadow,w
movwf lcd_port
endm
;------------------------------
;strobe lcd enable
lcd_strobe:
movlw .20
call delay
bsf lcd_enable
lcd_uport
movlw .20
call delay
movf lcd_port,w
andlw 0xF0
movwf lcd_tmp
bcf lcd_enable
lcd_uport
swapf lcd_tmp,w
return
;------------------------------
lcd_send_nibble:
movwf lcd_tmp
movlw 0x0F
andwf lcd_tmp,f
andwf lcd_shadow,f
swapf lcd_tmp,w
iorwf lcd_shadow,f
lcd_uport
goto lcd_strobe
;------------------------------
lcd_read_byte:
movlw 0xF0
tris lcd_port
bsf lcd_rw
lcd_uport
call lcd_strobe
movwf lcda
swapf lcda,f
call lcd_strobe
iorwf lcda,f
movlw 0
tris lcd_port
bcf lcd_rw
movf lcda,w
return
;------------------------------
#define sv_addr bit_tmp,0
lcd_putc:
bsf lcd_rs
lcd_send_byte:
movwf lcd_char
bcf sv_addr
btfsc lcd_rs
bsf sv_addr
bcf lcd_rs
sb0 call lcd_read_byte ;wait until not lcd busy
andlw B'10000000'
skpz
goto sb0
bcf lcd_rw
bcf lcd_rs
btfsc sv_addr
bsf lcd_rs
swapf lcd_char,w
call lcd_send_nibble
movf lcd_char,w
goto lcd_send_nibble
;------------------------------
lcd_init:
movlw 0
tris lcd_port
clrf lcd_shadow
lcd_uport
movlw .50
call delay_ms
movlw 3
movwf lcda
bcf lcd_rs
lcdi0 movlw 3
call lcd_send_nibble
movlw .15
call delay_ms
decfsz lcda,f
goto lcdi0
movlw .2
call lcd_send_nibble
movlw B'00101000' ;function set
call lcd_send_byte ;4 bit,1/6 duty,5x8
movlw B'00001000' ;display off,cursor off, blink off
call lcd_send_byte
movlw B'00000001' ;clear screen cursor home
call lcd_send_byte
movlw B'00000110' ;Increment cursor, don't shift screen
call lcd_send_byte
movlw B'00001111' ;display on,cursor on, blink on
call lcd_send_byte
return
;------------------------------
;lcd_gotoxy
; input W = YYXXXXXX
; 76543210
;
; Y address
; --- -------
; 00 0
; 01 0x40
; 10 20
; 11 0x40+20
xy_loc macro x, y
movlw (y << 6) | (x & B'00111111')
call lcd_gotoxy
endm
lcd_gotoxy:
movwf lcd_tmp
andlw B'00111111'
btfsc lcd_tmp,6
addlw 0x40
btfsc lcd_tmp,7
addlw .20
iorlw B'10000000'
bcf lcd_rs
goto lcd_send_byte
;------------------------------
lcd_cursor_off:
bcf lcd_rs
movlw B'00001100' ;display on,cursor off, blink off
goto lcd_send_byte
;------------------------------
lcd_cursor_on:
bcf lcd_rs
movlw B'00001111' ;display on,cursor on, blink on
goto lcd_send_byte