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.