interfacing 16x2 lcd display with pic microcontroller supplier

In this tutorial, we’ll discuss how Alphanumeric LCD works and how to interface a 16×2 LCD with a microcontroller. You’ll learn how LCD (Liquid Crystal Display) works internally and how to send data and commands to it with a microcontroller, specifically PIC MCUs. And you’ll also learn how to develop a simple LCD Driver for your upcoming projects.

There are 2 practical LABs associated with this tutorial and here is a brief animation indicating what you’ll be able to do after completing this tutorial.

We typically add a 16×2 Alphanumeric LCD to small embedded systems & projects to enhance the user experience and UI of the device/project. You can use it to display text messages to the user, number, etc. Other types of LCDs provide different features such as the number of columns and rows (characters) and maybe colored display, and also different interfaces (parallel, spi, i2c, etc).

For this tutorial, we’ll consider the 16×2 LCD with a 16-pin header interface. Assuming it has the standard Hitachi LCD driver HD44780 controller. We’ll see how it works internally and how to interface it with microcontrollers. This small IC on the backside of the LCD module controls the LCD itself and accepts user commands and data sent by the master MCU.

The LCD module consists of 16×2 character cells, and each one of them is 5×8 dots. Controlling all of this is a tedious task for our main microcontroller to do. However, it doesn’t have to do. As there is a specific function controller on the LCD itself controlling the display while reading in the user’s commands & data. Here, I’ll be considering the Hitachi HD44780 controller.

The HD44780U has two 8-bit registers, an instruction register (IR) and a data register (DR). The IR stores instruction codes, such as display clear and cursor shift, and address information for display data RAM (DDRAM) and character generator RAM (CGRAM). The IR can only be written from the MPU. The DR temporarily stores data to be written into DDRAM or CGRAM and temporarily stores data to be read from DDRAM or CGRAM. Data written into the DR from the MPU is automatically written into DDRAM or CGRAM by an internal operation.

Display data RAM (DDRAM) stores display data represented in 8-bit character codes. Its extended capacity is 80 × 8 bits, or 80 characters. The area in display data RAM (DDRAM) that is not used for display can be used as general data RAM. Therefore, whatever data you send to the DDRAM, it’ll get displayed on the LCD. As long as the characters count is below 32 (for 16×2 LCD), it’ll be visible. Otherwise, written characters are stored in the DDRAM but not visible.

The table down below shows you the standard ASCII equivalent characters for the LCD display stored in the CGROM. And you can also create your custom characters and symbols if you want to, as we’ll see in a future tutorial. Note the “A” character which has a binary code of (0100 0001)b this is equivalent to 65 (the ASCII value for A in the ASCII table).

The cursor/blink control circuit generates the cursor or character blinking. The cursor or the blinking will appear with the digit located at the display data RAM (DDRAM) address set in the address counter (AC).

There are two ways to interface the LCD diver (controller) IC. You can use the full bus width (8-Bits) for data or alternatively you can use a 4-Bit interface for a reduced pin count needed to control the LCD. Specifically low pin count MCUs need to operate in the 4-Bit mode.

At the beginning of your system’s firmware, you should do some initialization steps for the LCD display before it’s usable. These steps are listed by the manufacturer of the LCD Driver IC and let your LCD know how it’s going to operate afterward. Which interface mode you’ll be using (4 or 8 bits), which font and so on.

The LCD takes some time to process commands or data. Therefore, there must be a small delay before issuing a new command to the LCD. This delay could be chosen arbitrarily as long as it’s longer than the time required by the LCD itself as indicated in the datasheet. Alternatively, you can just read the busy flag bit to know whether the previous command was successfully processed or not.

When a data or a command is sent to the LCD, the BF or D7 bit of the LCD becomes 1 and as soon as the command is successfully processed, the BF becomes 0.

And here is another table for some commands examples that you can test yourself. We’ll implement a couple of them in the following practical LABs and the rest are left for you to experiment with.

First of all, we should define the IO pins which we’ll be using to interface the LCD. It’s a recommended practice to isolate the hardware drivers firmware from the application layer and for the sake of portability of your code. This step makes your code less dependent on the specific MCU chip you’re using in the current project.

if at any point you found out that a specific pin must be changed, it’ll be an easy task to change it without searching your code and replacing each and every single occurrence for that line of code.

We’ll be using the 4-Bit interface in these tutorials as it’s the most common and most wished for. Nobody wants to consume all of his microcontroller’s pins just to hook an LCD. In fact, there is an I2C interface for the LCD which we’ll be using in a future tutorial and its main feature is reducing the pin count used for LCD control.

All in all, what we need now is a routine to parse out half-a-byte of data and send these bits to the corresponding pins of the IO pins associated with LCD Data. Here is a simple implementation for such a routine.

