LCDs are alphanumeric (or graphical) displays. They are frequently used in microcontroller based applications. There are many devices in the market which come in different shapes and sizes.

Some LCDs have 40 or more character lengths with the capability to display several lines. Some other LCD displays can be programmed to display graphic images. Some modules offer color displays, while some others incorporate back lighting so that they can be viewed in dimly lit conditions. In terms of interfacing technique, we can group them in two categories: Parallel LCDs and serial LCDs. Parallel LCDs like the popular Hitachi HD44780 series are connected to the microcontroller circuitry such that data is transferred to the LCD using more than one line and usually four data lines (4-bit mode) or eight data lines (8-bit mode) are used. This module is monochrome and comes in different shapes and sizes usually with character lengths of 8, 16, 20, 24, 32, and 40 and 1, 2 or 4 lines. Each character consists of 5×8 or 5×11 dot matrix.

Figure 1: A 2×16 LCD Display

Serial LCD is connected to a microcontroller using one data line only and data is transferred using the RS232 asynchronous data communications protocol. Serial LCDs are generally much easier to use, but they are more costly than the parallel ones. In this article we will discuss only the parallel LCDs, as they are cheaper and are used more commonly in microcontroller-based projects. Low-level programming of a parallel LCD is usually a complex task and requires a good understanding of the internal operation of the LCD, including an understanding of the timing diagrams. The good news, there are many LCD libraries that we can use to communicate with HITACHI HD44780 LCD controller. This xlcd library works only with PIC18F series microcontrollers, but you can modify it for other series or you can write your own library based on the LCD controller datasheet, there are many other libraries as we’re gonna learn in this tutorial

This LCD display device generally has 14 pins which are marked on the PCB with some models have 16 pins if the the device has a back-light built in.

Function

Pin Number

Name

Logic State

Description

Ground

1

Vss

–

0V

Power supply

2

Vdd

–

+5V

Contrast

3

Vee

–

0V to +5V

Control of operation

4

RS

0

D0-D7 are interpreted as commands

1

D0-D7 are interpreted as data

5

R/W

0

Write data (from microcontroller to LCD)

1

Read data (from LCD to microcontroller)

6

E

0

Access to LCD disabled

1

Normal operation

From 1 to 0

data/ commands are sent to LCD

Data/ commands

7

D0

0/1

Bit 0 LSB

8

D1

0/1

Bit 1

9

D2

0/1

Bit 2

10

D3

0/1

Bit 3

11

D4

0/1

Bit 4

12

D5

0/1

Bit 5

12

D6

0/1

Bit 6

14

D7

0/1

Bit 7 MSB

Table 1: Pin descriptions
Table 1 above shows the pin configuration and pin functions of a typical 14-pin LCD. If back-light is needed and available, The K pin should be connected to ground and pin A/Vee should be connected to positive supply via a series current limiting resistor as shown in figure 2 below.

Figure 2: LCD connection to Port B of PIC Microcontroller

The LCD controller contains three memory blocks:

DDRAM – Display Data RAM:This memory block is used for storing characters that should be displayed.
Each character occupies one DDRAM address. The first line addresses are from 00 to 27, the second line addresses start from 40 to 67 in hexadecimal. To move the cursor to the beginning of second line, the DDRAM address will be 0x40. For LCDs with more than 2 lines, please check their datasheet for more information.

CGRAM – Character Generator RAM: This memory contains the default character map with all characters that can be displayed on the screen. The addresses of CGROM memory locations match the characters of ASCII table.

Example:

Symbol

ASCII Code in binary

0

00110000

1

00110001

2

00110010

$

00100100

%

00100101

&

00100110

A

01000001

B

01000010

b

01100010

CGROM – Character Generator ROM:This memory is used to create your own characters.

MPLAB is phasing out the PIC18F Peripheral Library which is no longer included in XC8 compilers from version v1.35. In these versions, you have to download and install them separately into your compiler and they are now called Legacy Peripheral Libraries.

If you are using a latest XC8 compiler from v1.35 and you want to use MPLAB® Code Configurator (MCC) to generate drivers for your peripherals, you can use this LCD library supplied with Microchip PICDEM 2 Plus Demo Board Source Code. It can be used with PIC16F and PIC18F microcontroller series, all you need to do is to include the lcd.h and the lcd.c files, they include all the commonly used LCD functions. For more information, you can Download the HD44780 LCD controller datasheet.

