Pages Menu
Categories Menu

Posted by on Jun 16, 2011 in Atmel AVR, Microcontrollers | 226 comments

LCD Interfacing with AVR

LCD Interfacing with AVR

AVR SeriesIn this post, we will learn something cool! Something visual! Something like displaying your name in an LCD and then making it roll over, bounce over, etc etc etc ;)

So basically I am re-posting this tutorial, but in a different manner. I hope it will be useful for you.

LCD – General Introduction

Graphical LCD

Graphical LCD

LCD stands for Liquid Crystal Display. It can be used to display anything (virtually anything!). They are of many types. The ones we commonly use for embedded systems, robotics, etc are of two types – character LCD and graphical LCD. We will discuss about character LCDs in this post whereas graphical LCDs will be discussed later.

The most popular type of character LCD is the HD44780 Character LCD. In this post, we will be using the JHD 162A character LCD shown below. One of my readers, Rizwan, has also worked out this tutorial successfully using the LMB162ABC character LCD. Thanks Rizwan for the update! :)

JHD 162A Character LCD

JHD 162A Character LCD

The JHD 162A LCD is fully compatible with the HD44780 LCD. Hence, the same set of codes will work for both. It is a 16×2 LCD module i.e. it has 16 columns and 2 rows for display. It can operate in either 8 bit mode or 4 bit mode. In 8 bit mode, an 8 bit is data is sent to the LCD from the MCU whereas in 4 bit mode, 4 bits of data are sufficient to operate it.

It has 16 pins, the details of which is given below:

JHD 162A Pin Configuration

JHD 162A Pin Configuration

Now, for the LCD to work in 8 bit mode, it requires the 8 data pins (DB0…DB7) and 3 control pins (RS, R/W, EN) whereas in 4 bit mode, it requires 4 data pins (DB4…DB7, only the upper nibble) and 3 control pins (RS, R/W, EN). Though the 8 bit mode is faster and more accurate, it consumes more pins of the MCU. However, the 4 bit mode is also fast and accurate enough to satisfy most of our need, plus it requires only 7 pins for interfacing. Hence, we will be working in the 4 bit mode. In the 4 bit mode, data pins DB0…DB3 are left open.

Interfacing LCD

First of all, you need to make basic connections of the LCD. You can refer to the following circuit diagram for this. Relate it with the pin configuration given above.

LCD Connector

LCD Connector

Before coding, kindly download the LCD library written by Peter Fleury from here. This is an awesome library with predefined codes so that we can ease out a little bit by not breaking our heads upon the coding part. Thus we get to use the library functions instead of going into the depths of programming. This method is much more productive, efficient and time saving. At this point, don’t worry about how a library is written. May be in days to come, I’ll teach you that as well. ;)

Configuring the library

Now that we are ready for programming, open up AVR Studio 5 and create new project. If you are new to AVR Studio 5, view this page to get started. Now in the right pane, you will find the Solution Explorer window. There, right click on the project name, go to Add and then choose Existing Item…. Now browse to the folder where you have downloaded the libraries and choose lcd.c and lcd.h.

Adding Libraries

Adding Libraries

Added Files and Headers

Added Files and Headers

Now you can find the two files (the c file and the header file) listed in your project. Now follow the following steps in order to configure the library.

  • Double click on the ‘lcd.h’ file (in the Solution Explorer) to open it. Now make sure that you scroll down very slowly or else you will miss out on some important details.
  • As you begin to scroll down, you will find some commented text describing the library. Note the line where it says LCD_IO_MODE = 0 for memory mapped mode, LCD_IO_MODE = 1 for 4 bit mode, whereas 8 bit mode is not supported.
  • Scroll further down and you will find a line asking you to set your XTAL (or F_CPU). By default it’s 8MHz. Replace it with your own exact F_CPU. Make sure that this is correct or else there will be mismatch in delay timings.
  • Scroll down to the place where you need to set your LCD_IO_MODE. Make sure that it is set/defined to 1 (for 4 bit mode).
  • Just below it lies the best part. You can choose your own port where to interface the LCD with! As I said earlier, in 4 bit operation, there will be 4 data pins (DB4…DB7) and 3 control pins (RS, R/W, EN). You can either choose them to be across one port, or distributed across different ports. This is where you do it. By default it’s across PORTA. Choose them as per your pin availability.
  • Now, if you further scroll it down, you can find a list of different commands that can be passed to the LCD using the lcd_command() function.
  • Now, if you continue to scroll, you will find a list of all the functions defined in the library along with their description. You will find functions like lcd_init(), lcd_clrscr(), lcd_home(), lcd_gotoxy(), lcd_putc(), lcd_puts(), lcd_puts_p(), lcd_command(), lcd_data() and lcd_puts_P(). Their description is attached alongwith their declaration.


Now that you have gone through the different functions available, let’s write a sample code for it. Don’t forget to include “lcd.h” header file.

#include <avr/io.h>
#include <util/delay.h>

#include "lcd.h"

