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
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
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.
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
I swapped the nibbles so they fit to the I/O Ports I use, but it still doesn't work :(
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
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
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 |
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.
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
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
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
Thank you very very much for your help :). Yes i'm using a linux compiler (gpasm). Regards, Marius
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
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
Log in with Google account
No account? Register here.