Interfacing 16×2 LCD with Atmega16 AVR Microcontroller in 4-Bit Mode

Interfacing 16x2 LCD

Display is the necessary part of any machine whether it is any home appliance or industrial machines. Display not only shows the control options to operate the machine but also shows the status and output of the task performed by that machine. There are many types of displays used in electronics like 7-segment display16×2 LCD displayTFT touch screen displayOLED display etc.

 Interfacing 16x2 LCD

16×2 LCD display is the most basic display module and also used in some small electronics equipment like calculator, digital meter etc. We have done lot of projects using 16×2 LCD including the basic interfacing with other microcontrollers:

In this tutorial, we will see how to interface a 16×2 LCD with Atmega16 AVR microcontroller and display a simple welcome message.

Components Required

  • Atmega16
  • 16×2 LCD Module
  • Jumpers
  • Breadboard
Components Required 1

Circuit Diagram

Circuit Diagram

Programming Atmega16 for 16×2 LCD Display

Programming doesn’t require any external libraries. Here the Atmega16 is programmed using USBASP and Atmel Studio7.0Complete Program and Working Video is given at the end of the project, just upload the program in Atmega16 and rotate 10k POT to adjust the brightness of LCD.

Initially define the CPU Frequency and include the necessary libraries which comes with Atmel Studio Package such as <avr/io.h> for accessing IO pins and <util/delay.h> for generating delay in the program.

<util/d#define F_CPU 16000000UL        
#include <avr/io.h>                                
#include <util/delay.h>

Define RS and EN pin of LCD in the program. The RS Pins is used to select the data and command register. The enable pin latches the data.

#define en PA3                                                   
#define rs PA2

Also define that which PORT of Atmega16 will be used to interface LCD. Here, the PORTA is used.

#define lcdDirection  DDRA       
#define lcdPort PORTA

Next step is to construct a function which will accept a command by passing a parameter. There are many LCD HEX Commands. The Hex Commands are used to define the function of LCD. Since we are using the 4-bit Mode of LCD, the byte (8-bit) will be sent in two packets. The one packets will be Upper Nibble (4-bit) and other packet will be Lower Nibble (4-bit).

void lcdCommand( unsigned char commands )
{
lcdPort = (lcdPort & 0x0F) | (commands & 0xF0); 
            lcdPort &= ~ (1<<rs);             
            lcdPort |= (1<<en);                
            _delay_us(1);
            lcdPort &= ~ (1<<en);            
            _delay_us(200);
            lcdPort = (lcdPort & 0x0F) | (commands << 4);
            lcdPort |= (1<<en);                                                                
            _delay_us(1);
            lcdPort &= ~ (1<<en);                                                
            _delay_ms(2);
}

The next step would be accepting the characters and latching it to the port of LCD. The characters received is then sent to the LCD nibble by nibble. The Function takes the character using pass by parameter and then takes the upper and lower nibble. The ‘rs’ pin is set to high for data register and then a rising pulse is sent to latch the data. Similarly the lower nibble in sent by changing the value of enable and sending the rising pulse for enable.

void lcdChar( unsigned char string )
{
            lcdPort = (lcdPort & 0x0F) | (string & 0xF0); 
            lcdPort |= (1<<rs);                                       
            lcdPort|= (1<<en);                                                                             
            _delay_us(1);
            lcdPort &= ~ (1<<en);                                                                                    
            _delay_us(200);
            lcdPort = (lcdPort & 0x0F) | (string << 4);   
            lcdPort |= (1<<en);                                                                            
            _delay_us(1);
            lcdPort &= ~ (1<<en);                                                                        
            _delay_ms(2);
}

This function just converts the character into string and can be used in the program later where writing string is needed.

void lcdString (char *str) 
{
            int j;
            for(j=0;str[j]!=0;j++)                     
            {
                        lcdChar (str[j]);
            }
}

Now a function is written just to clear the screen. You just need to send the command 01 in HEX and then just set the cursor to initial position.

void lcdClear()                                                                                               
{
            lcdCommand (0x01);                              
            _delay_ms(2);
            lcdCommand (0x80);                             
}

Now in the main function, the LCD is initialized. Initially set the PORT direction for LCD to interface. Here, the PORT is set as OUTPUT so set FF.

lcdDirection = 0xFF;                                  
_delay_ms(20)

Then set the LCD in the 4-bit mode by sending 02 in hex. Also send 28 in hex to set it in the 2 line, 15×7 matrix pixels in 4-bit mode.

lcdCommand(0x02);              
lcdCommand(0x28);

The command 0c and 06 is used to control cursor position. And finally just clear the screen by sending 01 in hex. This will finish the initialization of LCD.

lcdCommand(0x0c);                       
lcdCommand(0x06);                       
lcdCommand(0x01);

After initialization is finished just test the LCD by sending a string. Here we are sending a String “Interfacing LCD” in the 1st row.

lcdString("Interfacing LCD");

Then move the cursor to the next row by sending the command c0 in hex. And finally on this position, write the string “With Atmega16″.

lcdCommand(0xC0);              
lcdString("With Atmega16");
Programming

This finishes the complete tutorial on Interfacing a 16×2 LCD with Atmega16. Note that if you don’t get any image or pixels then either check your wiring according to code and circuit diagram or change the value of the POT attached to V0 pin of LCD. If you have any doubt or suggestion then you can reach us to either by writing to our forum or comment below.

Leave a Comment

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