HD44780 LCD with PIC 18F2550

Guest #1903129
Rate this post
useful
not useful
Hi,

I want to control a HD44780 display with a PIC 18F2550 via a 4bit 
interface, but my routine doesn't seem to work. I've already looked on 
several pic sites but I just can't find my mistakes. So if someone could 
look over it, I would be very thankful :).

Thanks in advance
Attached files:
Guest #1903205
Rate this post
useful
not useful
Hi Maurius,

if you try to switch to 4 Bit Mode you`ve to keep in mind that
the HD Controller is still in 8 Bit Mode.

lcd_init:
         BCF      RS ; put into Comand Mode
  CALL  delay_16ms    ; should be 30 mS for Saftey
  MOVLW  b'00000010'
  MOVWF  PORTB    ;initialize display interface to 4bit
  CALL  lcd_enable

  CALL  delay_100us
  MOVLW  b'00001110'  ;2 rows
  CALL  lcd_sendcommand

  CALL  delay_100us
  MOVLW  b'00001100'  ;Display on
  CALL  lcd_sendcommand

  CALL  delay_100us
  MOVLW  b'00000110'  ;Cursor right, no shift
  CALL  lcd_sendcommand

  CALL  delay_100us
  MOVLW  b'00000001'  ;Clear display
  CALL  lcd_sendcommand

this should work now, please Report

PicArd
Guest #1903368
Rate this post
useful
not useful
Hi Maurius,

sorry my fault, try this

lcd_init:
  BCF   RS ; put into Comand Mode
  CALL  delay_16ms    ; should be 30 mS for Saftey
  MOVLW  b'00000010'
  MOVWF  PORTB    ;initialize display interface to 4bit
  CALL  lcd_enable

  CALL  delay_100us
  MOVLW  b'10000010'  ;2 rows
  CALL  lcd_sendcommand

  CALL  delay_100us
  MOVLW  b'00001100'  ;Display on, Cursor off, Blink off
  CALL  lcd_sendcommand

  CALL  delay_100us
  MOVLW  b'00000110'  ;Cursor right, no shift
  CALL  lcd_sendcommand

  CALL  delay_100us
  MOVLW  b'00000001'  ;Clear display
  CALL  lcd_sendcommand

in my Routines i do a read of the PortB first and store the content in a
FR. Then i add the changed 4 Bit for the LCD and write them back to the 
Port.
This prevent a malefunktion of RS E and so forth.

In your Sendcommand Routine the High Nibble is not changed to the I/O 
you use.

Better do:
lcd_sendcommand:
  MOVWF  scomm
         MOVLW  b'11110000'      ; High Nibble First
  ANDWF  scomm,w
         MOVWF    TEMP
         SWAPF    TEMP,w          ; HIGH Nibble change to Output Bit
  MOVFW    PORTB
  CALL  lcd_enable
  MOVLW  b'00001111'
  ANDWF  scomm, w
  MOVWF  PORTB
  CALL  lcd_enable
  CALL  delay_100us
  RETURN

The Same you do with the senddata

try it....
PicArd
Guest #1903420
Rate this post
useful
not useful
Hi Marius, got your Name wrong first sorry...

the sendcommand routine with Reading of PortB look like that:

lcd_sendcommand:
  MOVWF  scomm
         MOVLW  b'11110000'      ; High Nibble First
  ANDWF  scomm,w
         MOVWF    TEMP
         SWAPF    TEMP,f          ; HIGH Nibble change to Output Bit

  MOVFW  PORTB            ; read PortB
  MOVWF  TEMP2            ; Store Temporary
  MOVLW  b'11110000'      ; keep the I/O of PortB (HIGH NIBBLE)
  ANDWF  TEMP2,f          ; remove 4 BIT LCD DATA (LOW NIBBLE)of PORTB
  MOVF   TEMP2,w
  ADDWF  TEMP,w           ; Add the new 4 BIT LCD DATA
  MOVFW    PORTB          ; write to Port
  CALL  lcd_enable
  MOVLW  b'00001111'
  ANDWF  scomm, w
  ADDWF  TEMP2,w
  MOVWF  PORTB
  CALL  lcd_enable
  CALL  delay_100us
  RETURN

this is the best way to get out of conflict with the PORTB High Nibbles

PicArd
Guest #1903436
Rate this post
useful
not useful
Hello Marius,

i forgot one important thing....

lcd_sendcommand:

; FIRST put the LCD into Command Modus
  BCF    RS   ; PortB,4 in your Design
; ____________________________________

  MOVWF  scomm
         MOVLW  b'11110000'      ; High Nibble First
  ANDWF  scomm,w
         MOVWF    TEMP
         SWAPF    TEMP,f          ; HIGH Nibble change to Output Bit

  MOVFW  PORTB            ; read PortB
  MOVWF  TEMP2            ; Store Temporary
  MOVLW  b'11110000'      ; keep the I/O of PortB (HIGH NIBBLE)
  ANDWF  TEMP2,f          ; remove 4 BIT LCD DATA (LOW NIBBLE)of PORTB
  MOVF   TEMP2,w
  ADDWF  TEMP,w           ; Add the new 4 BIT LCD DATA
  MOVFW    PORTB          ; write to Port
  CALL  lcd_enable
  MOVLW  b'00001111'
  ANDWF  scomm, w
  ADDWF  TEMP2,w
  MOVWF  PORTB
  CALL  lcd_enable
  CALL  delay_100us
  RETURN

and for lcd_senddata:

lcd_senddata:

; FIRST put the LCD into DATA Modus
  BSF    RS   ; PortB,4 in your Design
; ____________________________________

  MOVWF  scomm
         MOVLW  b'11110000'      ; High Nibble First
  ANDWF  scomm,w
         MOVWF    TEMP
         SWAPF    TEMP,f          ; HIGH Nibble change to Output Bit

  MOVFW  PORTB            ; read PortB
  MOVWF  TEMP2            ; Store Temporary
  MOVLW  b'11110000'      ; keep the I/O of PortB (HIGH NIBBLE)
  ANDWF  TEMP2,f          ; remove 4 BIT LCD DATA (LOW NIBBLE)of PORTB
  MOVF   TEMP2,w
  ADDWF  TEMP,w           ; Add the new 4 BIT LCD DATA
  MOVFW    PORTB          ; write to Port
  CALL  lcd_enable
  MOVLW  b'00001111'
  ANDWF  scomm, w
  ADDWF  TEMP2,w
  MOVWF  PORTB
  CALL  lcd_enable
  CALL  delay_100us
  RETURN

These Routines i use in my LCD Applications and they work.

If this fail's try to increase the WAIT Time, this varrys from LCD to 
LCD

good luck

PicArd
Guest #1903575
Rate this post
useful
not useful
Still doesn't work. I also don't understand the sense in reading PORTB? 
Anyways my two routines look like this:
1
lcd_sendcommand
2
  BCF  RS
3
  MOVWF  scomm
4
  MOVLW  b'11110000'
5
  ANDWF  scomm, 0
6
  MOVWF  TEMP    ;swap nibbles to fit on the I/O
7
  SWAPF  TEMP, 1  
8
  MOVF  PORTB, 0  ;read PORTB
9
  MOVWF  TEMP2
10
  MOVLW  b'11110000'
11
  ANDWF  TEMP2, 1
12
  MOVF   TEMP2, 0
13
  ADDWF  TEMP, 0
14
  MOVWF  PORTB
15
  CALL  lcd_enable
16
  MOVLW  b'00001111'
17
  ANDWF  scomm, 0
18
  ADDWF  TEMP2, 0
19
  MOVWF  PORTB
20
  CALL  lcd_enable
21
  CALL  delay_100us
22
  RETURN
23

24

25
lcd_senddata
26
  BSF  RS
27
  MOVWF  sdata
28
  MOVLW  b'11110000'
29
  ANDWF  sdata, 0
30
  MOVWF  TEMP
31
  SWAPF  TEMP, 1
32
  MOVF  PORTB, 0
33
  MOVWF  TEMP2
34
  MOVLW  b'11110000'
35
  ANDWF  TEMP2, 1
36
  MOVF  TEMP2, 0
37
  ADDWF  TEMP, 0
38
  MOVWF  PORTB
39
  CALL  lcd_enable
40
  MOVLW  b'00001111'
41
  ANDWF  sdata, 0
42
  ADDWF  TEMP2, 0
43
  MOVWF  PORTB
44
  CALL  lcd_enable
45
  CALL  delay_100us
46
  RETURN
Guest #1903788
Rate this post
useful
not useful
Hello Marius,

the sense is simple, If you are using the PortB,7 as Input or Output
a move Instruction does a read of the TRIS instead of the Port and write
the Byte, this can result in "Funny" reaction of your Program later.

IMPORTANT:
Did you switch the PortB Function PIN's to be a explicit I/O on RB0-4 at 
the beginning of the program ? Please read the DATASHEET at section 10.2
The Anonciater are set after Power on, you have to switch them to be
an I/O !

PicArd
Guest #1903827
Rate this post
useful
not useful
Ok Marius,

i've got all Parts (18F1250) here to Test your Code, please attach your
full Sourcecode and i will test it tomorrow evening and report the 
result back to you.

BTW: i use MPLAB on Windows, i think you are using a Linux compiler?

best regards

PicArd
Guest #3002327
Rate this post
useful
not useful
You could also first test your communicaton protocol directly from a PC. 
I had a similar problem and I solved it this way. I made a HEX file that 
enables me to control all the PIC18 registers directly from my Windows 
application. Only after thorough testing I transfered the programming to 
PIC18.

Reply

Please log in before posting.

or

Log in with Google account

Registration is free and takes only a minute.

Register now