Interfacing 16X2 LCD to AVR Microcontroller
This session completely deals with the interfacing AVR microcontroller (ATMEGA 16) with 16X2 LCD. The Atmega16 belongs to the AVR microcontroller family.
Outline
- Circuit Diagram of Interfacing 16X2 LCD to AVR Microcontroller:
- Programming ATMEGA16 for Interfacing with 16X2 LCD:
- Code for Interfacing the LCD to ATMEGA16:
Circuit Diagram of Interfacing 16X2 LCD to AVR Microcontroller:
Circuit Explanation:
- This is similar to how the LCD is connected to an 8051 or PIC microcontroller. The microcontroller will receive its clock from the crystal oscillator. The capacitors attached to the crystal will operate as filters, assisting the crystal in resonating and oscillating in parallel mode.
- The LCD’s contrast may be adjusted with the help of the potentiometer, which is attached to pins 3 and 2. The Register select, Read/write, and Enable pins of the LCD are connected to the PD0, PD1, and PD2 pins of the Atmega16. The LCD’s data pins are wired to the Atmega16’s pins 33 to 40.
Programming ATMEGA16 for Interfacing with 16X2 LCD:
You can delve deeper into LCDs by referring to the essay titled “Interfacing 16×2 LCD with an 8051 microprocessor.” As mentioned earlier, the core principles of programming remain consistent, except for the specifics of accessing the microcontroller’s pins and registers.
The manner in which data and commands are transmitted to the LCD is of utmost importance. For instance, when sending data to the LCD, it is imperative to set the ENABLE pin of the 16×2 LCD to a low state before transmitting the data. Subsequently, you must set the ENABLE pin to a high state when you are confident that the data you intend to send is ready—equivalent to a logical ‘1’ in programming terms. Only when the ENABLE pin is set to high will the LCD function properly.
Merely setting the ENABLE pin to high won’t suffice; you must also elevate the REGISTER SELECT pin (RS pin) to a high state to signal to the LCD that the incoming data is meant for normal display. Failing to set the RS pin to high will lead the LCD to assume that the user is issuing a command, and it will prepare to execute actions in accordance with the command, such as moving the cursor, clearing the LCD’s data, and so forth.
Lastly, there is the read/write pin to consider. As is universally known, the fundamental capability of any device hinges on its capacity to read and write data; reading and writing data constitute the most fundamental and pivotal functions for any peripheral or system. When transmitting data for display on the LCD, set the R/W pin to a low state so that the LCD recognizes that data should be written to the screen and responds accordingly.
However, the process of sending data and displaying it is not the culmination of the task. The most significant and critical responsibility for the programmer is to organize data in a comprehensible manner. You can arrange data on the LCD or make the LCD function as per your requirements by dispatching commands or special functions to the LCD. You may be curious about the kinds of commands necessary to prompt specific actions from the LCD, such as commands for setting the cursor position, adjusting contrast, changing the cursor line from the first to the second line, and so forth. To send a command to the LCD, you should manipulate the pins by setting them to high or low states in the same manner as data transmission.
For transmitting a command, you need to set the ENABLE PIN to high, set the REGISTER SELECT pin (RS pin) to low (equivalent to ‘0’ in programming terms), and maintain the read/write pin (R/W pin) at a high state. It’s crucial to remember this pin configuration when sending commands.
Different commands and their corresponding hexadecimal codes are typically employed by programmers when instructing the LCD on how to display data.
SNO | INSTRUCTION FOR LCD | HEX CODE |
---|---|---|
1 | If you want to display content in one line in 5×7 matrix | 0x30 |
2 | If you want to display content in two line in 5×7 matrix | 0x38 |
3 | If you display 4 bit data in one line in 5×7 matrix | 0x20 |
4 | If you display 4 bit data in two line in 5×7 matrix | 0x28 |
5 | entry mode | 0x06 |
6 | To clear the display without clearing the ram content | 0x08 |
7 | Making the cursor on and also display on | 0x0E |
8 | Making the cursor off and also display off | 0x0C |
9 | Displaying the data on cursor blinking | 0x0F |
10 | Shifting complete display data to left side | 0x18 |
11 | Shifting complete display data to right side | 0x1C |
12 | Moving cursor to one place or one character left | 0x10 |
13 | Moving cursor to one place or one character RIGHT | 0x14 |
14 | Clearing the complete display including RAM DATA | 0x01 |
15 | Set DDRAM address on cursor position | 0x80+add |
If we want to talk in brief for displaying data in LCD
- E=1; enable pin should be high
- RS=1; Register select should be high
- R/W=0; Read/Write pin should be low.
For sending command to LCD
- E=1; enable pin should be high
- RS=0; Register select should be low
- R/W=1; Read/Write pin should be high.
When you are passing a string, its better use a string pointer and increment the pointer, if you are incrementing a pointer it will automatically go the next address of the variable in which you can store your character which you wanted to display. See the below example.
void write_string(unsigned char *str) //store address value of the string in pointer *str
{
int i=0;
while(strng[i]!=’\0′) // loop will go on till the NULL character in the string
{
lcd_write(strng[i]);// sending data on LCD byte by byte
i++;
}
return;
}
Code for Interfacing the LCD to ATMEGA16:
LCD DATA port----PORT B
signal port------PORT D
rs-------PD0
rw-------PD1
en-------PD2
*/
#define LCD_DATA PORTB //LCD data port
#define ctrl PORTD
#define en PD2 // enable signal
#define rw PD1 // read/write signal
#define rs PD0 // register select signal
void LCD_cmd(unsigned char cmd);
void init_LCD(void);
void LCD_write(unsigned char data);
int main()
{
DDRB=0xff; // setting the port B
DDRD=0x07; // setting for port D
init_LCD(); // initialization of LCD
_delay_ms(50); // delay of 50 mili seconds
LCD_write_string(“hello world”); // function to print string on LCD
return 0;
}
void init_LCD(void)
{
LCD_cmd(0x38); // initialization of 16X2 LCD in 8bit mode
_delay_ms(1);
LCD_cmd(0x01); // clear LCD
_delay_ms(1);
LCD_cmd(0x0E); // cursor ON
_delay_ms(1);
LCD_cmd(0x80); // —8 go to first line and –0 is for 0th position
_delay_ms(1);
return;
}
void LCD_cmd(unsigned char cmd)
{
LCD_DATA=cmd;
ctrl =(0<<rs)|(0<<rw)|(1<<en);
_delay_ms(1);
ctrl =(0<<rs)|(0<<rw)|(0<<en);
_delay_ms(50);
return;
}
void LCD_write(unsigned char data)
{
LCD_DATA= data;
ctrl = (1<<rs)|(0<<rw)|(1<<en);
_delay_ms(1);
ctrl = (1<<rs)|(0<<rw)|(0<<en);
_delay_ms(50);
return ;
}
void LCD_write_string(unsigned char *str) //store address value of the string in pointer *str
{
int i=0;
while(str[i]!=’\0′) // loop will go on till the NULL character in the string
{
LCD_write(str[i]); // sending data on LCD byte by byte
i++;
}
return;
}