Quick and dirty Hello World, PIC 16F1509 + 4 Bit 44780 format LCD

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.

lcd_16f1509

;*******************************************************************************
; 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


					
					

Leave a Reply