I have been trying to get a Hitachi HD44780 LCD to work with my PIC18F452 for a few days now, with no luck. I have tried moving the data lines to different ports on the microchip, I've tried interfacing it with a few arduino's I have lying around, and also swapping the LCD out for another – but all that comes up on the display is a single line of block characters.
I am writing the PIC code in assembly and have it wired up on a breadboard – I have triple checked the connections to make sure that they are to the correct pins on the microchip. PIC has a 10Mhz crystal attached to it, using PORTE for LCD control pins, PORTB for LCD data and PORTD for LED outputs.
My init subroutine for the LCD is
LCD_init:
delay_t 15, msec, delay_timer
;; AN5/E0 = RW, AN6/E1 = R/S, AN7/E2 = E
movlw b'00000010' ;; PORTA shared w/ PORTE, set pins to DIGITAL
movwf ADCON1
clrf TRISE ;; Clear TRISE - PORTE as outputs
clrf TRISB ;; Set PORTD to outputs
;; Function Set - 8-bit, 1 Line, 5x8 map
movlw b'00110000' ;; 00l DataLength NumbLine Font x x
movwf PORTB
movwf PORTD
call LCD_send_command
delay_t 5, msec, delay_timer
call LCD_send_command
delay_t 100, usec, delay_timer
call LCD_send_command
;; Display On/Off
movlw b'00001110' ;; 00001 DisplayOn Cursor Blink
movwf PORTB
movwf PORTD
call LCD_send_command
;; Entry Mode set
movlw b'00000110' ;; 000001 Inc/Dec Shift
movwf PORTB
movwf PORTD
call LCD_send_command
;; Clear Screen
movlw b'00000001'
movwf PORTB
movwf PORTD
call LCD_send_command
;; Data write test
movlw b'01001001'
movwf PORTB
movwf PORTD
call LCD_send_char
return
My LCD_send_command subroutine:
LCD_send_command:
call LCD_busy ;; Wait for LCD to finish command
clrf TRISB ;; Set PORTD to outputs
bcf LCD_rw ;; Clear R/W
bcf LCD_rs ;; Clear R/S
bsf LCD_enable ;; Pulse E High...
delay_t 1, msec, delay_timer
bcf LCD_enable ;; ... then low
return
My LCD_send_char subroutine:
LCD_send_char:
call LCD_busy
clrf TRISB ;; Set PORTB to outputs
bcf LCD_rw ;; Clear R/W
bsf LCD_rs ;; Set R/S
bsf LCD_enable ;; Pulse E High...
delay_t 1, msec, delay_timer
bcf LCD_enable ;; ... then low
return
My LCD_busy subroutine:
LCD_busy:
setf TRISB ;; Set PORTD to inputs
bcf LCD_rs ;; R/S = 0
bsf LCD_rw ;; R/W = 1
btfss LCD_BUSY ;; BUSY_FLAG, skip if set
return
bra LCD_busy
Please let me know if there is anything else you need from me, any help would me much appreciated. Thank you.
Best Answer
It would appear that you have "issues" in your code.
The comments refer to PORTD but your code used PORTB.
Timing with the older HD44780 modules can be tricky.
You may find this complete and tested implementation useful:
This uses the 4-bit data and 3-bit control interface for the LCD module.
This code does not use the 8-bit data so you will need to modify the mask for LCD_DATA_BITS for the correct position of the nybble bits.