int main(void)
    lcd_init(LCD_DISP_ON_CURSOR); /* initialize lcd, display on, cursor on */
                                  /* for more options for
                                  /* lcd_init(), view lcd.h file
    while(1)                      /* run continuously */
        lcd_clrscr();             /* clear screen of lcd */
        lcd_home();               /* bring cursor to 0,0 */
        lcd_puts("hello");        /* type something random */
        lcd_gotoxy(0,1);          /* go to 2nd row 1st col */
        lcd_puts("maxEmbedded");  /* type something random */
        _delay_ms(50);            /* wait 50ms */

After building the project and burning your code, you will see “hello” written in the first row and “maxEmbedded” written in the second row. This was a basic example. Now it’s up to you upon how to exploit the library resources. Okay, try this one out by yourself. The LCD should display your in the first line, and then create a bouncing effect. Your name should move towards right till it reaches the corner. And then it should move left till it once again reaches the other corner. This should continue. Hint: Use lcd_command() function e.g. lcd_command(LCD_MOVE_DISP_RIGHT), lcd_command(LCD_MOVE_DISP_LEFT), etc.

Now try to create a rolling effect. The text should roll into the view and then move out of it. I found one such code here.

#include <avr/io.h>
#include <util/delay.h>
#include "lcd.h"

#define STRING_LENGTH 27
#define LCD_MAX 15 

void main()
    char array[STRING_LENGTH] = { "welcome to maxEmbedded blog" };
    int i,j;
    int start;
    int end; 

        for ( j = 0; j < STRING_LENGTH; j++ )
            if ( j >= LCD_MAX )
                lcd_gotoxy( 0, 0 );
                lcd_gotoxy( LCD_MAX - j, 0 ); 

            start = (j <= LCD_MAX) ? 0 : (j - LCD_MAX); 

            end = (j <= LCD_MAX) ? j : (start + LCD_MAX); 

            if ( end >= STRING_LENGTH )
                end = STRING_LENGTH - 1; 

            for ( i = start; i <= end; i++ )
                lcd_putc( array[i] ); 



How does it look? Cool, eh?

Displaying ‘int’ and ‘float’ values

One drawback of Fleury’s library is that the is no function which can directly display an integer or floating point value on the LCD. For that, we can use lcd_puts() itself in combination with itoa() and sprintf() funtions.

For displaying integer values, the following modification is required.

char buffer[10]; 

int n = 12345; 

itoa(n, buffer, 10);

For displaying floating point values, the following modification is required.

char buffer[10]; 

float f = 3.1415926; 

sprintf(buffer, "%f", f);

Thus, we are done with LCD interfacing. Now you can play with it. ;)

Possible Errors that might show up

While connecting the LCD, you might face some problems. Some of the most common problems that you might face are:

  • Nothing is visible on the screen.
  • Black Squares are visible on the screen.
  • Only the cursor blinks on the screen.
  • Sometimes even the screen blinks.
  • Random/Garbage symbols are displayed on the screen.

For such troubles, you can follow the following troubleshooting methods (most of the time it works out!).

  • Adjust the contrast pot to increase visibility.
  • Check your connections. Check for any short circuit.
  • Check and change the delay. Make sure you have entered the correct XTAL value in “lcd.h” file.
  • And last but not the least, check your code! ;)

Last updated on July 15, 2014.


  1. On other words , can we print something permanently , I mean its displayed again on the LCD after reboot the LCD ?
    and never changed again until you run the programming again ?

  2. from where can i download the directory in atmel studio 7

  3. hi
    thanks for your time
    how can i define new lcd port in my program without changing lcd library?

  4. followed up on this tutorial to every detail, however, im still unable to display any float values on the lcd. even tried the conversion you had instructed…. could i be missing something here.

  5. hello sir..
    sir can be scroll the data which is starting from 0x80 position and as soon as it goes beyond 0x8f it should star scrolling in second row.

  6. how to change port for lcd…i want to use adc….ur doing nyc job….u made one fan..

  7. Hi i have just changed the FCPU to 16 MHz of my microcontroller in the main file. I have then increased the delay to 500. My lcd just shows black squares on both lines. Any help will be appreciated.

  8. Hello Mayank,

    I cannot find the setting for XTAL in the downloaded lcd.h — Did something change? Nothing about XTAL or F_CPU. I checke the file seeral times.
    Scroll further down and you will find a line asking you to set your XTAL (or F_CPU). By default it’s 8MHz. Replace it with your own exact F_CPU. Make sure that this is correct or else there will be mismatch in delay timings.

    Udo (19. december 2017)

  9. hello max
    can you help me to customize the code for atmega16A ,clock frequency 12MHz, RS-PC0,RW-PC1,EN-PC2,DB4-PC4,DB5-PC5,DB6-PC6,DB7-PC7

  10. sir… i want a tutorial on glcd….plzz upload it asap.


  1. Sistem Pengukuran Muatan Truk di Pabrik Kelapa Sawit – Sistem Mikroprosesor - […], 17 Mei 2017, 17:50. […]
  2. Automatic Temperature Controlled Fan - […] LCD Interfacing with AVR […]

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: