A1.

8051 Interfacing:LCD 16x2

Introduction:LCD
Liquid Crystal Display(LCDs) provide a cost effective way to put a text output unit for a microcontroller. As
we have seen in the previous tutorial, LEDs or 7 Segments do no have the flexibility to display informative
messages. This display has 2 lines and can display 16 characters on each line. Nonetheless, when it is
interfaced with the microcontroller, we can scroll the messages with software to display information which is
more than 16 characters in length.

LCD Internal Controller

Fig 1: LCD Block diagram

The LCD is a simple device to use but the internal details are complex. Most of the 16x2 LCDs use a Hitachi
HD44780 or a compatible controller. Yes, a micrcontroller is present inside a Liquid crystal display as shown
in figure 1.

1

D.  Read/Write RW=0.The Display Controller takes commands and data from a external microcontroller and drivers the LCD panel(LCDP). Basic Commands The LCD controller uses RS and RW lines along with E to operate the LCD. E. C etc at the bottom of instruction set to decode the instructions completely..  Clear Display  Cursor Home  Set Entry Mode  Display on/off control  Cursor/display shift  Function Set 2 .g. Observe the Bit names: I/D. RW=1. writes to the LCD.Reads from the LCD.  Resister Select (RS): Determines weather a command(RS = 0) is sent (to set up the display) or actual data(RS=1) is sent. The commonly used instructions are shown in the instruction set below. S. It takes a ASCII value as input and generate a patter for the dot matrix. to display letter 'A'. it takes its value 0X42(hex) or 66(dec) decodes it into a dot matrix of 5x7 as shown in figure 2.

 Read Busy Flag  Data Read  Data Write Instruction Set HD44780U based instruction set Code Instruction R R/ B B B B B S W 7 6 5 4 3 Clear display 0 Cursor home 0 Entry mode set Display on/off control Description 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 B B B 2 1 0 0 0 1 D 0 1 Clears display and returns cursor to the home position (address 0). These operations are performed during data I/ S read/write. 0 0 0 0 0 0 Cursor/displa 0 y shift 0 0 0 0 1 S/ R/ * C L * Sets cursor-move or display-shift (S/C). cursor on/off (C). Also returns display being shifted to the original position. shift direction (R/L). DDRAM content 3 . specifies to shift the display (S). 1 Sets cursor move direction (I/D). and blink of cursor position C B character (B). DDRAM content * remains unchanged. D Sets on/off of all display (D). Returns cursor to home position.

1 = shift right.0 = decrement cursor position.0 = 4-bit interface. S . N . number * of display line (N). 1 = cursor blink on . S/C . Function set 0 0 D 0 0 1 N L F Sets interface data length (DL).0 = cursor off.0 = 5×8 dots.0 = 1/8 or 1/11 duty (1 line). 1 = cursor on. B . 1 = display shift.0 = display off. LCD UNIT 4 . and character font (F). 1 = 5×10 dots. 1 = 1/16 duty (2 lines).0 = can accept instruction. 1 = increment cursor position.0 = shift left. 1 = 8-bit interface. BF . C . R/L . DL .remains unchanged. D . 1 = shift display.0 = move cursor. Read busy flag & address counter 0 1 Write CGRAM or DDRAM 1 0 Write Data Write data to CGRAM or DDRAM.0 = no display shift. Write CGRAM or DDRAM 1 0 Write Data Write data to CGRAM or DDRAM. * Reads busy flag (BF) indicating internal operation being performed and reads CGRAM or DDRAM address counter contents (depending on previous instruction). 1 = display on. F .0 = cursor blink off. 1 = internal operation in progress. B F CGRAM/DDRAM address Instruction bit names — I/D .

R/W=0: Write. All the pins are identically to the lcd internal controller discussed above PIN NUMBER FUNCTION 1 Ground 2 VCC 3 Contrast adjustment (VO) 4 Register Select (RS).Let us look at a pin diagram of a commercially available LCD like JHD162 which uses a HD44780 controller and then describe its operation. RS=1: Data 5 Read/Write (R/W). R/W=1: Read 5 . RS=0: Command.

Falling edge triggered 7 Bit 0 (Not used in 4-bit operation) 8 Bit 1 (Not used in 4-bit operation) 9 Bit 2 (Not used in 4-bit operation) 10 Bit 3 (Not used in 4-bit operation) 11 Bit 4 12 Bit 5 13 Bit 6 14 Bit 7 15 Back-light Anode(+) 16 Back-Light Cathode(-) 6 .6 Clock (Enable).