LCD Connection:You can change the default LCD connections from PORTD to your preferred PORT by modifying the #define LCD_PORT in the lcd.h file and modifying the TRISregister in the lcd.c file. You can change as well the individual LCD pin connections by modifying the #define LCD_EN,#define LCD_RW and #define LCD_RS in the lcd.h file.

LCD_Initialize(): This routine initializes the LCD driver. This routine must be called before any other LCD routine is called.

LCDPutChar(): This function displays the specified ASCII character at current position on the LCD

LCDPutStr(): This routine writes string to LCD at current cursor position

LCDPutCmd(): This routine writes character to LCD command register

LCDGoto(): This function positions the cursor at the specified Line and column.

DisplayClr(): Clear the display

cursor_on():Switch ON the cursor

Watch The video ADC and LCD with MPLAB Code Configurator

Example:

In this example, we are configuring our PIC18F26K20 with MPLAB® Code Configurator (MCC). The PIC will use 8MHz internal oscillator, the MCLR pin will be disabled. The LCD is connected to PORTB as shown on figure 3 below.

In this example we’ll learn how to use the LCDPutChar(), LCDPutStr(), LCDClr() and LCDGoto() functions of the LCD library

// If using interrupts in PIC18 High/Low Priority Mode you need to enable the Global High and Low Interrupts

// If using interrupts in PIC Mid-Range Compatibility Mode you need to enable the Global and Peripheral Interrupts

// Use the following macros to:

// Enable high priority global interrupts

//INTERRUPT_GlobalInterruptHighEnable();

// Enable low priority global interrupts.

//INTERRUPT_GlobalInterruptLowEnable();

// Disable high priority global interrupts

//INTERRUPT_GlobalInterruptHighDisable();

// Disable low priority global interrupts.

//INTERRUPT_GlobalInterruptLowDisable();

// Enable the Global Interrupts

//INTERRUPT_GlobalInterruptEnable();

// Enable the Peripheral Interrupts

//INTERRUPT_PeripheralInterruptEnable();

// Disable the Global Interrupts

//INTERRUPT_GlobalInterruptDisable();

// Disable the Peripheral Interrupts

//INTERRUPT_PeripheralInterruptDisable();

LCDPutStr(" Hello World!");//Display String "Hello World"

LCDGoto(8,1);//Go to column 8 of second line

LCDPutChar('1');//Display character '1'

Delay_Seconds(1);// 1 second delay

LCDGoto(8,1);//Go to column 8 of second line

LCDPutChar('2');//Display character '2'

Delay_Seconds(1);// 1 second delay

LCDGoto(8,1);//Go to column 8 of second line

LCDPutChar('3');//Display character '3'

Delay_Seconds(1);// 1 second delay

DisplayClr();// Clear the display

LCDPutStr(" LCD Display");//Display String "LCD Display"

LCDGoto(0,1);//Go to second line

LCDPutStr("StudentCompanion");//Display String "StudentCompanion"

while(1)

{

// Add your application code

}

}

/**

End of File

*/

LCD Functions with PIC18 Peripheral Library

Microchip XC8 LCD library provides a large number of functions to control the HD44780 LCD controller with 4-bit and 8-bit data interface in the PIC18F Peripheral Libraries.

Watch the video tutorial

Important:

From XC8 v1.35, the Peripheral Libraries which include the LCD and other peripherals like ADC, SPI, I2C libraries are no longer included in the installation file as with previous versions. You can either write your own LCD library and use MPLAB code configurator to configure the other peripherals or the easiest is to download the Peripheral Libraries as a separate download and install them,. You can download them at microchip website under the MPLAB XC Compilers downloads tab. They are now called PIC18 Legacy Peripheral Libraries.

Four-bit interface-based text LCDs are the most commonly used LCDs because they save 4 microcontroller pins that can be used for other things.
You can access this library (only XC8 compiler v1.34 and older versions) by opening the help file (Help menu —> Help contents —>Search for LCD Function Descriptions or press F1 inside your project).

Function

Description

Code Example

BusyXLCD

Is the LCD controller busy?

while( BusyXLCD() ); // Wait here while LCD Controller is busy

OpenXLCD

Configure the I/O lines used for controlling the LCD and initialize the LCD.

