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