Electronic – Physical connection of LCD using PIC18F4550 and xlcd.h

lcdpicwiring

I want to turn on an LCD with a PIC18F4550 and the periperial library xlcd.h. My code is the next:

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <plib/xlcd.h>
#include <plib/delays.h>

#pragma config PLLDIV = 5, CPUDIV = OSC1_PLL2, USBDIV = 2
#pragma config FOSC = HSPLL_HS, FCMEN = OFF, IESO = OFF
#pragma config PWRT = OFF, BOR = OFF, VREGEN = OFF
#pragma config WDT = OFF, WDTPS = 32768
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF
#pragma config STVREN = ON, LVP = OFF, ICPRT = OFF, XINST = OFF

#define _XTAL_FREQ 48000000

void DelayFor18TCY(void);
void DelayPORXLCD(void);
void DelayXLCD(void);

int main() {

 OpenXLCD(FOUR_BIT & LINES_5X7);

 while(BusyXLCD());

 WriteCmdXLCD(0x06);

 WriteCmdXLCD(0x0C);

 while(1)
 {

    SetDDRamAddr(0x00);
    putrsXLCD("HELLO");

    SetDDRamAddr(0x40);
    putrsXLCD("WORLD");
 }

}
void DelayFor18TCY(void)
{
 Delay10TCYx(120);
}

void DelayPORXLCD(void)
{
 Delay1KTCYx(180);
 return;
}

void DelayXLCD(void)
{
 Delay1KTCYx(60);
 return;
}

And works perfectly in Proteus

enter image description here

The problem comes with making the real circuit, since the LCD only keeps blinking in the first position:

enter image description here

My diagram is the next ( https://i.stack.imgur.com/pDpHV.png ) :
enter image description here

I don't see why is not working, everything is connected as the diagram shows. The LCD works fine when I use an Arduino. All the vss connections have a common ground and the same for the vdd connections that have a common 5V. I even have decoupling capacitors for the vdd pins. I would appreciate any suggestions, thanks

Additional info:
I am using the PICkit3 for program it and a 5V DC adapter of a cellphone. I have already tried with 2 different adapters and two different PIC18F4550

Best Answer

I'm away from my PIC18 development environment, but I can see one problem in your setup (although it might not be the only one).

Summary:

Your code is trying to read the LCD controller's "busy status" but your hardware design doesn't support that. Result: Your code will either hang or not wait long enough for the LCD controller to initialise - either way, your LCD is unlikely to display characters correctly, which is the problem you are reporting.

Explanation:

It may help to know that, although it is often written as "R/W", that signal to an LCD module using an HD44780-compatible controller like your one, is really \$\small{\textrm R/}\overline{\textrm W}\$ (see the HD44780 datasheet like this one for more information). This means for that signal:

  • logic 1 = Read from LCD (e.g. check the LCD controller's busy status)
  • logic 0 = Write to LCD (e.g. send commands and characters to display)

Your "real schematic" shows that you have connected the LCD \$\small{\textrm R/}\overline{\textrm W}\$ pin (pin 5) to Gnd. This is quite common, but it means that you cannot read the LCD controller's "busy status". That is because the LCD controller will be expecting all data to be writes to the LCD, when its \$\small{\textrm R/}\overline{\textrm W}\$ input is grounded (logic 0).

However you are also using the Microchip peripheral library function BusyXLCD() which does attempt to read the LCD controller's status. Typically, assuming it is configured for Port B, the library expects the LCD \$\small{\textrm R/}\overline{\textrm W}\$ pin to be connected to PIC RB6 pin. On your schematic, we see there is no connection between those pins.

Therefore depending on whether that PIC pin floats high or low, the library code will either:

  • spin-wait and hang when you call while(BusyXLCD()); so the rest of your code doesn't execute, or;

  • immediately execute the following statement i.e. it will not wait long enough for the LCD controller to become ready before sending further commands to it, resulting in malfunction of the LCD display.

Fix:

Either:

  • Change your main code to use appropriate delays instead of calling BusyXLCD(), or;

  • Assuming that the configuration settings in your xlcd.h expect the LCD \$\small{\textrm R/}\overline{\textrm W}\$ pin (pin 5) to connect to PIC RB6, and assuming (as seems to be true in the schematic) that the PIC and LCD are using the same power supply (i.e. the same Vdd voltage), then simply connect those two pins. That should allow the calls to BusyXLCD() to work as intended.


There might be more problems in your design, but you need to fix that one.