Assuming a microcontroller clock frequency of 4 MHz, the instruction cycle time is 1 μs. With a clock frequency of 8 MHz, the instruction cycle time is 0.5 μs. The 18-cycle delay is obtained using no operation (NOP) statements, where each NOP operation takes one cycle to execute. The end of a function with no “return” statement takes two cycles. When a “return” statement is used, a BRA statement branches to the end of the function where a RETURN 0 is executed to return from the function, thus adding two more cycles.
For more on delay functions, check the article:

The physical connection between the LCD and microcontroller I/O ports is defined in file “xlcd.h” and the default settings use PORTB pins in 4-bit mode where the low 4 bits of the port (RB0-RB3) are connected to the upper data lines (D4–D7) of the LCD. This file should be changed if the LCD is to be connected differently or to another PORT. After modifying the LCD pin connection in the xlcd.h file, the user must recompile the XLCD routines and then include the updated files in the project. This can be accomplished by adding the XLCD source files into the project.
The LCD pin R/W can be connected to ground if there is no need to read from the LCD as in most cases. This can spare another pin on the microcontroller.
Figure 5 above shows the LCD in 4-bit mode connected to PIC18F2620.

Display the words ” Hello World” on first line of LCD and “LCD Display” on second line as shown in the circuit diagram on figure 5 above.
The MCLR is not enabled and the circuit uses internal oscillator at 8MHz so an external crystal device and a resistor to MCLR pin are not required.

Hi
Did you set correctly your configuration bits? Did you create the “LCD.h” configuration bits file before including it in your main source file?
Which file or line of code is complaining about?
Can your try to change this include: #include to this: #include

jome

sir,
i solved that error
there is no delay.h file in my includes folder
i reinstalled the compiler with an older version 1.30(i have 1.35) then it is ok for 18f series
is there any easy way to use it with 16f series?

It’s difficult to guess what could be your problem as you don’t give clear description of your problem, your code and your circuit. any of these could be the problem. have you watched the LCD tutorial video?
How are you connecting your LCD?

Gunther74

I have folowed the video and the code provided on this page.
i only have a aditional loop in the main routine that looks for inputs on portA and send outputs to portC. I just noticed that these i/o doesnt work with the lcd code included. 2 outputs are high. Strange enough becouse the lcd is connected to portB.

Gunther74

To make sure i didn’t misstype i downloaded the files.
I have Text out 3 lines for build error:
OSC = INTIO67
BOREN = OFF
CCP2MX = PORTC
After build, only black blocks. So there is no custom code anymore

olami

//*************The following is the error i do get when i follow the LCD tutorial…..pls kindly help me out…the error is really killing my spirit… i observe the red line error as show in the image bellow in your tutorial too but am very surprised it build without error…pls help me sir i will be glad
***************//

1. Try to add this include: #include
2.Did you set correctly the configuration bits of your PIC?
3. Are you using the same PIC as in our example?

olami

