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

Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.

Formatting
  • [c]C-Code[/c]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]
  • [[Title]] – link to an article
  • Link to another post: right-click its post ID (#8078628), copy the address, paste it into the text

More about formatting

Post long source code as an attachment, not in the text.

Already registered? Log in

Not shown to anyone. We send you a link; your post appears once you confirm it there.

By submitting you create a free account and accept the terms of use.