Getting started with 2*16 Character LCD

In this post we are going learn how to interface LCD (Liquid Crystal Display) with Atmega8. LCD’s are very common in embedded systems like Coffee machines, Weighing machines etc.,

Generally these LCD have 16 pins.


The numbering starts from left to right in the above picture. The left most pin is VSS and right most pin is LED-

Pin1 (VSS) : Connect ground of your 5V Supply to this pin

Pin2 (VDD) : 5V Supply

Pin3 (VEE) : This is the contrast voltage pin. We should connect this pin via a potentiometer if we want to change the

contrast of the LCD module. For default contrast this pin has to be connected to ground pin. But I strongly recommend to have a potentiometer.

Pin4 (RS) : Register select, By using this we decide whether the information we are passing on the data bus is data or a command. When this line is low, bytes transferred to the display are treated as commands and bytes read from the display indicate its status. By setting RS line high, character data can be transferred to and from the module.

Pin5 (R/W) : This is Read/Write line. Low logic on this line indicates write to the LCD module and high indicates read from the LCD module.

Pin6 (E) : Enable, This pin is used to initiate the actual transfer of commands or character data between the module and data lines. When we are writing on the display, data is transferred only on the high to low transition of this signal. However, when reading form the LCD, data will be available shortly after the low to high transition and remain stable until signal falls low again

Pin7 to Pin14 (D0 to D7): Data lines, Normally there are two type of display modes and they are 4-bit mode and 8-bit mode.

8-bit mode: In this mode we will use 8 data lines (D0-D7) to transfer the data. That is one byte will transferred at a time.

4-bit mode: In this mode we will use only 4 data line(D4-D7) to transfer the data. One byte will be transferred as two nibbles(1 nibble=4 bits).

Mode selection purely depends on the number of IO lines available in your micro-controller. If you have plenty enough to support 8-bit mode, you can use 8-bit mode. But by using 4-bit mode, we can save 4 IO lines. In this post I will explain 4-bit mode.

Pin15 (LED+) : This pin is the positive terminal of back light LED. Connect it to 5V supply.

Pin16 (LED-) : This pin is negative terminal of back light LED. Connect it to the GND


LCD Command set:





D7 D6 D5 D4 D3 D2 D1 D0
Clear Display 0 0 0 0 0 0 0 1 01
Cursor Home 0 0 0 0 0 0 1 x 02 or 03
Character Entry Mode 0 0 0 0 0 1 I/D S 04 to 07
Display on/off & Cursor 0 0 0 0 1 D U B 08 to 0F
Display/Cursor Shift 0 0 0 1 D/C R/L x x 10 to 1F
Function set 0 0 1 8/4 2/1 10/7 x x 20 to 3F

I/D: 1=Increment ‘,0=Decrement

S: 1=Display shift on ,0= Display shift off ‘

D: 1=Display on , 0=Display off ‘

U: 1=Cursor underline on, 0=Cursor under line off ‘

B: 1=Cursor blink on, 0=Cursor blink off ‘

D/C: 1=Display shift, 0=cursor move

R/L: 1 = Right shift, 0 = Left shift

8/4: 1=8 bit interface’,0=4 bit interface

2/1: 1= 2 line mode, 0 = 1 line mode’

10/7: 1= 5*10 dot format, 0 = 5*7 dot format’

‘ = indicates initial setting

Now we have all the information to write our first program for LCD. We will write a small program that will display iCircuit on LCD

Functions required:

lcd_clrscr() //to clear the display

lcd_puts() //to write strings

lcd_putc() //to wrote character data

lcd_cmd() //to write command buytes

lcd_gotoxy() //to navigate to different positions in LCD

lcd_init() //to initialize the LCD with the required settings.

we need to decide the IO mapping also.we need 4 data lines and 3 control lines. In total we need 7 IO’s

D4-D7 : PD4-PD7

RS :  PB0

E : PB1

R/W : PB2


Now we can implement the functions one by one.


#define F_CPU 16000000ul

#define e_low PORTB&=~(1<<PB1)
#define e_high PORTB|=(1<<PB1)
#define rw_low PORTB&=~(1<<PB2)
#define rw_high PORTB|=(1<<PB2)
#define rs_low PORTB&=~(1<<PB0)
#define rs_high PORTB|=(1<<PB0) void lcd_busy() //to check LCD readiness to receive commands from controller { // we will wait here until LCD is ready to receive the commands from controller e_low; rs_low; //change the data lines to input mode DDRD&=0x0F; rw_high; //we are reading the data from LCD uint8_t data=0x80; while((data&0x80)==0x80) { e_high; _delay_us(20); data=(PIND&0xF0); e_low; _delay_us(20); e_high; _delay_us(20); data|=(PIND&0xF0)>>4;
 DDRD|=0xF0; //make data lines as ouput

 void e_toggle()

 void lcd_write(uint8_t c,uint8_t rs)//rs 1 means data,0 means cmd
   rw_low;//since we are writing 

 //output high nibble first
 PORTD&=0x0F; //clear the data lines

 //ouput low nibble
 PORTD&=0x0F; //clear the data lines


void lcd_putc(char c)

void lcd_puts(char* str)
 uint8_t c;
 while ( (c = *str++) ) {

void lcd_cmd(char c)
void lcd_clrscr()
 lcd_cmd(0x01);//clear data
 lcd_cmd(0x02); //set cusrosr to home

void lcd_gotoxy( uint8_t x, uint8_t y)
 uint8_t cmd=128+(64*y)+x;

void lcd_init()
 //initialize IO lines

 rs_low;  //by default the LCD will be in 8-bit mode, we need to bring it to 4 bit mode
 PORTD|=(0x20); //enable four 4 bit mode

 lcd_cmd(0x2C); //4 bit mode,2 line,5*10 dot format
 lcd_cmd(0x0E); //display on, cursor under line on
 lcd_cmd(0x01); //Clear display

int main()
 lcd_init(); //we need to call this function before doing any operation on LCD
 _delay_ms(5000); //5 sec delay, this is built in fucntion

Now we have all the functions to display some text on LCD. So build the program and burn to HEX file to Atmega8. Hurry Up!!

Getting started with LCD

Add a Comment

Your email address will not be published. Required fields are marked *