edofbrighton
Member
Hi,
Im trying to get my LCD display working (first time i've used one) and i can't figureout whats wrong. The code i'm using seems fine, but I'm not 100%. The only other reason i can think it wouldn't work is the contrast voltage Vo is wrong. I've tried altering it and i can change it between dark squares and no squares, but i never get any characters. Please can someone help me?
here is the code i'm using.
; DELAY EQUATES
CNT EQU 0X25 ;ADDRESS FOR COUNTER
CNT2 EQU 0X26 ;ADDRESS FOR COUNTER2
CNT3 EQU 0X27 ;ADDRESS FOR COUNTER3
CNT4 EQU 0X28 ;ADDRESS FOR COUNTER4
; LCD EQUATES AND DEFINES
#DEFINE DDRE TRISB,7 ;DATA DIRECTION
#DEFINE DDRRS TRISB,5 ;DATA DIRECTION
#DEFINE E PORTB,7 ;ENABLE LINE ON LCD
#DEFINE RS PORTB,5 ;INSTRUCTION/DATA SELECT
#DEFINE RW PORTB,6
TEMP_LCD EQU 0X3A ;STORAGE FOR LCD
LCD EQU PORTC ;LCD DATA PORT
CLRSCR EQU B'00000001' ;COMMAND FOR CLRSCR
HOME EQU B'00000010' ;SENDS CURSOR TO HOME
ON EQU B'00001100' ;TURNS ON THE DISPLAY
OFF EQU B'00001000' ;TURNS THE DISPLAY OFF
LEFT EQU B'00011000' ;LEFT SHIFT
RIGHT EQU B'00011100' ;RIGHT SHIFT
LIN2 EQU B'11000000' ;SETS TO LINE 2
;----------------------------------------
; VECTOR FOR NORMAL START UP.
ORG 0
GOTO START
; MAIN PROGRAM STARTS HERE:
START CLRW ; CLEAR W.
MOVWF PORTA ; ENSURE PORTA IS ZERO BEFORE WE ENABLE IT.
MOVWF PORTB ; ENSURE PORTB IS ZERO BEFORE WE ENABLE IT.
movwf PORTC
BSF STATUS,RP0 ; SELECT BANK 1
MOVLW H'00' ; MASK FOR PORTA FOR ALL OUTPUTS.
MOVWF TRISA ; SET TRISA REGISTER.
MOVLW H'00' ; MASK FOR PORTB FOR ALL OUTPUTS.
MOVWF TRISB ; SET TRISB REGISTER.
MOVLW H'00'
MOVwf TRISC
BCF STATUS,RP0 ; RESELECT BANK 0.
CALL INIT_LCD ; Initialse the LCD
bsf PORTA,2
MOVLW CLRSCR ; Clear the screen
CALL COMMAND ; Initiate the command in the W reg
MOVLW .1 ; wait for 1 second
BsF PORTA,2
BcF PORTA,2
MOVLW 'H' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'e' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'l' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'l' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'o' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW LIN2 ; Set display to line 2
CALL COMMAND ; Initiate the command in the W reg
MOVLW 'W' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'o' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'r' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'l' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'd' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW '!' ; send h
CALL DISPLAY ; Display the w reg on the LCD
goto $ ; Stop here
;**************************lcdv6******************************
;Porta 1 for the enable and porta 2 for rs/ portb for lcd data
;*************************************************************
;************************************************************
; Initialize the LCD
;************************************************************
INIT_LCD:
MOVLW .200 ;DELAY IN MICROSECONDS
CALL MDELAY ; '' ''
MOVLW B'00111100' ;tell display its two lines
CALL COMMAND ;output to the screen
MOVLW ON ;turn on display
CALL COMMAND ;output to the screen
MOVLW B'00000110' ;shift along every write
CALL COMMAND ;output to the screen
RETURN
;************************************************************
; This routine is to set the lcd to the second line
;************************************************************
SECOND_LINE:
MOVLW LIN2 ;set to line 2
CALL COMMAND ;output to the screen
RETURN
;************************************************************
; THis executes a command in the W reg
;************************************************************
COMMAND:
BCF RS
BCF RW ;command coming
MOVWF LCD ;PUT OUT ONTO PORT
MOVLW .200 ;delay time in microsecs
CALL MDELAY ;wait a while
MOVLW .250 ;delay time in microsecs
CALL MDELAY ;WAIT
BSF E ;make sure the enable line is up
MOVLW .200 ;delay time
CALL MDELAY ;wait a while
MOVLW .250 ;delay time in microsecs
CALL MDELAY ;WAIT
BCF E ;clock the data in
MOVLW .200 ;delay time
CALL MDELAY ;wait a while
MOVLW .250 ;delay time in microsecs
CALL MDELAY ;WAIT
BSF RS ;return to a data input
RETURN
;************************************************************
; This controls the module. When you call this
; routine, the contents of the 'w' register is
; displayed on the LCD screen. It is written in a
; module like this for portability!!
;************************************************************
DISPLAY:
BSF RS
BCF RW ;make sure it will accept data
MOVWF LCD ;send data to lcd
MOVLW .250 ;delay time in microsecs
CALL MDELAY ;WAIT
MOVLW .250 ;delay time in microsecs
CALL MDELAY ;WAIT
BSF E ;make sure the enable line is up
MOVLW .250 ;delay time
CALL MDELAY ;wait a while
MOVLW .250 ;delay time in microsecs
CALL MDELAY ;WAIT
BCF E ;clock the data in
MOVLW .250 ;delay time
CALL MDELAY ;wait a while
MOVLW .250 ;delay time in microsecs
CALL MDELAY ;WAIT
RETURN
;*************************************************************
; 1 MICROSECOND DELAY
;*************************************************************
MDELAY:
MOVWF CNT ;LOAD DELAY TIME
COUNT:
NOP ;TWO NO OPERATIONS
NOP ;TO OBTAIN THE DELAY
DECFSZ CNT,1 ;DECREMENT THE COUNTER
GOTO COUNT ;GOTO COUNT IF NOT FINISHED
RETURN
;*************************************************************
; SECOND DELAY, A DELAY FOR 1 SECOND!
;*************************************************************
SEC_DELAY:
MOVWF CNT ;LOAD DELAY TIME IN APPROX SECONDS
LOOP5:
MOVLW .1 ;LOAD W WITH .42
MOVWF CNT4 ;AND INTO COUNTER
LOOP4:
MOVLW .198 ;LOAD W WITH .198
MOVWF CNT3 ;AND INTO COUNTER
LOOP3:
MOVLW .199 ;LOAD W WITH .199
MOVWF CNT2 ;AND INTO COUNTER
LOOP2:
DECFSZ CNT2,1 ;DECREMENT THE COUNTER
GOTO LOOP2 ;GOTO LOOP AGAIN
DECFSZ CNT3,1 ;DECREMENT THE OTHER COUNTER
B LOOP3 ;IF NOT FINISHED, GOTO LOOP AGAIN
DECFSZ CNT4,1 ;DECREMENT THE OTHER COUNTER
B LOOP4 ;IF NOT FINISHED, GOTO LOOP AGAIN
DECFSZ CNT,1 ;DECREMENT THE OTHER COUNTER
B LOOP5 ;IF NOT FINISHED, GOTO LOOP AGAIN
RETURN
END
Im trying to get my LCD display working (first time i've used one) and i can't figureout whats wrong. The code i'm using seems fine, but I'm not 100%. The only other reason i can think it wouldn't work is the contrast voltage Vo is wrong. I've tried altering it and i can change it between dark squares and no squares, but i never get any characters. Please can someone help me?
here is the code i'm using.
; DELAY EQUATES
CNT EQU 0X25 ;ADDRESS FOR COUNTER
CNT2 EQU 0X26 ;ADDRESS FOR COUNTER2
CNT3 EQU 0X27 ;ADDRESS FOR COUNTER3
CNT4 EQU 0X28 ;ADDRESS FOR COUNTER4
; LCD EQUATES AND DEFINES
#DEFINE DDRE TRISB,7 ;DATA DIRECTION
#DEFINE DDRRS TRISB,5 ;DATA DIRECTION
#DEFINE E PORTB,7 ;ENABLE LINE ON LCD
#DEFINE RS PORTB,5 ;INSTRUCTION/DATA SELECT
#DEFINE RW PORTB,6
TEMP_LCD EQU 0X3A ;STORAGE FOR LCD
LCD EQU PORTC ;LCD DATA PORT
CLRSCR EQU B'00000001' ;COMMAND FOR CLRSCR
HOME EQU B'00000010' ;SENDS CURSOR TO HOME
ON EQU B'00001100' ;TURNS ON THE DISPLAY
OFF EQU B'00001000' ;TURNS THE DISPLAY OFF
LEFT EQU B'00011000' ;LEFT SHIFT
RIGHT EQU B'00011100' ;RIGHT SHIFT
LIN2 EQU B'11000000' ;SETS TO LINE 2
;----------------------------------------
; VECTOR FOR NORMAL START UP.
ORG 0
GOTO START
; MAIN PROGRAM STARTS HERE:
START CLRW ; CLEAR W.
MOVWF PORTA ; ENSURE PORTA IS ZERO BEFORE WE ENABLE IT.
MOVWF PORTB ; ENSURE PORTB IS ZERO BEFORE WE ENABLE IT.
movwf PORTC
BSF STATUS,RP0 ; SELECT BANK 1
MOVLW H'00' ; MASK FOR PORTA FOR ALL OUTPUTS.
MOVWF TRISA ; SET TRISA REGISTER.
MOVLW H'00' ; MASK FOR PORTB FOR ALL OUTPUTS.
MOVWF TRISB ; SET TRISB REGISTER.
MOVLW H'00'
MOVwf TRISC
BCF STATUS,RP0 ; RESELECT BANK 0.
CALL INIT_LCD ; Initialse the LCD
bsf PORTA,2
MOVLW CLRSCR ; Clear the screen
CALL COMMAND ; Initiate the command in the W reg
MOVLW .1 ; wait for 1 second
BsF PORTA,2
BcF PORTA,2
MOVLW 'H' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'e' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'l' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'l' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'o' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW LIN2 ; Set display to line 2
CALL COMMAND ; Initiate the command in the W reg
MOVLW 'W' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'o' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'r' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'l' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW 'd' ; send h
CALL DISPLAY ; Display the w reg on the LCD
MOVLW '!' ; send h
CALL DISPLAY ; Display the w reg on the LCD
goto $ ; Stop here
;**************************lcdv6******************************
;Porta 1 for the enable and porta 2 for rs/ portb for lcd data
;*************************************************************
;************************************************************
; Initialize the LCD
;************************************************************
INIT_LCD:
MOVLW .200 ;DELAY IN MICROSECONDS
CALL MDELAY ; '' ''
MOVLW B'00111100' ;tell display its two lines
CALL COMMAND ;output to the screen
MOVLW ON ;turn on display
CALL COMMAND ;output to the screen
MOVLW B'00000110' ;shift along every write
CALL COMMAND ;output to the screen
RETURN
;************************************************************
; This routine is to set the lcd to the second line
;************************************************************
SECOND_LINE:
MOVLW LIN2 ;set to line 2
CALL COMMAND ;output to the screen
RETURN
;************************************************************
; THis executes a command in the W reg
;************************************************************
COMMAND:
BCF RS
BCF RW ;command coming
MOVWF LCD ;PUT OUT ONTO PORT
MOVLW .200 ;delay time in microsecs
CALL MDELAY ;wait a while
MOVLW .250 ;delay time in microsecs
CALL MDELAY ;WAIT
BSF E ;make sure the enable line is up
MOVLW .200 ;delay time
CALL MDELAY ;wait a while
MOVLW .250 ;delay time in microsecs
CALL MDELAY ;WAIT
BCF E ;clock the data in
MOVLW .200 ;delay time
CALL MDELAY ;wait a while
MOVLW .250 ;delay time in microsecs
CALL MDELAY ;WAIT
BSF RS ;return to a data input
RETURN
;************************************************************
; This controls the module. When you call this
; routine, the contents of the 'w' register is
; displayed on the LCD screen. It is written in a
; module like this for portability!!
;************************************************************
DISPLAY:
BSF RS
BCF RW ;make sure it will accept data
MOVWF LCD ;send data to lcd
MOVLW .250 ;delay time in microsecs
CALL MDELAY ;WAIT
MOVLW .250 ;delay time in microsecs
CALL MDELAY ;WAIT
BSF E ;make sure the enable line is up
MOVLW .250 ;delay time
CALL MDELAY ;wait a while
MOVLW .250 ;delay time in microsecs
CALL MDELAY ;WAIT
BCF E ;clock the data in
MOVLW .250 ;delay time
CALL MDELAY ;wait a while
MOVLW .250 ;delay time in microsecs
CALL MDELAY ;WAIT
RETURN
;*************************************************************
; 1 MICROSECOND DELAY
;*************************************************************
MDELAY:
MOVWF CNT ;LOAD DELAY TIME
COUNT:
NOP ;TWO NO OPERATIONS
NOP ;TO OBTAIN THE DELAY
DECFSZ CNT,1 ;DECREMENT THE COUNTER
GOTO COUNT ;GOTO COUNT IF NOT FINISHED
RETURN
;*************************************************************
; SECOND DELAY, A DELAY FOR 1 SECOND!
;*************************************************************
SEC_DELAY:
MOVWF CNT ;LOAD DELAY TIME IN APPROX SECONDS
LOOP5:
MOVLW .1 ;LOAD W WITH .42
MOVWF CNT4 ;AND INTO COUNTER
LOOP4:
MOVLW .198 ;LOAD W WITH .198
MOVWF CNT3 ;AND INTO COUNTER
LOOP3:
MOVLW .199 ;LOAD W WITH .199
MOVWF CNT2 ;AND INTO COUNTER
LOOP2:
DECFSZ CNT2,1 ;DECREMENT THE COUNTER
GOTO LOOP2 ;GOTO LOOP AGAIN
DECFSZ CNT3,1 ;DECREMENT THE OTHER COUNTER
B LOOP3 ;IF NOT FINISHED, GOTO LOOP AGAIN
DECFSZ CNT4,1 ;DECREMENT THE OTHER COUNTER
B LOOP4 ;IF NOT FINISHED, GOTO LOOP AGAIN
DECFSZ CNT,1 ;DECREMENT THE OTHER COUNTER
B LOOP5 ;IF NOT FINISHED, GOTO LOOP AGAIN
RETURN
END