8 bit Mode Objective fig LCD display There is lot of stuff that can be done with the LCDs. PIN 3 is the contrast pin and is output of center terminal of potentiometer(voltage divider) which varies voltage between 0 to 5v to vary the contrast. all of the 8 datalines DB0 to DB7 are connected from the microcontroller to a LCD module as shown the schematic. Schematic Discription  Data Lines: In this mode. The led backlight can be powered through a simple current limiting resistor as we do with normal leds.  Back-light: The PIN 15 and 16 are used as backlight. as discussed earlier.Interfacing LCD with 8051 LCD can be interfaced with the 8051 micrcontroller in two modes. 8 bit and 4 bit. to start with we will simple display a couple of strings on the 2 lines of the LCD as shown in the image.  Control Lines:' The RS. 7 .  Power & contrast:Apart from that the LCD should be powered with 5V between PIN 2(VCC) and PIN 1(gnd). Let us Interface it in 8 bit mode first. RW and E are control lines.

8 . We will discuss the implementation while discussing the lcd_8_bit.c.c and lcd_8_bit. main.Schematic Code As with all the interfaces to simplify thing we have separated code into two files. it makes things very simple when the libraries are well written.c file. As you can see. Then it uses several functions from the lcd_8_bit. The main.c is very simple it includes the standard library files.c file to set up and display messages. You may go through the tools setup tutorial on configuring the code.

Let us look at few important lines and functions. world" on first line*/ LCD_DisplayString("hello.c /* Reg51. sbit rw= P0^1.h contains the defnition of all ports and SFRs */ #include <reg51. The timing diagrams for command write 9 .h" //Xplore Labz Delay library /* start the main program */ void main() { /* Initilize the lcd before displaying any thing on the lcd */ LCD_Init().h" //Xplore labz LCD library #include "delay. P2 // LCD databus connected to PORT2 // Register select pin connected to P0. void LCD_CmdWrite( char cmd) Commands are required to sent to lcd in order to set it up or initialize. Specifying the Connections: The connections described in the schematic are specified with following lines of code. #define databus sbit rs= P0^0.c consists of various functions that are required to initialize and use the LCD.1 // Enable pin connected to P0. sbit en= P0^2.2 Let us look at three important functons in lcd_8_bit.c: 8 bit lcd library file The lcd_8_bit. LCD_DisplayString("good morning"). /* Display "hello.c 1. while(1). /*Go to second line and display "good morning" */ LCD_GoToLineTwo().0 // Read Write pin connected to P0.h> #include "lcd.The main file main. world"). } lcd_8_bit.