Yes sir i used same pic as in the tutorial i follow the tutorial from a-z but i keep getting errors but why your code in the tutorial give error red line sign and it w[ork fine?…..secondly how will i create the #include<plibxlcd.h….will i jsust include it in my code or i will have to create it first …pls how will i create it….i

Hi the reason the code in the tutorial works but still showing red lines is because we did not expressly include the xlcd library, but when we compile the code, as it’s in the correct directory, the compiler can still find it.
If you want to remove the red lines, add this code, you don’t have to include it as it’s there already: #include
Check out this tutorial: https://youtu.be/RkDN2GW_SxU

You can generate it yourself, It’s more or less the same as this one, you just have to change your configuration bits and make some few changes in the main code.

Ricardo Am

Try connecting RW to RB6, I solved the same problem with my 18f2550

Ricardo Am

could you guys help me to understand what im doing wrong? I tried to change the por on my pic 18f4550 and then i get this error:
:0: error: (500) undefined symbols:
_SetDDRamAddr(dist/default/productionPROJECT2.X.production.obj) _WriteCmdXLCD(dist/default/productionPROJECT2.X.production.obj) _putrsXLCD(dist/default/productionPROJECT2.X.production.obj) _OpenXLCD(dist/default/productionPROJECT2.X.production.obj) _BusyXLCD(dist/default/productionPROJECT2.X.production.obj)

Are you changing the PIC or a PORT where you connected your LCD? your question is not clear.

Ricardo Am

I was trying to change the data port portb for portd. But it gave that error. I did the first example and it works well, but when i did the same example it doesn’t work. I noticed this. P.D. I’m mexican

Then you must watch the video on this page: LCD Connection to PORTC, it is going to explain to you how you can connect an LCD display to another PORT like PORTC or PORTD.

attersee

Dear Sir, May I kindly ask for support with your XC8 LCD example? Actually, I decided
continuously to move from MPASM to C language. But after little success, I am confronted with a heavy beginner’s roadblock.
Using MPLABX V3.10 and XC8 V1.35 I created a PIC18F2620 project and loaded your LCD sample code one by one as .c and .h files. When I build the project there are not just warnings, but also error messages appearing (see output cutout):

Finally, build failed. Trying to eliminate the warnings (361), I tried to include and , but neither was accepted. Ok, I can leave with the warnings, but unfortunately not with the undefined identifier error (192).
I already spent hours searching around for a solution without success. I hope you can help me to overcome this issue. Thank you.

Can you watch our Video tutorial on this page, it explain step by step how to do it.

attersee

Thanks for your reply. Sorry, but I strictly tried to follow the videos, typed all the code manually and got this error 192. Suspecting a typing error, I finally downloaded the files. But nothing changed. Can you give me a hint about the mistake I made please?

It’s difficult for us to guess what could be your problem as you didn’t post the fullcode. Can you post your full code or your project on our Facebook page?

attersee

Unfortunately, I am not on Facebook, but I communicate via Disqus. Is it possible to send the code this way or by e-mail? But as I said, it is 100 % your code. The only difference is, that I named the files goC_06.c and goC_06.h. Of course I changed #include “LCD.h” to #include “goC_06.h” in the .c file.
I could also send the whole output file, because the copy above is just part of it, as you know.

I just found the solution. ‘delays.h’ and ‘xlcd.h’ are no longer included in the
standard archives. One has to download the ‘Peripheral Library’ from Microchip, install it and make it accessible by activating
Run / Set project configuration / Customize / XC8 compiler / XC8 global options / XC8 linker / Link in Peripheral Library.
Your changes in the code stimulated the solution finally. Thank you very much.

Thank you very much for your feedback, we have just noted that the new XC8 compiler v1.35 doesn’t include the Peripheral Library anymore by default. If they are needed, they have to be downloaded as Legacy peripheral Library. Now one has to use the Code Configuration.
Thanks because now we will be able to update and help others who will need this information.

attersee

My last post wasn’t the end of the story. First I was glad that the sample code compiled anyway. Then I made the changes in xlcd.h for using PortC instead of PortB as LCD-Port, to make PortB available for interrupts. But unfortunately the compiler said: „error: (255) not a member of the struct/union“. From a tread at the Microchip Forum I learned that I had to change the bit definitions:

#define RW_PIN LATBits.LATCx to #define RW_PIN LATCx

#define TRIS_RW TRISBits.TRISCx to #define TRIS_RW TRISCx
etc.

Finally it compiled with no error, – but still no symbols on the LCD. Again a step backward to PortB. The same effect, nothing to see on the LCD (KS0066U controller). Then with the debugger I realized that the library routine busyxlcd.h has been waiting in a continuous loop for the busy bit. Simply, busyxlcd.h needs the R/W signal. With the R/W line connected, symbols appeared on the screen, but with a wrong (Chinese?) character on LCD position 00. For the time being I regarded it as minor flaw and turned to PortC again.

After a long search for possible causes, I found that in xlcd.h the
instruction code in #define SHIFT_CUR_RIGHT 0b00000101 doesn’t match with the datasheet. I changed the code to 0b000000110. Furthermore, in openxlcd.c the corresponding line had to be changed in the entry mode setting:

WriteCmdXLCD(SHIFT_CUR_LEFT)
to WriteCmdXLCD(SHIFT_CUR_RIGHT)

… and the display was alive. But there was still this wrong character at position 00.

By carefully reading the headers of the library routines WriteDataXLCD and SetDDRamAddr, I put attention on the note “The user must check to see if the LCD controller is busy before calling this routine”. onsequently, I called ‘while(BusyXLCD())’ in advance, respectively. Then the LCD did what one expects it should do.

After all, it wasn’t an easy C-newbies project, but with some educational contents.

My impression is that different library routines have been used in the sample video, otherwise the same / or similar problems should have been appeared.

I summarized this experience, because it might help other people pulling themselves out of the LCD swamp by the scruff of its own neck.

while (BusyXLCD());
SetDDRamAddr(0x02); // 2nd Char in top line
while (BusyXLCD());
putrsXLCD(“Craig”);

while (1)
{
}

}