As we’ve discussed earlier in this tutorial, sending a command to the LCD should start with selecting the command register. Then the command data is transferred to the LCD io data pins. Then we should clock or send enable signal pulse. This routine is followed in general settings, whether it’s a 4-Bit interface of an 8-Bit.

Now, it’s time to create the LCD initialization routine. This function is an exact implementation of the steps we’ve discussed earlier in this tutorial. The 4-Bit interface initialization steps are indicated in a previous flow chart and our task right now is to implement it in C.

Sending an 8-Bit character to the LCD followed by an enable pulse (clock) will display that character on the LCD. However, in our case of using a 4-Bit interface, this step will be divided into two consequent steps. First of which is parsing the 8-Bit character into a high_nibble and low_nibble. Then we’ll send the high4 bits first followed by an EN clock, then we’ll send the low4 bits followed by another EN clock. And that’s it!

To send a string to the LCD, we’ll need a loop to repeatedly send characters to the LCD until a buffer end is found, and typically it’s the NULL character “\0”. Here is the implementation of this routine.

As you’ve seen in the previous sections, the datasheet of the LCD driver IC includes all the command that it could handle. And we’re going to add a couple of them to our LCD Driver code. All the rest are left for you to experiment with. Some specific commands may help you in specific projects and it’s up to you to decide on which one you need to implement.

The commands I’m going to implement in this section are the most used ones in different projects. And will help you get more familiar with sending commands in 4-Bit mode. And there is no difference from what we’ve done so far.

The header file includes only the declarations of sub-routines with simple documentation indicating the functionality of each routine and what it takes and returns if it’s not void, etc. The LCD.h header file will be something like this

It’s now way more clean/clear. And it’s easier to debug or extend the functionality of your LCD driver module. Here is the compiled project, download it and customize it as you wish.

Open the MPLAB IDE and create a new project name it “LCD_16x2_LAB1”. If you have some issues doing so, you can always refer to the previous tutorial using the link below.

Open the MPLAB IDE and create a new project name it “LCD_16x2_LAB2”. If you have some issues doing so, you can always refer to the previous tutorial using the link below.

In this tutorial, we’ve implemented some of the most common LCD commands that you are most likely to use in your various projects. However, there still are some other commands that you can implement and test on your own. Just get the datasheet and start tinkering around and if you feel stuck at any point, just drop me a comment and I’ll be here to help you.

As we’ve discussed in a previous section, it’s a recommended practice to separate your device drivers layer from the application layer as much as possible. It helps in terms of portability and enhances code re-usability. Each device driver should have a header file .h and a source file .c and you can #include this library in whichever project you want. Reducing the time to port your project to another platform (microcontroller).

You can use the sprintf function from the standard library by including stdio.h. Now you can combine numbers (int, float, etc) with text in a single array “string” that you can print out on your LCD. We’ve done this in a previous lab for the LM35 sensor.

interfacing 16x2 lcd display with pic microcontroller supplier

Here we are discussing various aspects of 16*2 Character LCD Interfacing with PIC Microcontroller in 8-bit Mode. A character LCD is the most basic form of an electronic display device which is widely used. The module will consist of 2 rows each with 16 columns which can display 16 characters. Already discuss LCD in4-bit mode in the chapter 4-bit LCD interfacing with pic microcontroller

Several other LCD modules are also available like 20×4 dimension LCD which can display 20 characters per line and 4 such lines would be available. The choice for the module depends on the requirement.

The main advantage of using a character LCD instead of a seven segment display and other multi-segment LEDs is that there is no limitation in displaying special & custom characters animations and so on. All character LCDs will have 16 pins among which 8 are data pins through which data or commands are passed into the LCD registers. A character LCD can be configured in 8 bit or 4-bit mode in which 8 data pins and 4 data pins are used respectively. This feature allows efficient use of the digital I/0 pins of the microcontroller.

The features of a character LCD module make it more suitable as an electronic display than 7 segment displays and other multi-segment display modules. Most importantly the module can be interfaced much easily unlike other modules with no complexity in both hardware and software. The 4-bit mode interfacing of the LCD module enables an efficient method of saving the number of general purposes I/O pins which is a major criterion for an embedded system designer. There is no limitation in characters which can be displayed using the module. The contrast of the module can be adjusted using the VEE pin of the module and LED backlight which makes the display more bright can be enabled with LED+ and LED- pin.

The RS (Register Select) pin of the LCD module is used to select the specific register. When RS is low, the command register is selected and when RS is high, data register is selected. State of R/W pin determines the operation to be performed whether to read or write data.

All instructions to be executed by the LCD are latched into the command register of the LCD. LCD commands include a clear display, the cursor on/off, display shift and so on.

Commands are instructions given to the LCD module to perform a predefined task. The task to be performed is defined by the manufacturer. Some of the LCD commands are listed below.