en=0.  step3: Select Write operation making RW low.  step1: Send the I/P command to LCD.  step2: Select the Control Register by making RS low. delay_ms(1). void LCD_CmdWrite( char cmd) { databus=cmd. } 10 . // Select the Command Register by pulling RS LOW rw=0.are shown in the figure. // Send the command to LCD rs=0.  step4: Send a High-to-Low pulse on Enable PIN with some delay_us. // Send a High-to-Low Pusle at Enable Pin delay_us(10). // Select the Write Operation by pulling RW LOW en=1.

 Clear the LCD  Get the cursor to first line first position.2. void LCD_DataWrite( char dat) This function sends a character to be displayed on LCD in the following steps. void LCD_DataWrite( char dat) { databus=dat.  step2: Select the Data Register by making RS high. LCD_CmdWrite(0x38). LCD_CmdWrite(0x01). void LCD_Init() Looking at the instruction set of the LCD controller. The code is listed below. // LCD // // // 2lines. The timings are similar as above only change is that RS is made high. // Select the Write Operation by pulling RW LOW en=1. LCD_CmdWrite(0x80). en=0. void LCD_Init() { delay_us(5000). // Send the data to LCD rs=1.  step1: Send the character to LCD. we can initialize the LCD with following steps  Set the display mode as 2 lines.  step4: Send a High-to-Low pulse on Enable PIN with some delay_us. } 3. // Select the Data Register by pulling RS HIGH rw=0. // Send a High-to-Low Pusle at Enable Pin delay_us(10). 5 x 7 matrix  Turn On the dislay. 5*7 matrix Display ON cursor ON Blinking off Clear the LCD Cursor to First line First Position 11 . delay_ms(1). and cursor. LCD_CmdWrite(0x0E).  step3: Select Write operation making RW low.

// Cursor to First line First Position } void LCD_CmdWrite( char cmd) { databus=cmd. // Enable pin connected to P0.h" #define databus P2 // LCD databus connected to PORT2 sbit rs= P0^0. // Send a High-to-Low Pusle at Enable Pin delay_us(10). char col) { char pos.h" #include "lcd.h> #include "delay. we need to send the command to select 4 bit mode as shown in the instruction set above. } void LCD_GoToXY(char row. // LCD 2lines. You could observe that the basic functions to read data and write write command are used extensively and entire library is built upon them. // Register select pin connected to P0. } 4 bit Mode Schematic There are following differences in 4 bit mode. en=0. // Send the data to LCD rs=1. // Select Write Operation by pulling RW LOW en=1. // Read Write pin connected to P0. delay_ms(1).0 sbit rw= P0^1.The remaining code is listed below. LCD_CmdWrite(0x38). 5*7 matrix LCD_CmdWrite(0x0E). // Select the Write Operation by pulling RW LOW en=1. // Send a High-to-Low Pusle at Enable Pin delay_us(10). delay_ms(1). en=0. // Send the command to LCD rs=0.1 sbit en= P0^2. } void LCD_DataWrite( char dat) { databus=dat.2 /* 16x2 LCD Specification */ #define LCDMaxLines 2 #define LCDMaxChars 16 #define LineOne 0x80 #define LineTwo 0xc0 #define BlankSpace ' ' void LCD_Init() { delay_us(5000).  In code. // Select the Data Register by pulling RS HIGH rw=0. //take the char number //now pos points to XY pos LCD_CmdWrite(pos) } } void LCD_DisplayString(char *string_ptr) { while(*string_ptr) LCD_DataWrite(*string_ptr+ +). // Select Command Register by pulling RS LOW rw=0.  Only data lines D4 to D7 are used as shown in the schematic below. // Clear the LCD LCD_CmdWrite(0x80). if(row<LCDMaxLines) { pos= LineOne | (row << 6). #include<reg51. 12 . There are also other functions that are used to display number etc in the lcd library file. // Display ON cursor ON Blinking off LCD_CmdWrite(0x01). // take the line number //row0>pos=0x80 row1->pos=0xc0 if(col<LCDMaxChars) pos= pos+col.

The important and required code is listed below.h> #include "delay. // Read Write pin connected to P0. LCD_CmdWrite(0x02). // Enable pin connected to P0.0 sbit rw= databus^1. we simply include the lcd_4_bit. // Register select pin connected to P0. Code #include<reg51.2 /* 16x2 LCD Specification */ #define LCDMaxLines 2 #define LCDMaxChars 16 #define LineOne 0x80 #define LineTwo 0xc0 #define BlankSpace ' ' void LCD_Init() { delay_us(5000).c to work in 4 bit mode.h" #define databus P0 //LCD databus connected to PORT0 sbit rs= databus^0. //Initilize the LCD 13 .h" #include "lcd.The main program remains exactly as in 8 bit mode.1 sbit en= databus^2.

// Select the Data Register by pulling RS HIGH rw=0. // wait for some time.in 4bit Mode LCD_CmdWrite(0x28). delay_ms(1). en=0. // Select the Command Register by pulling RS LOW rw=0. // Send the Higher Nibble rs=0. // Move the Cursor to Second line } Downloads "The code is given for 4 and 8 bit modes with and without busy Flag" 8051_LCD_Tutorial_Code. en=0. delay_us(10). // Send the Higher Nibble rs=1. delay_ms(1). LCD_CmdWrite(0x0E). // Select the Write Operation by pulling RW LOW en=1. // wait for some time databus=((cmd<<4) & 0xf0). // Clear the LCD LCD_CmdWrite(0x80). // Select the Write Operation by pulling RW LOW en=1. // Select the Command Register by pulling RS LOW rw=0. // Select the Data Register by pulling RS HIGH rw=0. delay_us(10).zip 14 . // Send a High-to-Low Pusle at Enable Pin delay_us(1). // Display ON cursor ON LCD_CmdWrite(0x01). // Send the Lower Nibble rs=0. // Select the Write Operation by pulling RW LOW en=1. databus=((dat <<4) & 0xf0). en=0. // Cursor to First line First Position } void LCD_CmdWrite( char cmd) { databus=(cmd & 0xf0). // Send a High-to-Low Pusle at Enable Pin delay_us(1). // Send a High-to-Low Pusle at Enable Pin delay_us(1). // Select the Write Operation by pulling RW LOW en=1. // Send the Lower Nibble rs=1. } void LCD_DataWrite( char dat) { databus=(dat & 0xf0). } void LCD_GoToLineTwo() { LCD_CmdWrite(LineTwo). // Send a High-to-Low Pusle at Enable Pin delay_us(1). } void LCD_DisplayString(char *string_ptr) { while(*string_ptr) LCD_DataWrite(*string_ptr++). en=0.