Lab Handout#05,06 Solved
Lab Handout#05,06 Solved
Lab Experiment #5
Interfacing Character LCD with AVR ATMEGA 16
Name Hitesh Kumar Roll # 21ES048
Signature of Lab Tutor Date
RUBRICS:
USE OF MODERN
DATA ANALYSIS
Performance Metric
PARTICIPATION
OBSERVATION/
CALCULATION
ENGINEERING
CONDUCTING
AND CODING
EXPERIMENT
TEAMWORK
Total Score
PROGRAM
RESULTS
TOOLS
0.5 0.5 1 1 1 1 05
Obtained
OBJECTIVE(S)
The purpose of this lab is to:
# Topic # Of Lectures CLO Taxonomy level
Become familiar with Character LCD and its
1
working.
3 4,5 P3, A2
Display the characters on LCD through C
2
programming of ATMEGA16
OUTCOME(S)
a. An ability to use the techniques, skills, and modern PLO5: Modern Tool Usage
engineering tools necessary for engineering practice.
b. An ability to function on multi-disciplinary teams PLO9: Individual and Teamwork
Character LCDs:
With various LCD Manufacturers, the pin positions also vary. In most of character LCDs the pin
1 starts from Left side of LCD and ends at either pin number 14 or 16. Pin description is same
for all character LCDs, the pin number 15 and 16 are for Backlight, positive supply and GND.
Pin Description of Character LCD is given in table 1.
Working of LCD:
The LCD works in two modes, command mode and data mode. RS pin of LCD is responsible for
selecting Mode. When RS =0 then command mode is selected and when RS=1 data mode is
selected.
When we instruct LCD to do some operations like clear LCD, set cursor position, increment
cursor etc, we will use command mode (RS=0).
When we want to display data on screen of LCD then we will use Data Mode (RS=1).
Initializing LCD:
There are various commands by which LCD is initialized; the list of commands is given in Table
2:
The list of necessary commands for initializing LCD is given below:
1. 8-Bit – 2 lines 5x7 matrix
2. Display ON
3. Increment Cursor
4. Clear Display Screen
5. Set Starting Cursor Position
Schematic Diagram:
We will connect LCD with Port C and D. Simplified connections are shown below:
Data lines of LCD are connected to Port C and Control Pins RS and EN of LCD are connected to
Port D Pin 7 and 6 respectively.
Programming:
Delay subroutine:
There is a built-in delay subroutine, which can be added to program by including header file
<delay.h>, and delay can be generated by calling.
_delay_ms(time in milliseconds);
Anywhere in program, where <time in milliseconds> will be replaced by a number.
For example, if we want to generate delay of 1 second (1000 milliseconds):
_delay_ms(1000);
Programming LCD:
As Port C is connected to Data lines of LCD and RS pin is connected to Port D-pin6, EN of LCD
is connected to Port D-pin7.
To write any command to LCD:
First make Port C and Port D as output ports:
DDRC=0xFF;
DDRD=0xFF;
To send any command to LCD, make RS=0, by writing logic LOW to Port D-pin 6:
PORTD &=~(1 << 6);
Now, send command, for example we are sending 8-bit mode command, which is 0x38 from
Table 2:
PORTC = 0x38;
After writing any command or sending any data, we must make EN signal of LCD HIGH for a
little time and then make it off, such that data available on data lines can be stored in LCD’s
buffer. Hence, the code will be:
To initialize LCD, we will send multiple commands and between each command we will create
some delay say 10 milliseconds. To send multiple commands to LCD, we will repeat above code,
by just changing command code, like for LCD on, Cursor Blinking, we have to write: 0x0E, the
code will be:
Now this code will be repeated for every command. Why not to make a subroutine for this code.
Making a subroutine:
To make a function or subroutine, the basic structure is:
void name (datatype& variable)
{
// Code here
}
Now whenever we call lcd_cmd (any data); it will execute subroutine define above, but it will
send data that is placed in brackets (here it is <any data>).
it will execute full subroutine of lcd_cmd but now data variable has value of 0x38. And 0x38 will
write to Port C.
The main program to write multiple commands to LCD will look like:
#include "avr/io.h"
#include "util/delay.h"
voidlcd_cmd(unsigned char cmnd)
{
PORTD &= ~(1 <<rs);
data = cmnd;
PORTD |= (1 << en);
_delay_ms(1);
PORTD &= ~(1<< en);
}
int main(void)
{
DDRD=0xFF;
DDRC=0xFF;
lcd_cmd(0x38); // 8-bit Mode
_delay_ms(1);
lcd_cmd(0x0E); // Display on, Cursor Blinking
….
return 0;
}
Similarly, if we want to make data subroutine (RS=1):
But the above subroutine will only print one character to LCD per call.
Now, we have to execute multiple commands on LCD and have to send more than one character
to display on LCD.So the main program will be:
#include "avr/io.h"
#include "util/delay.h"
int main(void)
{
DDRD=0xFF; // Port D as output
DDRC=0xFF; // Port C as output (LCD Data)
lcd_cmd(0x38); // 8-bit Mode
_delay_ms(1);
While (1);
return 0;
}
This program will write just one character ‘A’ to LCD screen, if we want to display multiple
characters to LCD, we have to repeatlcd_data(); for each letter. Hence, to avoid that we can use
arrays to write multiple bytes to LCD screen.
Using Arrays:
Using Arrays, we can store data which is to be displayed on LCD screen:
in square-brackets we will write size of word that is stored in array. Here word “Welcome”
occupies 7 bytes, hence we have written 7 in square brackets.
Now if want to write welcome on LCD, we will use loop and repeat lcd_data(); command, like:
for(int i=0;i<7;i++)
{
lcd_data(data[i]);
_delay_ms(1);
}
This will repeat lcd_data(); command and each time it will take a byte from array “data” and
display it on LCD.
C0 C1 ……… …. .. …. .. .. . .. .. . . ….. . .
...............CF
To display data starting from row 1, column 2, 0x81 command will be sent to LCD.
Lab Tasks:
Simulate on Proteus and execute the following programs on AVR Chip. Attach the C program
files and simulation results snapshots along with the handouts for the following tasks.
RUBRICS:
USE OF MODERN
DATA ANALYSIS
Performance Metric
PARTICIPATION
OBSERVATION/
CALCULATION
ENGINEERING
CONDUCTING
AND CODING
EXPERIMENT
TEAMWORK
Total Score
PROGRAM
RESULTS
TOOLS
0.5 0.5 1 1 1 1 05
Obtained
OBJECTIVE(S)
The purpose of this lab is to:
# Topic # Of Lectures CLO Taxonomy level
Determine the different aspects of Keypad
1 interfacing/programming with an ATMEGA 16.
Imitate and execute the programs to display data on 3 4,5 P3, A2
2 LCD which is given by keypad by interfacing these two
with ATmega16/32.
OUTCOME(S)
a. An ability to use the techniques, skills, and modern PLO5:Modern Tool Usage
engineering tools necessary for engineering practice.
b. An ability to function on multi-disciplinary teams PLO9: Individual and Teamwork
Interfacing of Keypad:
Keyboards/Keypads are grouped in a matrix of rows and columns. The microcontroller accesses both rows
and columns through ports (A-D in case of ATmega16/32). Therefore, with a single 8- bit port, a 4*4
matrix keypad can be connected to a microcontroller. When a key is pressed, rows and columns make a
connection and microcontroller detects which key has been pressed. All 4 columns are connected as an
input to the lower nibble (PB0-PB3) of PORTB while the 4 rows are connected as an output to the upper
nibble (PB4-PB7) of PORTB. The LCD can also be connected to show the value of the pressed key. Refer
figure 3, LCD is connected to the PORTC and PORTD (PD6-PD7).
Keypad Program:
#include <avr/io.h>
#include <util/delay.h>
#define KEY_PRT PORTB
#define KEY_DDR DDRB
#define KEY_PIN PINB
do
{
_delay_ms(20); /* 20ms key debounce time
*/ colloc = (KEY_PIN & 0x0F); /* read status of column
*/
}while(colloc == 0x0F); /* check for any key press */
while(1)
{
/* now check for rows */
KEY_PRT = 0xEF; /* check for pressed key in 1st row
*/ colloc = (KEY_PIN & 0x0F);
if(colloc != 0x0F)
{
rowloc = 0;
break;
}
if(colloc == 0x0E)
PORTA= (keypad[rowloc][0]);
else if(colloc == 0x0D)
PORTA= (keypad[rowloc][1]);
else if(colloc == 0x0B)
PORTA= (keypad[rowloc][2]);
else
PORTA= (keypad[rowloc][3]);
}
return;
}