The register select pin of the LCD module should be connected to a general purpose I/O pin and the corresponding pin should be made low. R/W pin should be grounded to select the write operation. The command register will not be accessed.

Enabling the LCD would latch in the value of the data port into the command register of the module. Enabling the module involves applying a high to low pulse to the Enable pin of LCD.

Data write operation involves the similar steps as that of a command write operation except data register should be selected by setting the RS pin and grounding the R/W pin. Enabling the module would then latch in the value in the data port to the data register of the module and corresponding character will be displayed on the LCD module.

First of all, it needs to be initialized before writing data into the character LCD. The initialization is done to configure the module for the specific use. It involves writing some initialization commands into the command register. Some of the initialization commands include a command to turn the display on and cursor off, the command to set cursor at the preferred position and the command to set the option for cursor increment or decrement and so on.

The user can also display custom characters on LCD. More Details of displaying of custom character on LCD is specified in the Chapter Display Custom Character on 16*2 LCD using PIC microcontroller

interfacing 16x2 lcd display with pic microcontroller supplier

In the previous chapter, we have discussed how a character LCD is interfaced with a PIC microcontroller in 8-bit mode, where we used predefined characters stored in the LCD to display our data. In this article, we will learn more about the LCD and how we can create and use custom characters.

DDRAM or “Data Display Random Access Memory” is the working data buffer of the display. Each character on the display has a corresponding DDRAM location and the byte loaded in DDRAM controls which character is displayed.

CGROM or “Character Generation Read Only Memory” holds all the standard patterns for the 5 x 7 dot matrix characters. For instance, if you want to display character “A”, you would send ASCII code 65 (decimal) to the DDRAM. The display controller looks up the pattern of dots to display for this code in the CGROM and lights up the ones appropriate for “A”. The CGROM contents depend on the particular character set and model of display, US, Chinese etc. and cannot be changed.

CGRAM or “Character Generation Random Access Memory” allows the user to define special supplementary non-standard character types that are not in the CGROM. You can load your own dot pattern shapes and call these up for display.

For making custom patterns we need to write values to the CGRAM area defining which pixel to glow. These values are to be written in the CGRAM address starting from 0x40. CGRAM has a total of 64 Bytes. For LCD using 8×5 dots for each character, you can define a total of 8 user defined patterns (1 Byte for each row and 8 rows for each pattern).

Custom characters are assigned fixed display codes from 0 to 7 for pattern stored in the location pointed by CGRAM address 0x40, 0x48, 0x56… and so on. So, if the user wants to display second pattern (pattern stored at CGRAM address 0x48), simply call the data function with value 1 as an argument at a desired location in the LCD.

To display the sequence in the LCD, we need to specify the position on LCD and which pattern to display at the position. Provide adequate delay in between frames to observe the sequence distinctly.

interfacing 16x2 lcd display with pic microcontroller supplier

In this session we will see how to interface 16×2 LCD to PIC18F4550 microcontroller which is of family PIC18F. You can get information of 16×2 LCD in the session

PIC18F4550 belongs to the PIC18F family; PIC18F4550 is an 8bit microcontroller and uses RISC architecture. PIC18F4550 has 40 pins in PDIP (dual in line package) and 44 pin in TQFP (Quad flat package).

32KB flash memory, 2048 bytes of SRAM (synchronous Random Access memory), EEPROM (Electrically Erasable Program Read Only Memory) of 256 bytes are embedded in the PIC18F4550.

It has 35 I/O pins for interfacing and communication with other peripherals, 13channel of 10bit analog to digital converters which are used for interfacing and communicating the analog peripherals (DC motor, LDR, etc.).

PIC18F4550 has SPI (serial peripheral interface) and i2c (inter integrated circuit) for master and slave modes. It has SPP (Streaming Parallel Port) for USB streaming transfer.

PIC18F4550 is embedded with 4 timer modules (timer0 to timer3), 2 comparator modules and 3 external interrupt. It has Dual Oscillator options allow microcontroller and USB module to run at different clock speeds. It can operate in 2.0V to 5.5V

The resistor R1 is used for giving the contrast to the LCD. The crystal oscillator of 12 MHz is connected to the OSC1 and OSC2 pins of Pic microcontroller PIC18F4550 for system clock. The capacitor C2 and C3 will act filters to the crystal oscillator. You can use different ports or pins for interfacing the LCD before going to different ports please check the data sheet whether the pins for general purpose or they are special function pins.

Interfacing LCD to PIC is not different from interfacing to 8051. The basic concept and gist of the programming is almost same. Visit the following link for more information

Only the pins, registers and architecture using for interfacing will be different. When we look at the program, functions like initialization, sending data to the LCD will be almost same.

