;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 MOV W, lcd_shadow MOV lcd_port, W endm ;------------------------------ ;strobe lcd enable lcd_strobe: MOV W, #20 CALL delay SETB lcd_enable lcd_uport MOV W, #20 CALL delay MOV W, lcd_port AND W, #$F0 MOV lcd_tmp, W CLRB lcd_enable lcd_uport MOV W, <>lcd_tmp RET ;------------------------------ lcd_send_nibble: MOV lcd_tmp, W MOV W, #$0F AND lcd_tmp, W AND lcd_shadow, W MOV W, <>lcd_tmp OR lcd_shadow, W lcd_uport JMP lcd_strobe ;------------------------------ lcd_read_byte: MOV W, #$F0 ;*** WARNING: TRIS expanded in two instructions. Check if previous instruction is a skip instruction. ; tris lcd_port SETB lcd_rw lcd_uport CALL lcd_strobe MOV lcda, W SWAP lcda CALL lcd_strobe OR lcda, W MOV W, #0 ;*** WARNING: TRIS expanded in two instructions. Check if previous instruction is a skip instruction. ; tris lcd_port CLRB lcd_rw MOV W, lcda RET ;------------------------------ #define sv_addr bit_tmp,0 lcd_putc: SETB lcd_rs lcd_send_byte: MOV lcd_char, W CLRB sv_addr SNB lcd_rs SETB sv_addr CLRB lcd_rs sb0 CALL lcd_read_byte ;wait until not lcd busy AND W, #%10000000 SB Z JMP sb0 CLRB lcd_rw CLRB lcd_rs SNB sv_addr SETB lcd_rs MOV W, <>lcd_char CALL lcd_send_nibble MOV W, lcd_char JMP lcd_send_nibble ;------------------------------ lcd_init: MOV W, #0 ;*** WARNING: TRIS expanded in two instructions. Check if previous instruction is a skip instruction. ; tris lcd_port CLR lcd_shadow lcd_uport MOV W, #50 CALL delay_ms MOV W, #3 MOV lcda, W CLRB lcd_rs lcdi0 MOV W, #3 CALL lcd_send_nibble MOV W, #15 CALL delay_ms DECSZ lcda JMP lcdi0 MOV W, #2 CALL lcd_send_nibble MOV W, #%00101000 ;function set CALL lcd_send_byte ;4 bit,1/6 duty,5x8 MOV W, #%00001000 ;display off,cursor off, blink off CALL lcd_send_byte MOV W, #%00000001 ;clear screen cursor home CALL lcd_send_byte MOV W, #%00000110 ;Increment cursor, don't shift screen CALL lcd_send_byte MOV W, #%00001111 ;display on,cursor on, blink on CALL lcd_send_byte RET ;------------------------------ ;lcd_gotoxy ; input W = YYXXXXXX ; 76543210 ; ; Y address ; --- ------- ; 00 0 ; 01 0x40 ; 10 20 ; 11 0x40+20 xy_loc macro x, y MOV W, #(y < ;< 6) | (x & B'00111111') CALL lcd_gotoxy endm lcd_gotoxy: MOV lcd_tmp, W AND W, #%00111111 SNB lcd_tmp.6 ;*** WARNING: ADDLW was expanded in three instructions! Check if previous instruction is a skip instruction. ; addlw 0x40 MOV Hack, W MOV W, #$40 ADD W, Hack SNB lcd_tmp.7 ;*** WARNING: ADDLW was expanded in three instructions! Check if previous instruction is a skip instruction. ; addlw .20 MOV Hack, W MOV W, #20 ADD W, Hack OR W, #%10000000 CLRB lcd_rs JMP lcd_send_byte ;------------------------------ lcd_cursor_off: CLRB lcd_rs MOV W, #%00001100 ;display on,cursor off, blink off JMP lcd_send_byte ;------------------------------ lcd_cursor_on: CLRB lcd_rs MOV W, #%00001111 ;display on,cursor on, blink on JMP lcd_send_byte