Physical connection of LCD using PIC18F4550 and xlcd.h
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.