Pages Menu
TwitterRssFacebook
Categories Menu

Posted by on Jun 16, 2011 in Atmel AVR, Microcontrollers | 210 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.

Coding

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; 

    lcd_init(LCD_DISP_ON_CURSOR);
    lcd_clrscr();
    while(1)
    {
        for ( j = 0; j < STRING_LENGTH; j++ )
        {
            if ( j >= LCD_MAX )
                lcd_gotoxy( 0, 0 );
            else
                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] ); 

            _delay_ms(100);
        } 

        lcd_clrscr();
    }
}

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);
lcd_puts(buffer);

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

char buffer[10]; 

float f = 3.1415926; 

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

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.

210 Comments

  1. Hey, im using AVR Butterfly and i want to interface it with LCD, is this possible? need some guidance.

    • AVR Butterfly comes with an onboard ATmega169, which has an inbuilt LCD controller. You can program the microcontroller just like you program any other ATmega controller. You can find reference bootloader source code here.

  2. hola que tal
    disculpa estoy utilizando un atmega328p en atmel 6.2 pero al poner el código salen estos errores a que se deverá
    Error 1 undefined reference to `lcd_init(unsigned char)’
    Error 2 undefined reference to `lcd_clrscr()’
    Error 5 undefined reference to `lcd_gotoxy(unsigned char, unsigned char)’
    Error 7 ld returned 1 exit status

    #include
    #define F_CPU 11059200UL
    #include
    #include “lcd.h”

    int main(void)
    {
    lcd_init (LCD_DISP_ON_CURSOR);
    while(1)
    {
    lcd_clrscr ();
    lcd_home ();
    lcd_puts ( “hola” );
    lcd_gotoxy (0,1);
    lcd_puts ( “JUAN” );
    _delay_ms (50);
    }
    }

    • This means that the LCD library is not added to your project. The compiler cannot search for these library functions.
      PS. We would appreciate if you could post your comment in English. Use Google translate if you need to. Thanks!

  3. hi,
    I want my lcd to print the range(value) of colours it sense from its LDR sensor.
    i m working on atmega16.
    can you please help how to do so..

    • Hi Abhishek

      From what I’ve understood, what you need to do is use ADC to take inputs from the LDR and make a table of the readings that you get from the LDR for different colours. In the program, use ADC and compare the realtime readings to the readings you had taken before, and print the matched colours on the LCD.

      Hope this helps!

  4. sir i want to display 50 names of students on a 16×2 lcd
    on clicking the button name of next student should display
    how can i make this code plz tell me

    • Hi Aleem

      You should try making a function which polls a pin, to which you connect the switch, and at every successful trigger, changes the string that gets displayed on the LCD.

      Hope this Helps!

  5. [CODE REMOVED BY ADMIN]

    This code is working on proteus but when I am using it on AVR board, the lcd screen just remains blank.
    Please help.

    • Shubham,
      There could be a million and one reasons why it doesn’t work. Have you checked your connections? Is the LCD contrast adjusted? Is the chip getting programmed correctly?

      • Thanks for your reply sir,
        Yes, the connections are correct. I have tried out many times. I have even changed the ports (making a corresponding change in header file). Still it didnt work out. I cant understand why the same connection works fine on proteus but not on AVR board.

        PS- I later tried to implement lcd interfacing in cvavr with necessary changes. It worked fine. But I am keen to work on Atmel Studio 6. Please help.

  6. [CODE REMOVED BY ADMIN]
    That is simple code but when I debug it it gives me

    Error 1 undefined reference to `lcd_init'
    Error 2 undefined reference to `lcd_clrscr'
    Error 3 undefined reference to `lcd_home'
    Error 4 undefined reference to `lcd_puts'
    Error 5 undefined reference to `lcd_gotoxy'
    Error 6 undefined reference to `lcd_puts'
    Error 7 ld returned 1 exit status collect2.exe

    • Looks like your LCD library isn’t added to the project. Add it to the project AND include it in your main file as well.

      • I already added it.

      • And included it

  7. I want to ask i cannot find the set XTAL in my lcd.h file but i can found it in the makefile.Would it possible i change my F_CPU in the makefile?

  8. Hi,
    i am using WinAVR. How can i configure the LCD library? Will these same c file and h file work for me? My microcontroller is Atemga32A.
    Can you pls help?

  9. change extension to .cpp if using c++ project

  10. Hi,

    Can you shows some example where we can blink certain characters ? using the library ?

  11. Hey I used your code with 4×16 LCD, and i Change LCD_LINES to 4 but it wont work it always show data on first and 3rd line.

    • Cuz this library ain’t supposed to be used with 4×16 LCD.

  12. Hello, I am having an issue with the library in the lcd.h file. I have added the library to my project but it keeps returning this error:

    In function ‘toggle_e’
    error: ‘PORTA’ undeclared (first use in this function)

    it also repeats this error for the lcd_write,read,init functions as well.
    Do you have any ideas about the cause of this? Thanks so much for your time.

    • Nevermind, as soon as I posted that I realized it was because my target avr doesn’t have a PORTA. Thanks

  13. hello, I made PCB where i by default connected R/W pin to GND (because i’m using writing function only). is there any problem about that? because i’m not getting any letter on my LCD.

    • That’s now how it works, Shariful. :) Two things:

      1. LCD is an output device, but this doesn’t always mean that you’re writing to it. There’s more to it. You need to perform a series of read and write operations (yes, both) in order to display anything on the LCD. Just follow the circuit diagram I showed above.

      2. Next time onward, check your connections on a breadboard first before making a PCB.

  14. Hi there, I’m making for my classes a little project with Atmega8. The point is to control displaying things by six buttons. Pressing the 1st button should occur move of the word displayed in 1st line ,1 position to the right. Pressing the 2nd button should occur move of the word displayed in 2nd line ,1 position to the right. Third button should occur move of the word displayed in 1st line ,1 position to the left. Fourth button should occur move of the word displayed in 2nd line ,1 position to the left. Fifth button should occur move of the both words to the right edge of LCD. Sixth button should occur move of the both words to the left edge of LCD.

    I’m using Atmel studio 6. I’m writing my program in C. Could You help me with this project. I already wrote some code for 3 buttons but I don’t have a clue how to move displaying words to the right edge of LCD. I’m using Peter Fluery library.

    [CODE REMOVED BY ADMIN]

    • Hi Matt,
      Sorry but we can’t help you with your homework. If you have any questions, we can answer that.

  15. [CODE REMOVED BY ADMIN]
    i am trying to display temperature with the help of lm35 on lcd this program should work but its displaying either random /garbage character or nothing. what is the problem please help me

  16. i don;t have the lcd.h and lcd.c file please give me link to download it

    • The links are mentioned in the post. Please read it properly before asking.

Trackbacks/Pingbacks

  1. Menampilkan Tulisan pada LCD dengan Menggunakan AVR studio - […] // Referensi : maxembedded.com […]

Leave a Reply to Kalpesh Patel Cancel reply

%d bloggers like this: