EmbDev.net

Forum: µC & Digital Electronics HD44780 LCD with PIC 18F2550


von Marius (Guest)


Attached files:

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

von Tobias (Guest)


Rate this post
useful
not useful
look on this page ;) it is explain very easy.
http://www.sprut.de/electronic/lcd/index.htm

von PicArd (Guest)


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

von Marius (Guest)


Rate this post
useful
not useful
Thanks for your replies but it still doesn't work. I also made the 
delays a little bit longer, but that didn't help either.

von PicArd (Guest)


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

von Marius (Guest)


Rate this post
useful
not useful
I swapped the nibbles so they fit to the I/O Ports I use, but it still 
doesn't work :(

von PicArd (Guest)


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

von PicArd (Guest)


Rate this post
useful
not useful
and don't forget to change the senddata routine as well !

PicArd

von PicArd (Guest)


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

von Marius (Guest)


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

von Benni L. (sutter_cain)


Rate this post
useful
not useful
Which Compiler are you using?

MCC18 Compiler from Micrchip is shipped with a library for the hd44780. 
You only had to: #include xlcd.h

There must also be a docu somwhere. Otherwise just look in the Header 
itself.

von PicArd (Guest)


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

von PicArd (Guest)


Rate this post
useful
not useful
It should be like that:

init:

CLRF PORTB
CLRF LATB
MOVLW h'0E'  ; Switch AN = OFF
MOVWF ADCON1 ;
MOVLW h'00'h ; all PORTB = OUTPUT
MOVWF TRISB

hope that helps

PicArd

von Marius (Guest)


Rate this post
useful
not useful
Thank you very much for your help, but that didn't help either :(

von PicArd (Guest)


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

von Marius (Guest)


Attached files:

Rate this post
useful
not useful
Thank you very very much for your help :). Yes i'm using a linux 
compiler (gpasm).

Regards,
Marius

von PicArd (Guest)


Attached files:

Rate this post
useful
not useful
Hello Marius,

here is my changed version for Test, i will test it tomorrow evening 
with
Hardware... but maybe you won't wait and test.

good nigth
PicArd

von SV (Guest)


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.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.