DEV Community

Cover image for Interfacing a 16x2 LCD display with 8051 microcontrollers
Krypton | Madhusudan Babar for Madhusudan Live

Posted on • Originally published at madhusudan.live on

Interfacing a 16x2 LCD display with 8051 microcontrollers

Introduction

LCDs are used for various applications in electronic systems, almost every kiosk, any kind of meter, signboards and almost all the systems we see, use smaller or bigger display. today we will cover how to interface a 16X2 Liquid Crystal Display with an 8051/52 microcontroller, the connections and code is provided below.

8051/8052 Family

Firstly let me brief you about the 8051 series, 8051 is a popular 8-bit microcontroller family developed by Intel, this family had 4KB of ROM or program memory and a 128 bytes of RAM, the 8052 family is also similar to 8051 just it has an additional ROM of 4KB i.e. total of 8KB and also additional RAM of 128 bytes, making a total of 256bytes, We will be using AT89S52 , it is the widely popular microcontroller for small-scale projects with powerful hardware. it sports 8 KB of program memory (ROM) and 256 bytes of RAM and 4 ports, for peripherals. after its launch it became widely popular for various applications and currently it is available in multiple versions in market by different vendors, this hardware is more than enough for our use case, we can also use AT89S51 as well.

Components

  • 1 - 16X2 LCD
  • 1 - AT89S51/2 Microcontroller ( For controlling the LCD )
  • 1 - Potentiometer ( For adjusting the Backlight of LCD )
  • 12 Approx. - connecting wires

16X2 LCD

In your day to day life, you must have seen small green coloured displays from various appliances like DVD Players, Medical Devices, Industrial Control Panels, Energy Meters. those green coloured display are called as 16X2 LCD displays, The term LCD stands for Liquid Crystal Display the 16 refers to the number of rows and the 2 as number of columns. these are used in variety of applications like many consumer electronic devices, embedded systems, control panels, information kiosks, weighing machines at public places and the list goes on.

The 16X2 LCD can be configured in two modes i.e. 8-bit mode and 4-bit mode, for the sake of simplicity we will be using 8-bit mode. So connect the data pins to the desired port of the microcontroller, but be careful with the PORT 0, it doesn’t have internal pull-ups, so in order to use the PORT 0 you need to connect external pull-up resistors.

Pin configuration of 16x2 LCD

sr no name function
1 VSS ground
2 VDD power supply ( +5V )
3 VEE contrast
4 RS register select
5 R/W read / write 0=write 1=read
6 E enable
7-14 Data Data lines
15 A Anode ( LCD Backlight )
16 K Cathode ( LCD Backlight )

Here I am connecting the LCD to PORT 1, and other pins i.e.

  1. RS ( Register Select ) : PORT2_0
  2. R/W ( Read/Write ) : PORT2_1
  3. E ( Enable ) : and PORT2_2.

Block diagram of LCD interfaced with AT89s52 microcontroller
Block Diagram of 16x2 interfaced with AT89s52 MCU

For simplicity, here I have not shown the LCD contrast, VCC, GND, and pins but make their connections too, connect the VCC to +5V, GND to ground and the contrast to the Ground through a potentiometer. As our Connections part is done, we will write a program to print "KRYPTON" on this LCD.

16X2 LCD Commands

LCD Commands are the crucial instructions for the Display to perform certain tasks, these commands needs to be sent to LCD in order to work properly

sr no. Command Purpose
1 0x01 Clear Screen
2 0x02 Return Home
3 0x04 Decrement/Shift Cursor Left
4 0x05 Shift Display Right
5 0x06 Increment/Shift Cursor Right
6 0x07 Shift Display Left
7 0x08 Display Off, Cursor Off
8 0x0A Display Off, Cursor On
9 0x0C Display On, Cursor Off
10 0x0E Display On, Cursor On
11 0x0F Display On, Cursor Blink
12 0x10 Shift cursor position to left
13 0x14 Shift cursor position to Right
14 0x18 Shift entire display to left
15 0x1C Shift entire display to Right
16 0x80 Force cursor to beginning of 1st line
17 0xC0 Force cursor to beginning of 2nd line
18 0x38 2 lines 5x7 matrix

C Program for AT89S52 (8052) Microcontroller

#include<AT89X52.h> //header file
#define RS P2_0 //register select pin
#define RW P2_1 //read/write pin
#define EN P2_2 //enable pin
#define PORT P1
void delay(); //delay function
void com(char ); //to send command to LCD
void dat(char ); //to send data to LCD
void print(char ); //our function to print the name.

