4 Bit LCD interfacing

4 Bit LCD Interfacing with Atmel AVR Micro-controllers

Different Interfacing Techniques

Most of the time in your projects you have to interface some displaying unit. A 16x2 LCD is best solution for this purpose. There are three ways to interface a 16x2 LCD with a micro-controller.

  • 8 Bit Interfacing
  • 4 bit interfacing
  • I2C interfacing

8 Bit Interfacing

8 Bit interfacing is the most common method to interface your LCD with microcontrollers. But there is a big disadvantage of using this technique. You have to utilize at least 10 pins of microcontroller in which 2 pins for commands and 8 pins for data.

I2C Interfacing

I2C interfacing is the latest method to interface a 16x2 LCD. It needs only two wires to handle all communication. There are two ways to implement this method. Either you buy I2C 16x2 LCD direct or either buy a typical 16x2 LCD with I2C Converter. Both ways will lead you to little bit higher price as compared to other interfacing method.

4 Bit Interfacing

4 bit interfacing is optimized method to interface your typical 16x2 LCD with micro-controllers because it needs only 6 pins of micro-controller to work properly. Moreover this method does not need any extra things. You just have to add some extra coding and that’s all. In this article I will focus on 4 bit LCD interfacing.

Pin Configuration and Connections

I am not going into useless details of LCD interfacing. Let’s just focus on the practical part of it. In the figure below you can watch the connections you have to do when using the LCD.  I used Atmega8 in this example which is from the family of Atmel AVR Microcontrollers. Here, most important part is the variable resistor present in the diagram. This resistor has no use in simulation software but in real system you have to adjust the value of this resistor properly.  Remember if your LCD code is perfectly working in simulation software then there is no reason that your LCD does not work in real system. There may be some loose connection, damaged LCD, or variable resistor problem.

 

Figure 1: Connections

In connection diagram, you can see that I grounded the R/W pin. It is basically read/write pin and normally we give zero level (0) to this pin. The remaining pins (D0-D7) are data pins. As you are learning 4 bit interfacing so you don’t have to worry about (D0-D3) pins.

Initializing LCD in 4 Bit Mode:

 There are commands through which LCD is initialized. I used an initialization function for this purpose. In normal case, you can use this function as it is. But if you want to alter your LCD according to your requirement then you have to study the table shown below and change your initialization code accordingly.

Figure 2: Control Commands

Now carefully understand the function below and match with the above table.

void lcd_iniit(void){
 writecmd(0x02);// Return Home
 writecmd(0x28);//4 bit initialization-2line display-
 writecmd(0x0C);//Display on-Cursor off-Blink off
 writecmd(0x01);//Clear All Display Data
 writecmd(0x06);//after every character cursor will move to right
 }

Difference Between Command and Data

Commands are that information which controls your LCD whereas Data is that information which displays on the LCD screen. But we have only data pins here. In fact “RS Pin” of LCD is used here to switch the command / data state. To send commands you have to set “LOW” the RS Pin as shown in function below.  To send data you have to set it to “HIGH”. The only difference between command and data function is this PIN position.

Study this function carefully:

int writecmd(char z){      
ctrl &= ~(1<<RS);// To write Commands
 char z1 = z << 4;// To shift 4 bits
 z &= 0b11110000; //masking lower 4 bits
 ctrl = (ctrl & 0x0F)|z; // sending data to LCD
 ctrl |= (1<<E);//send falling edge to send data to LCD
 _delay_ms(1);
 ctrl &= ~(1<<3);
 _delay_ms(1);
 z1 &= 0b11110000;//Again masking lower 4 bits
 ctrl = (ctrl & 0x0F)|z1;//Sending Remaining Data to LCD
 ctrl |= (1<<E);//send falling edge to send data to LCD
 _delay_ms(1);
 ctrl &= ~(1<<E);
 _delay_ms(1);
 return 0;
 }

Here, ctrl is the PORTB which I am using in this example. You have to send falling edge on Pin “E” of LCD to send data every time. Don’t worry you can get whole example code at the end of this article

Function to Control the Cursor Position

void LCD_XY(unsigned char x, unsigned char y){
 unsigned char firstcharadrs[] = {0x80, 0xC0,0x94,0xD4};
 writecmd(firstcharadrs[y-1] + x - 1);
 _delay_us(100);
 }

This is the very beautiful function to control the cursor of the 16x2 LCD. As you know here 16 is the Columns and 2 is the Rows of LCD. So, if you want to go to the 2nd row and 10th column then you just have to right LCD_XY(10,2) in your coding.

Sending Strings to 16x2 LCD

You can’t send characters one by one to the LCD because it makes your code bulky. There must be some technique through which you can send whole strings at a time. The function below will help you in this matter.

void putstring(char const *str){
 unsigned char z=0;
 //Sending character by character to LCD
 while (str[z]!=0){
 writedata(str[z]);
 z++;
 }
 }

This function will send strings to the LCD easily. Now download the example code and check the example code by yourself. Once you are able to run my code. Alter the code and check the effects. This code is written for the Atmega8 microcontroller and also can use for other Atmel AVR microcontrollers. I wrote this code on Atmel Studio.

I hope you understand now how to interface your 16x2 LCD with Atmel AVR Microcontrollers in 4 bit mode. In case of any queries feel free to comment below and don’t forget to like our facebook page.

To Download Complete Code click the button below:

 Complete Code

Ismail

Electrical engineering is my profession, my hobby and my passion. I completed bachelors of electrical engineering in 2015. Currently I am working with an Electric Utility Company. Power Electronics, Embedded Systems and Energy Metering are my fields of specialization. In free time I listen music and watch movies.

What do you think?