In the pic programming also for initializing the LCD the R/W pin should be low for writing the data, Enable pins should be high and register select pin (RS) should be high for writing the data. For sending a command the RS should be low, R/W pin should be low and enable pin should be high.

Install MPLAB in your system and create a new project, in selecting device and family select PIC18F family and add PIC18F4550 controller to your project.

interfacing 16x2 lcd display with pic microcontroller supplier

Thearduino LCD Keypad shieldis developed for Arduino compatible boards, to provide a user-friendly interface that allows users to go through the menu, make selections etc. It consists of a 1602 white character blue backlight LCD. The keypad consists of 5 keys select, up, right, down and left. To save the digital IO pins, the keypad interface uses only one ADC channel. The key value is read through a 5-stage voltage divider.

interfacing 16x2 lcd display with pic microcontroller supplier

This is our sixth tutorial in our PIC Tutorial Series, in this tutorial we learn Interfacing of 16x2 LCD with PIC Microcontroller. In our previous tutorials we have learnt the basics of PIC using some LED blinking Programs and have also learnt How to use Timers in PIC Microcontroller. You can check here all the tutorials on Learning PIC Microcontrollers using MPLABX and XC8 compiler.

This tutorial will be an interesting one because we will learn How to Interface 16×2 LCD with PIC16F877A, check the detailed Video at the end this tutorial. Gone are the old days where we used LEDs for user indications. Let us see how we can make our projects look more cool and useful by using LCD displays. Also check our previous articles on Interfacing LCD with 8051, with Arduino, with Raspberry Pi, with AVR.

To make things easier we have made a small librarythat could make things easy while using this LCD with our PIC16F877A. The header file "MyLCD.h" is given here for download, which contains all the necessary function to drive the LCD using PIC MCU. Library code is well explained by comment lines but if you still have doubts reach us through the comment section. Also check this article for Basic LCD working and its Pinouts.

Now, there are two ways to add this code into your program. You can either copy all the above lines of code in MyLCD.h and paste them before the void main(). Or you can download the header file using the link and add them to the header file of your project (#include " MyLCD.h ";). This can be done by right clicking on the header file and selecting Add existing Item and browsing to this header file.

Here I have copied and pasted the header file code into my main C file. So if you are using our code, then you don’t need to download and add the header file into your program, just use the complete Code given at the end of this Tutorial. Also note that this library will only support PIC16F series PIC Microcontroller.

void Lcd_Start():This function should be the first function that has to be called to start working with our LCD. We should call this function only once to avoid lag in the program.

void Lcd_Set_Cursor(x pos, y pos):Once started, our LCD is ready to take commands, we can instruct the LCD to set its cursor in you preferred location by using this function.  Suppose if, we need out cursor at 5th character of 1st row. Then the function will be void Lcd_Set_Cursor(1, 5)

Each time the Lcd_Print_Char(char data)is called, its respective character values is sent to the data-lines of the LCD. These characters reach the HD44780U in form of bits. Now this IC relates the bits to the character to be displayed by using its ROM memory as shown the below table. You can find bits for all the characters in the datasheet of HD44780U LCD Controller.

Now, since we are satisfied with our header file let’s build the circuit and test the program. Also check complete header file given in the link given above.

The hardware for this project is very simple. We are going to reuse the same PIC module that we used last time and connect the LCD module to our PIC using jumper wires.

interfacing 16x2 lcd display with pic microcontroller supplier

Using the serial enabled controller, it is easy to connect to any microcontroller that has a serial UART port such as an Arduino, AVR, PIC, etc. The SerLCD supports 16 and 20 character-wide screens with 2 or 4 lines of display.

Depending on your LCD"s specs, the input voltage may be 3.3V or 5V. For the LCDs listed below, the input voltage for the backpack must be 3.3V even though the silkscreen says 5V. The logic levels will be the same as the input voltage.

The LCDs listed below require an input voltage of 5V. Higher than 5.5V will cause damage to the PIC, LCD, and backlight (if attached). At 5V, the SerLCD uses 3mA with the backlight turned off and ~60mA with the backlight activated. The following LCDs do not have a SerLCD backpack.

The SerLCD and built-in serial LCDs comes equipped with a 10k potentiometer to control the contrast of the LCD. This is set during assembly and testing but may need correcting for your specific LCD module. Temperature and supply voltage can affect the contrast of the LCD. While powered, simply adjust the potentiometer with a screw driver.

The SerLCD v2.5 uses a general purpose, 1000mA NPN transistor to control the LCDs backlight. If you purchased the SerLCD module, you may use this pin as a general purpose, high power control pin. If you issue the backlight on/off command to the SerLCD or built-in serial LCD, the BL pin on the board can also be used to power / control other circuits with a maximum current of 1000 mA. This is usually the last pin on the top row of the LCD. Check your datasheet for proper pin outs.