Okay… nothing magical here. Just a boring old “Hello World”. There doesn’t seem to be any sample code for the newer enhanced mid-range PICs with a LCD that I could find online; perhaps you can find something better with Google than I will.
I promise you two things with this code: It’s fresh off the press so it’s ugly, sloppy, poorly commented, I didn’t use pagesel at all, it’s probably buggy as sh%t and it’s slow. Remember 300 baud modems and BBS chat rooms? yeah…. déjà vu. I was having problems with timing and I don’t have a proper logic analyzer and I didn’t care to do all the math.. so I went safe. In fact after pasting the code I see a huge obvious flaw as it is, you’ll see it, but anyways it’ll display Hello World. Enjoy.
Full disclosure: I was heavily inspired by this code as a building block from piclist.. mostly I wanted a quick and dirty way to go 4 bit.
;******************************************************************************* ; PIC 16F1509 LCD Test ; http://iradan.com ; ; ver 0.01 Hello World 4 bit, extra-dirty. ; ;*******************************************************************************
errorlevel -230, -302, -303 LIST R=DEC
#include "p16f1509.inc"
__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _CLKOUTEN_OFF __CONFIG _CONFIG2, _LVP_OFF & _STVREN_ON
;******************************************************************************* ;Device 16F1509 ; ; PIN DIAGRAM ; ; RA0 O x RC0 O LCD_1/11 ; RA1 I x RC1 O LCD_2/12 ; RA2 I x RC2 O LCD_3/13 ; RC3 O LCD_4/14 ; RA4 O x RB4 I RC4 O LCD_E/6 ; RA5 O x RB5 O x RC5 O ?FUTURE _ PWM? ; RB6 I RC6 O ; RB7 I RC7 O LCD_RS/4 ; ;*******************************************************************************
; GPR_VAR UDATA R_SEND_TMP RES 1 R_SEND_W_TMP RES 1 R_WDATA_TMP1 RES 1 R_WDATA_TMP2 RES 1 int_delay1 RES 1
;******************************************************************************* ; Reset Vector ;*******************************************************************************
RES_VECT CODE 0x0000 ; processor reset vector GOTO START ; go to beginning of program
;******************************************************************************* ; MAIN PROGRAM ;*******************************************************************************
MAIN_PROG CODE ; let linker place main program
banksel OSCCON movlw b'01111000' ; INTOSC 16MHz movwf OSCCON ; banksel OSCSTAT ; btfss OSCSTAT, HFIOFR ; Running? goto $-1 btfss OSCSTAT, HFIOFS ; Stable? goto $-1
goto START
;-------------------------------------------------------------
w_to_data BANKSEL PORTC movwf R_WDATA_TMP1 movf PORTC, W movwf R_WDATA_TMP2 bcf R_WDATA_TMP2, 0 bcf R_WDATA_TMP2, 1 bcf R_WDATA_TMP2, 2 bcf R_WDATA_TMP2, 3 btfsc R_WDATA_TMP1, 0 bsf R_WDATA_TMP2, 0 btfsc R_WDATA_TMP1, 1 bsf R_WDATA_TMP2, 1 btfsc R_WDATA_TMP1, 2 bsf R_WDATA_TMP2, 2 btfsc R_WDATA_TMP1, 3 bsf R_WDATA_TMP2, 3 movf R_WDATA_TMP2, W movwf PORTC return
pulse_e BANKSEL PORTC bsf PORTC,4 call delay2 BANKSEL PORTC bcf PORTC,4 call delay2 return
send_w movwf R_SEND_W_TMP swapf R_SEND_W_TMP, F movlw 0x0F andwf R_SEND_W_TMP, W call w_to_data call pulse_e
swapf R_SEND_W_TMP, F movlw 0x0F andwf R_SEND_W_TMP, W call w_to_data call pulse_e return
delay2 BANKSEL int_delay1 MOVLW 0x01 MOVWF int_delay1 OLOOP BANKSEL TMR0 CLRF TMR0 BANKSEL INTCON BCF INTCON,T0IF MOVLW 0xC0 ; PortB pull-ups are disabled, (c3=1:16) MOVWF OPTION_REG ; Interrupt on rising edge of RB0 ; Timer0 increment from internal clock ; with a prescaler of 1:4.
; The TMR0 interrupt is disabled, do polling on the overflow bit T0_OVFL_WAIT2 BTFSS INTCON, T0IF GOTO T0_OVFL_WAIT2
NOP BANKSEL int_delay1 DECFSZ int_delay1,1 GOTO OLOOP NOP ;... else
RETURN
START
BANKSEL PORTA CLRF LATA BANKSEL PORTB CLRF LATB BANKSEL PORTC CLRF LATC CLRF PORTC BANKSEL ANSELC ; CLRF ANSELC ;Digital IO BANKSEL PORTC ; CLRF PORTC BANKSEL TRISC ;Set all PORTC to outputs CLRF TRISC BSF PORTC,6
movlw b'11000111' ;configure TMR0 BANKSEL OPTION_REG movwf OPTION_REG
; GOTO LOOP ;<--------------DEBUG
BANKSEL PORTC bcf PORTC,7 ;LCD_RS movlw 0x02 ; Still in 8-bit, so appears as 0x20 to LCD call w_to_data call pulse_e
call delay2
movlw b'00101000' call send_w
movlw b'00001110' call send_w
movlw b'00000110' call send_w
call delay2
BANKSEL PORTC bcf PORTC,7 ; Command mode ; movlw b'00000010' ; Return cursor to home ; call send_w movlw 0x80 call send_w BANKSEL PORTC bsf PORTC,7 ; Data mode call delay2 ; Takes a couple of ms
movlw 'H' call send_w movlw 'e' call send_w movlw 'l' call send_w movlw 'l' call send_w movlw 'o' call send_w movlw ' ' call send_w movlw 'W' call send_w movlw 'o' call send_w movlw 'r' call send_w movlw 'l' call send_w movlw 'd' call send_w movlw '.' call send_w LOOP ;
NOP BANKSEL PORTC BCF PORTC, 5 call delay2
BANKSEL PORTC BSF PORTC,5 call delay2 GOTO LOOP ; loop forever
END