So according to the OSCCON bits I have set 8mhz internal osc. And I have defined _XTAL_FREQ as 8000000. But when I run in proteous, then pins have been sent data but nothing is shown on the display. Any ideas?

If you are using XC8 v1.35, the Peripheral Libraries which include the LCD library that you are using I presume because of the delays you have declared are no longer included in the installation file as with previous versions. You can either write your own LCD library or the easiest is to download the Peripheral Libraries as a separate download and install them,. You can download them at microchip website under the MPLAB XC Compilers downloads tab. They are now called PIC18 Legacy Peripheral Libraries.
Download: PIC18 Legacy Peripheral Libraries (http://www.microchip.com/pagehandler/en-us/devtools/mplabxc/home.html)

Craig

I have the Peripheral libraries already, and they work well with the Pic18F14k50, but not the pic18f25k22. Im stumped. Im wondering if I have a timing issue somewhere?

If you are using XC8 v1.35, the Peripheral Libraries which include the LCD library are no longer included in the installation file as with previous versions. You can either write your own LCD library or the easiest is to download the Peripheral Libraries as a separate download and install them,. You can download them at microchip website under the MPLAB XC Compilers downloads tab. They are now called PIC18 Legacy Peripheral Libraries. I believe that is where your problem lies.

Hi, thank you for this good tutorial
i followed all step you said in the video and saw comments that help me fix XC8 v1.36 problem and when i run the program on proteus it works well but in real device it doesn’t work any solution for this?

If you say you are inexperienced, then started writing your own drivers won’t be easy for you, you should consider the basics first, use the already available drivers then write your own. Read the touch screen datasheet then you’ll understand what is required.
Thanks

Bhavani A

Ok. I have got some example drivers but the problem is many header files are missing in new mplab compiler. When asked about this problem to displaytech( company providing Touch screen) said the microchip people might have renamed their APIs and other files so it may not work. Example #include “Hardwareprofile.h”, displaydriver etc are missing.

Hi, I did watch the video, but In the post you linked xc8 code which is different that the one in this video. Is there an example of changing the pins in LCD example with MPLAB, or did you upload the code from this video in another post ? Thank you

We don’t understand your question. In the video we connected the lcd to PORTC by modifying the xlcd.h file when you are using PIC18F peripherals libraries. In the second video we used a different lcd library for people who are using mplab code configurator. With this library it’s easy to change the connection by simply modifying those files. Did you watch those videos to the end?

Octavio

Hi, great videos, they are very useful. I have a question, why i have the next warnings: warning: (520) function “_DelayXLCD” is never called, and the other warning is warning: (752) conversion to shorter data type. The last one appear in the fuction OPENXLCD.

The other question is: these warnings are very important when I pass the program to PIC? Because in Proteus 8, the simulation runs good, but in physic, the LCD only show black rectangles in the first line.

If the project works well in Proteus, then those warnings shouldn’t be a problem. Add this include and if everything is correct than the warnings should disappear:
#include
#include
If in physical hardware the LCD displays only black rectangles it might be the contrast is too high, try to vary the contrast of your LCD by turning the variable resistor connected VEE on the LCD.

Hi. Which library are you refereeing to? we used two libraries in this article, the LCD library that we used with the MPLAB Code Configurator, you can use this library with PIC16F series, but the other library XLCD (with PIC18F Peripheral Library), you can’t use this one, this is only for PIC18F series.

Aravind NA

lcd library and i am using 1.37xc8 version….can i use lcd library for pic16….one doubt that
#include “LCD.h”
#include
#include
#include

No. This code cannot be used. This library is only for PIC18F series. Use the first library on this article. you can also watch the video tutorial : ADC and LCD with MPLAB code configurator to learn how to use it.

Cyril Lassouane

Hi. I’m using a PIC18F87J11. I wanted to try your code but there was many errors because of your pragma definitions so I put those instead:

Stay Update:

Search Here

Translate Website into your Language

Please support our work with a Donation

Writing tutorials and recording tutorials videos requires a lot of resources and time. If you found these tutorials helpful, please show your support and donate any amount you wish so that we can do even more.
Thanks