void main(){
    while(1){
        char text[]="KRYPTON";
        int i,n=0;
        com(0x0c); // display on cursor off
        com(0x01); //clear screen
        while(text[i]!='\0'){ //continue to print till we get the null character
      // this block is intentionally commented. to be used when printing more than 16 characters
      /* if(i>15){
                com(0x1c); //shift display left
                com(0x0c);
            }
      */
            print(text[i]);
            i++;
        }
        while(9);
    }
}

void print(char c){
    com(0x06); // shift cursor to right >>>>>>
    dat(c); // pass the character to LCD
}

void delay(){
    short int i;
    for(i=0;i<=255;i++);
}

void com(char m){
    PORT=m;
    RS=0;
    RW=0;
    EN=1;
    delay();
    EN=0;
    delay();
}

void dat(char m){
    PORT=m;
    RS=1;
    RW=0;
    EN=1;
    EN=0;
    delay();
}
Enter fullscreen mode Exit fullscreen mode

In the code above, we have defined few macros for the connections to the PORTS of our microcontroller, we have included the AT89X52.h header file to interact with the microcontroller, the same code works for at89s52, at89c52 or other 8052 family of microcontrollers, after that we have declared prototypes of few functions, that we have provided definitions after the main function. the delay function adds a short delay which is necessary as this LCD requires a High To Low pulse of ~10ms,function com is for command and dat is for passing data or text to our display, the function print is responsible for shifting the cursor and printing characters.

So in the function main, we have defined an array of characters to store our name, next lines are to initialize the LCD, i.e. turn on the display and clear the screen (initialization process). Now we have a function print that simply takes the character and displays it on the LCD by incrementing the cursor (i.e. shifting the cursor to the right). So calling the print function will take one character at a time and then do the cursor shifting operation and finally pass the character to the data function that displays it.

But as our LCD has some speed limitations, we cannot pass the values repeatedly in a short span, we need to add some delay otherwise the LCD will ignore the input, thus we are calling our delay function after every command or data function call, actually, there is a proper way to do so by checking the LCD busy flag, then sending the data else waiting till the busy flag clears, but this becomes very much complex, so we are not using the actual busy flag method instead we have used a simple for loop to clear the delay. the last line while(9) is intentionally placed there, as we don't want to perform any operation once our name is printed, the while(9) is an infinite loop so there will be no operation after printing "KRYPTON".

If you read the code, you'll find that there is a commented block, which you can use if you want to print longer words, this block will shift the display making you space available for the new characters.

Preview of LCD interfaced with 8051

Photo of LCD with KRYPTON written on it
16x2 LCD with krypton written on it

Code for AT89S51 (8051) microcontroller

The only change here is header file changed to AT89S51 specific, rest of the code is similar and you can use it with AT89X51 microcontroller.

#include<AT89X51.h> //header file is changed to **AT89X51.h**
#define RS P2_0 //register select pin
#define RW P2_1 //read/write pin
#define EN P2_2 //enable pin
#define PORT P1
void delay(); //delay function
void com(char ); //to send command to LCD
void dat(char ); //to send data to LCD
void print(char ); //our function to print the name.

void main(){
    while(1){
        char text[]="KRYPTON";
        int i,n=0;
        com(0x0c); // display on cursor off
        com(0x01); //clear screen
        while(text[i]!='\0'){ //continue to print till we get the null character
      // this block is intentionally commented. to be used when printing more than 16 characters
      /* if(i>15){
                com(0x1c); //shift display left
                com(0x0c);
            }
      */
            print(text[i]);
            i++;
        }
        while(9);
    }
}

void print(char c){
    com(0x06); // shift cursor to right >>>>>>
    dat(c); // pass the character to LCD
}

void delay(){
    short int i;
    for(i=0;i<=255;i++);
}

void com(char m){
    PORT=m;
    RS=0;
    RW=0;
    EN=1;
    delay();
    EN=0;
    delay();
}

void dat(char m){
    PORT=m;
    RS=1;
    RW=0;
    EN=1;
    EN=0;
    delay();
}
Enter fullscreen mode Exit fullscreen mode

Additional Links:

conclusion

16X2 display can be used to print the useful information/status for small scale project, embedded systems, these displays operate on 3.3V to 5V DC source and doesn't require much configuration, also these displays comes with an option to adjust the contrast levels so one can increase/decrease the contrast of the display for proper viewing experience. overall these displays can be a great choice for small texts like status informations, etc, also we can emulate scrolling text behaviour to display characters more than 16 in length.

Interface Dot Matrix Display with Arduino: Code & Connections, Secarmy CTF 2.0 junior walkthrough - team krypton
Keywords:
embedded, lcd, 8051, display, electronics, programming, microcontroller

Top comments (0)