tee_say
Newbie level 4
My LCD still cant display the word. My LCD is HD44780 16x2. This my code.
;------------------------------------------------------------------------------------------------------------------------
; Source code for the PIC16F876A based interfacing with HD44780 based 16x2 LCD.
;------------------------------------------------------------------------------------------------------------------------
;
; **LCD Pinouts
; 1 Vss - Ground, 3rd pin of the potentiometer
; 2 Vcc - 5V DC, 1st pin of the potentiometer
; 3 Vee - Middle pin of the potentiometer
; 4 RS - RC0 (Data - 1, Instruction - 0)
; 5 R/W - RC1 (R - 1, W - 0)
; 6 E - RC2 (Enable Pulse)
; 7 DB0 - RB0 (LSB)
; 8 DB1 - RB1
; 9 DB2 - RB2
; 10 DB3 - RB3 (Lower 4 bits)
; 11 DB4 - RB4 (Upper 4 bits)
; 12 DB5 - RB5
; 13 DB6 - RB6
; 14 DB7 - RB7 (MSB)
;
; Instruction Cycle Time = 1 / (4MHz / 4) = 1us per instruction
;------------------------------------------------------------------------------------------------------------------------
LIST P=16F876A
INCLUDE "p16f876A.inc"
; ERRORLEVEL -302
__CONFIG _PWRTE_OFF & _HS_OSC & _WDT_OFF & _LVP_OFF & _BODEN_OFF; configuration switches
N EQU 0x20
FIXDELAY EQU 0x21 ; General Purpose Registers.
org 0x00
movlw 0x00
movwf PCLATH
nop ; Reserved for ICD II.
goto start
start call initports ; Initialize Ports as output/inputs.
call INITLCD ; Initialize LCD.
main call testmsg ; Print test message on LCD
forever goto $
;------------------------------------------------------------------------------------------------------------------------
; Subroutine to initialize the PORTs as Inputs or Outputs.
;------------------------------------------------------------------------------------------------------------------------
initports
banksel PORTB
clrf PORTB ; Clear PORTs.
clrf PORTC
banksel TRISB
movlw 0x00 ; Define PORTB and PORTC as Outputs.
movwf PORTB
movwf PORTC
return
;------------------------------------------------------------------------------------------------------------------------
; Initialize the LCD.
;------------------------------------------------------------------------------------------------------------------------
INITLCD
BANKSEL PORTB ; Select Bank for PORTB.
MOVLW 0xE6 ; Call for 46ms delay
CALL NDELAY ; Wait for VCC of the LCD to reach 5V
BCF PORTC, 0 ; Clear RS to select Instruction Reg.
BCF PORTC, 1 ; Clear R/W to write
MOVLW B'00111011' ; Function Set to 8 bits, 2 lines and 5x7 dot matrix
MOVWF PORTB
CALL ENABLEPULSE
CALL DELAY50
CALL ENABLEPULSE
CALL DELAY50
CALL ENABLEPULSE
CALL DELAY50 ; Call 50us delay and wait for instruction completion
MOVLW B'00001000' ; Display OFF
MOVWF PORTB
CALL ENABLEPULSE
CALL DELAY50 ; Call 50us delay and wait for instruction completion
MOVLW B'00000001' ; Clear Display
MOVWF PORTB
CALL ENABLEPULSE
MOVLW 0x09 ; Call 1.8ms delay and wait for instruction completion
CALL NDELAY
MOVLW B'00000010' ; Cursor Home
MOVWF PORTB
CALL ENABLEPULSE
MOVLW 0x09 ; Call 1.8ms delay and wait for instruction completion
CALL NDELAY
MOVLW B'00001111' ; Display ON, Cursor ON, Blinking ON
MOVWF PORTB
CALL ENABLEPULSE
CALL DELAY50 ; Call 50us delay and wait for instruction completion
MOVLW B'00000110' ; Entry Mode Set, Increment & No display shift
MOVWF PORTB
CALL ENABLEPULSE
CALL DELAY50 ; Call 50us delay and wait for instruction completion
BSF PORTC, 0 ; Set RS to select Data Reg.
BCF PORTC, 1 ; Clear R/W to write
RETURN
;------------------------------------------------------------------------------------------------------------------------
; Enable Pulse for writing or reading instructions or data
;------------------------------------------------------------------------------------------------------------------------
ENABLEPULSE BCF PORTC, 2 ; 2us LOW followed by 3us HIGH Enable Pulse and 2us LOW.
NOP
NOP
BSF PORTC, 2
NOP
NOP
NOP
BCF PORTC, 2
NOP
NOP
RETURN
;------------------------------------------------------------------------------------------------------------------------
; N DELAY SUBROUTINE, delay in multiples of 200us up to 200us*255 = 51ms (or more)
;------------------------------------------------------------------------------------------------------------------------
NDELAY
MOVWF N ; N is delay multiplier
NOTOVER CALL DELAY200 ; Call for 200us
DECFSZ N, 1 ; Decrease N by 1
GOTO NOTOVER ; The delay isn't done
RETURN
;------------------------------------------------------------------------------------------------------------------------
; FIXED 200us DELAY (Possibly more due to execution time of the DECFSZ instruction.)
;------------------------------------------------------------------------------------------------------------------------
DELAY200
MOVLW 0x42 ; 66 LOOPS
MOVWF FIXDELAY ; 200us fixed delay
NOTDONE200 DECFSZ FIXDELAY, 1 ; Decrement of FIXDELAY
GOTO NOTDONE200 ; If 200us isn't up go back to NOTDONE200
RETURN ; If 200us is up then return to instruction.
;------------------------------------------------------------------------------------------------------------------------
; FIXED 50us DELAY (Possibly more due to execution time of the DECFSZ instruction.)
;------------------------------------------------------------------------------------------------------------------------
DELAY50
MOVLW 0x10 ; 16 LOOPS
MOVWF FIXDELAY ; 50us fixed delay
NOTDONE50 DECFSZ FIXDELAY, 1 ; Decrement of FIXDELAY
GOTO NOTDONE50 ; If 50us isn't up go back to NOTDONE50
RETURN ; If 50us is up then return to instruction.
;------------------------------------------------------------------------------------------------------------------------
; FIXED 20us DELAY (Possibly more due to execution time of the DECFSZ instruction.)
;------------------------------------------------------------------------------------------------------------------------
DELAY20
MOVLW 0x7 ; 7 LOOPS
MOVWF FIXDELAY ; 50us fixed delay
NOTDONE20 DECFSZ FIXDELAY, 1 ; Decrement of FIXDELAY
GOTO NOTDONE20 ; If 50us isn't up go back to NOTDONE50
RETURN ; If 50us is up then return to instruction.
;------------------------------------------------------------------------------------------------------------------------
; Fast Directive to write characters to LCD.
;------------------------------------------------------------------------------------------------------------------------
PUTCHAR
MOVWF PORTB ; A quicker way of writing characters to LCD.
CALL ENABLEPULSE
CALL CHKBUSY
RETURN
;------------------------------------------------------------------------------------------------------------------------
; Subroutine to check for the BUSY flag. Mostly used for instructions that follows up a character write.
;------------------------------------------------------------------------------------------------------------------------
CHKBUSY
bcf PORTC, 0 ; Clear RS to select Instruction Reg.
bsf PORTC, 1 ; Set R/W to read.
banksel TRISB ; Select Bank for TRISC.
movlw 0xFF ; Define all PORTC Pins as Inputs.
movwf PORTB
banksel PORTC ; Select Bank for PORTC.
bsf PORTC, 2 ; I tried to write my own code for this part initially but I wasn't successful.
movf PORTB, w ; Therefore, I implemented a portion of Peter Ouwehand's LCD Code.
bcf PORTC, 2 ; Will look more into the BUSY flag of the LCD.
andlw 0x80 ; Credits to Peter Ouwehand for his code here.
btfss STATUS, Z
goto CHKBUSY
banksel TRISB ; Select Bank for TRISB.
movlw 0x00 ; Define all PORTC Pins as Outputs.
movwf PORTB
banksel PORTC ; Select Bank for PORTA, B, and C.
bsf PORTC, 0 ; Set RS to select Data Register.
bcf PORTC, 1 ; Clear R/W to write.
return
;------------------------------------------------------------------------------------------------------------------------
; Position Cursor to the next line.
;------------------------------------------------------------------------------------------------------------------------
nextline
banksel PORTC
bcf PORTC, 0 ; Select Instructions Register.
bcf PORTC, 1 ; Select Write.
movlw b'11000000' ; Shift cursor to second line at 0x40 RAM address on LCD.
call PUTCHAR
return
;------------------------------------------------------------------------------------------------------------------------
; Clear screen and Cursor home.
;------------------------------------------------------------------------------------------------------------------------
clrscreen
banksel PORTC
bcf PORTC, 0 ; Clear RS to select Instructions Register.
bcf PORTC, 1 ; Clear R/W to select Write.
banksel PORTB
MOVLW B'00000001' ; Clear Display
call PUTCHAR
return
;------------------------------------------------------------------------------------------------------------------------
; Position Cursor to home position.
;------------------------------------------------------------------------------------------------------------------------
cursorhome
banksel PORTC
bcf PORTC, 0 ; Select Instructions Register.
bcf PORTC, 1 ; Select Write.
movlw b'00000010' ; Position cursor to home position.
call PUTCHAR
return
;------------------------------------------------------------------------------------------------------------------------
; A test message.
;------------------------------------------------------------------------------------------------------------------------
testmsg movlw D'49' ; Displays "I m working fine"
call PUTCHAR ; "Line 2 is alrite"
movlw A' '
call PUTCHAR
movlw A'm'
call PUTCHAR
movlw A' '
call PUTCHAR
movlw A'w'
call PUTCHAR
movlw A'o'
call PUTCHAR
movlw A'r'
call PUTCHAR
movlw A'k'
call PUTCHAR
movlw A'i'
call PUTCHAR
movlw A'n'
call PUTCHAR
movlw A'g'
call PUTCHAR
movlw A' '
call PUTCHAR
movlw A'f'
call PUTCHAR
movlw A'i'
call PUTCHAR
movlw A'n'
call PUTCHAR
movlw A'e'
call PUTCHAR
call nextline
movlw A'L'
call PUTCHAR
movlw A'i'
call PUTCHAR
movlw A'n'
call PUTCHAR
movlw A'e'
call PUTCHAR
movlw A' '
call PUTCHAR
movlw A'2'
call PUTCHAR
movlw A' '
call PUTCHAR
movlw A'i'
call PUTCHAR
movlw A's'
call PUTCHAR
movlw A' '
call PUTCHAR
movlw A'a'
call PUTCHAR
movlw A'l'
call PUTCHAR
movlw A'r'
call PUTCHAR
movlw A'i'
call PUTCHAR
movlw A't'
call PUTCHAR
movlw A'e'
call PUTCHAR
return
;------------------------------------------------------------------------------------------------------------------------
; End of programme.
;------------------------------------------------------------------------------------------------------------------------
end
;------------------------------------------------------------------------------------------------------------------------
; Source code for the PIC16F876A based interfacing with HD44780 based 16x2 LCD.
;------------------------------------------------------------------------------------------------------------------------
;
; **LCD Pinouts
; 1 Vss - Ground, 3rd pin of the potentiometer
; 2 Vcc - 5V DC, 1st pin of the potentiometer
; 3 Vee - Middle pin of the potentiometer
; 4 RS - RC0 (Data - 1, Instruction - 0)
; 5 R/W - RC1 (R - 1, W - 0)
; 6 E - RC2 (Enable Pulse)
; 7 DB0 - RB0 (LSB)
; 8 DB1 - RB1
; 9 DB2 - RB2
; 10 DB3 - RB3 (Lower 4 bits)
; 11 DB4 - RB4 (Upper 4 bits)
; 12 DB5 - RB5
; 13 DB6 - RB6
; 14 DB7 - RB7 (MSB)
;
; Instruction Cycle Time = 1 / (4MHz / 4) = 1us per instruction
;------------------------------------------------------------------------------------------------------------------------
LIST P=16F876A
INCLUDE "p16f876A.inc"
; ERRORLEVEL -302
__CONFIG _PWRTE_OFF & _HS_OSC & _WDT_OFF & _LVP_OFF & _BODEN_OFF; configuration switches
N EQU 0x20
FIXDELAY EQU 0x21 ; General Purpose Registers.
org 0x00
movlw 0x00
movwf PCLATH
nop ; Reserved for ICD II.
goto start
start call initports ; Initialize Ports as output/inputs.
call INITLCD ; Initialize LCD.
main call testmsg ; Print test message on LCD
forever goto $
;------------------------------------------------------------------------------------------------------------------------
; Subroutine to initialize the PORTs as Inputs or Outputs.
;------------------------------------------------------------------------------------------------------------------------
initports
banksel PORTB
clrf PORTB ; Clear PORTs.
clrf PORTC
banksel TRISB
movlw 0x00 ; Define PORTB and PORTC as Outputs.
movwf PORTB
movwf PORTC
return
;------------------------------------------------------------------------------------------------------------------------
; Initialize the LCD.
;------------------------------------------------------------------------------------------------------------------------
INITLCD
BANKSEL PORTB ; Select Bank for PORTB.
MOVLW 0xE6 ; Call for 46ms delay
CALL NDELAY ; Wait for VCC of the LCD to reach 5V
BCF PORTC, 0 ; Clear RS to select Instruction Reg.
BCF PORTC, 1 ; Clear R/W to write
MOVLW B'00111011' ; Function Set to 8 bits, 2 lines and 5x7 dot matrix
MOVWF PORTB
CALL ENABLEPULSE
CALL DELAY50
CALL ENABLEPULSE
CALL DELAY50
CALL ENABLEPULSE
CALL DELAY50 ; Call 50us delay and wait for instruction completion
MOVLW B'00001000' ; Display OFF
MOVWF PORTB
CALL ENABLEPULSE
CALL DELAY50 ; Call 50us delay and wait for instruction completion
MOVLW B'00000001' ; Clear Display
MOVWF PORTB
CALL ENABLEPULSE
MOVLW 0x09 ; Call 1.8ms delay and wait for instruction completion
CALL NDELAY
MOVLW B'00000010' ; Cursor Home
MOVWF PORTB
CALL ENABLEPULSE
MOVLW 0x09 ; Call 1.8ms delay and wait for instruction completion
CALL NDELAY
MOVLW B'00001111' ; Display ON, Cursor ON, Blinking ON
MOVWF PORTB
CALL ENABLEPULSE
CALL DELAY50 ; Call 50us delay and wait for instruction completion
MOVLW B'00000110' ; Entry Mode Set, Increment & No display shift
MOVWF PORTB
CALL ENABLEPULSE
CALL DELAY50 ; Call 50us delay and wait for instruction completion
BSF PORTC, 0 ; Set RS to select Data Reg.
BCF PORTC, 1 ; Clear R/W to write
RETURN
;------------------------------------------------------------------------------------------------------------------------
; Enable Pulse for writing or reading instructions or data
;------------------------------------------------------------------------------------------------------------------------
ENABLEPULSE BCF PORTC, 2 ; 2us LOW followed by 3us HIGH Enable Pulse and 2us LOW.
NOP
NOP
BSF PORTC, 2
NOP
NOP
NOP
BCF PORTC, 2
NOP
NOP
RETURN
;------------------------------------------------------------------------------------------------------------------------
; N DELAY SUBROUTINE, delay in multiples of 200us up to 200us*255 = 51ms (or more)
;------------------------------------------------------------------------------------------------------------------------
NDELAY
MOVWF N ; N is delay multiplier
NOTOVER CALL DELAY200 ; Call for 200us
DECFSZ N, 1 ; Decrease N by 1
GOTO NOTOVER ; The delay isn't done
RETURN
;------------------------------------------------------------------------------------------------------------------------
; FIXED 200us DELAY (Possibly more due to execution time of the DECFSZ instruction.)
;------------------------------------------------------------------------------------------------------------------------
DELAY200
MOVLW 0x42 ; 66 LOOPS
MOVWF FIXDELAY ; 200us fixed delay
NOTDONE200 DECFSZ FIXDELAY, 1 ; Decrement of FIXDELAY
GOTO NOTDONE200 ; If 200us isn't up go back to NOTDONE200
RETURN ; If 200us is up then return to instruction.
;------------------------------------------------------------------------------------------------------------------------
; FIXED 50us DELAY (Possibly more due to execution time of the DECFSZ instruction.)
;------------------------------------------------------------------------------------------------------------------------
DELAY50
MOVLW 0x10 ; 16 LOOPS
MOVWF FIXDELAY ; 50us fixed delay
NOTDONE50 DECFSZ FIXDELAY, 1 ; Decrement of FIXDELAY
GOTO NOTDONE50 ; If 50us isn't up go back to NOTDONE50
RETURN ; If 50us is up then return to instruction.
;------------------------------------------------------------------------------------------------------------------------
; FIXED 20us DELAY (Possibly more due to execution time of the DECFSZ instruction.)
;------------------------------------------------------------------------------------------------------------------------
DELAY20
MOVLW 0x7 ; 7 LOOPS
MOVWF FIXDELAY ; 50us fixed delay
NOTDONE20 DECFSZ FIXDELAY, 1 ; Decrement of FIXDELAY
GOTO NOTDONE20 ; If 50us isn't up go back to NOTDONE50
RETURN ; If 50us is up then return to instruction.
;------------------------------------------------------------------------------------------------------------------------
; Fast Directive to write characters to LCD.
;------------------------------------------------------------------------------------------------------------------------
PUTCHAR
MOVWF PORTB ; A quicker way of writing characters to LCD.
CALL ENABLEPULSE
CALL CHKBUSY
RETURN
;------------------------------------------------------------------------------------------------------------------------
; Subroutine to check for the BUSY flag. Mostly used for instructions that follows up a character write.
;------------------------------------------------------------------------------------------------------------------------
CHKBUSY
bcf PORTC, 0 ; Clear RS to select Instruction Reg.
bsf PORTC, 1 ; Set R/W to read.
banksel TRISB ; Select Bank for TRISC.
movlw 0xFF ; Define all PORTC Pins as Inputs.
movwf PORTB
banksel PORTC ; Select Bank for PORTC.
bsf PORTC, 2 ; I tried to write my own code for this part initially but I wasn't successful.
movf PORTB, w ; Therefore, I implemented a portion of Peter Ouwehand's LCD Code.
bcf PORTC, 2 ; Will look more into the BUSY flag of the LCD.
andlw 0x80 ; Credits to Peter Ouwehand for his code here.
btfss STATUS, Z
goto CHKBUSY
banksel TRISB ; Select Bank for TRISB.
movlw 0x00 ; Define all PORTC Pins as Outputs.
movwf PORTB
banksel PORTC ; Select Bank for PORTA, B, and C.
bsf PORTC, 0 ; Set RS to select Data Register.
bcf PORTC, 1 ; Clear R/W to write.
return
;------------------------------------------------------------------------------------------------------------------------
; Position Cursor to the next line.
;------------------------------------------------------------------------------------------------------------------------
nextline
banksel PORTC
bcf PORTC, 0 ; Select Instructions Register.
bcf PORTC, 1 ; Select Write.
movlw b'11000000' ; Shift cursor to second line at 0x40 RAM address on LCD.
call PUTCHAR
return
;------------------------------------------------------------------------------------------------------------------------
; Clear screen and Cursor home.
;------------------------------------------------------------------------------------------------------------------------
clrscreen
banksel PORTC
bcf PORTC, 0 ; Clear RS to select Instructions Register.
bcf PORTC, 1 ; Clear R/W to select Write.
banksel PORTB
MOVLW B'00000001' ; Clear Display
call PUTCHAR
return
;------------------------------------------------------------------------------------------------------------------------
; Position Cursor to home position.
;------------------------------------------------------------------------------------------------------------------------
cursorhome
banksel PORTC
bcf PORTC, 0 ; Select Instructions Register.
bcf PORTC, 1 ; Select Write.
movlw b'00000010' ; Position cursor to home position.
call PUTCHAR
return
;------------------------------------------------------------------------------------------------------------------------
; A test message.
;------------------------------------------------------------------------------------------------------------------------
testmsg movlw D'49' ; Displays "I m working fine"
call PUTCHAR ; "Line 2 is alrite"
movlw A' '
call PUTCHAR
movlw A'm'
call PUTCHAR
movlw A' '
call PUTCHAR
movlw A'w'
call PUTCHAR
movlw A'o'
call PUTCHAR
movlw A'r'
call PUTCHAR
movlw A'k'
call PUTCHAR
movlw A'i'
call PUTCHAR
movlw A'n'
call PUTCHAR
movlw A'g'
call PUTCHAR
movlw A' '
call PUTCHAR
movlw A'f'
call PUTCHAR
movlw A'i'
call PUTCHAR
movlw A'n'
call PUTCHAR
movlw A'e'
call PUTCHAR
call nextline
movlw A'L'
call PUTCHAR
movlw A'i'
call PUTCHAR
movlw A'n'
call PUTCHAR
movlw A'e'
call PUTCHAR
movlw A' '
call PUTCHAR
movlw A'2'
call PUTCHAR
movlw A' '
call PUTCHAR
movlw A'i'
call PUTCHAR
movlw A's'
call PUTCHAR
movlw A' '
call PUTCHAR
movlw A'a'
call PUTCHAR
movlw A'l'
call PUTCHAR
movlw A'r'
call PUTCHAR
movlw A'i'
call PUTCHAR
movlw A't'
call PUTCHAR
movlw A'e'
call PUTCHAR
return
;------------------------------------------------------------------------------------------------------------------------
; End of programme.
;------------------------------------------------------------------------------------------------------------------------
end