Connecting Martix Keypad to Microcontroller
Posted: Sun Sep 20, 2009 6:11 am
Introduction
Keypads are a part of HMI or Human Machine Interface and play really important role in a small embedded system where human interaction or human input is needed. Martix keypads are well known for their simple architecture and ease of interfacing with any microcontroller. In this part of tutorial we will learn how to interface a 4x4 matrix keypad with AVR and 8051 microcontroller. Also we will see how to program then in Assembly and C.
Constructing a Matrix Keypad
Construction of a keypad is really simple. As per the outline shown in the figure below we have four rows and four columns. In between each overlapping row and column line there is a key.
So keeping this outline we can construct a keypad using simple SPST Switches as shown below:
Now our keypad is ready, all we have to do is connect the rows and columns to a port of microcontroller and program the controller to read the input.
Scanning a Matrix Keypad
There are many methods depending on how you connect your keypad with your controller, but the basic logic is same. We make the columns as i/p and we drive the rows making them o/p, this whole procedure of reading the keyboard is called scanning.
In order to detect which key is pressed from the matrix, we make row lines low one by one and read the columns. Lets say we first make Row1 low, then read the columns. If any of the key in row1 is pressed will make the corresponding column as low i.e if second key is pressed in Row1, then column2 will give low. So we come to know that key 2 of Row1 is pressed. This is how scanning is done.
So to scan the keypad completely, we need to make rows low one by one and read the columns. If any of the button is pressed in a row, it will take the corresponding column to a low state which tells us that a key is pressed in that row. If button 1 of a row is pressed then Column 1 will become low, if button 2 then column2 and so on...
Now lets move on to the programming part of keypad in our next section.
Keypad Connections with AVR Microcontroller
Circuit shown above is for demonstration and does not include any reset and crystal circuit. For practical use you need to have a reset circuit and crystal.
Keypad Connections with 8051 Microcontroller
Circuit shown above is for demonstration and does not include any reset and crystal circuit. For practical use you need to have a reset circuit and crystal.
Programming AVR Microcontroller
ASM Code
C Code
The next section of the tutorial will cover the programming of 8051.
Programming 8051 Microcontroller
ASM Code
C Code
Keypads are a part of HMI or Human Machine Interface and play really important role in a small embedded system where human interaction or human input is needed. Martix keypads are well known for their simple architecture and ease of interfacing with any microcontroller. In this part of tutorial we will learn how to interface a 4x4 matrix keypad with AVR and 8051 microcontroller. Also we will see how to program then in Assembly and C.
Constructing a Matrix Keypad
Construction of a keypad is really simple. As per the outline shown in the figure below we have four rows and four columns. In between each overlapping row and column line there is a key.
So keeping this outline we can construct a keypad using simple SPST Switches as shown below:
Now our keypad is ready, all we have to do is connect the rows and columns to a port of microcontroller and program the controller to read the input.
Scanning a Matrix Keypad
There are many methods depending on how you connect your keypad with your controller, but the basic logic is same. We make the columns as i/p and we drive the rows making them o/p, this whole procedure of reading the keyboard is called scanning.
In order to detect which key is pressed from the matrix, we make row lines low one by one and read the columns. Lets say we first make Row1 low, then read the columns. If any of the key in row1 is pressed will make the corresponding column as low i.e if second key is pressed in Row1, then column2 will give low. So we come to know that key 2 of Row1 is pressed. This is how scanning is done.
So to scan the keypad completely, we need to make rows low one by one and read the columns. If any of the button is pressed in a row, it will take the corresponding column to a low state which tells us that a key is pressed in that row. If button 1 of a row is pressed then Column 1 will become low, if button 2 then column2 and so on...
Now lets move on to the programming part of keypad in our next section.
Keypad Connections with AVR Microcontroller
Circuit shown above is for demonstration and does not include any reset and crystal circuit. For practical use you need to have a reset circuit and crystal.
Keypad Connections with 8051 Microcontroller
Circuit shown above is for demonstration and does not include any reset and crystal circuit. For practical use you need to have a reset circuit and crystal.
Programming AVR Microcontroller
ASM Code
Code: Select all
.include "8515def.inc"
.equ col1 = PINA0
.equ col2 = PINA1
.equ col3 = PINA2
.equ col4 = PINA3
.def keyval = r16
.def temp = r17
.def flags = r18
.equ keyport = PORTA
.equ pressed = 0
key_init:
ldi keyval,$F0 ;Make Cols as i/p
out DDRA, keyval ;and Rows as o/p
ldi keyval,$0F ;Enable pullups
out keyport, keyval ;on columns
ret
get_key:
ldi keyval,$0 ;Scanning Row1
ldi temp,$7F ;Make Row1 low
out keyport,temp ;Send to keyport
rcall read_col ;Read Columns
sbrc flags,pressed ;If key pressed
rjmp done ;Exit the routine
ldi keyval,$4 ;Scanning Row2
ldi temp,$BF ;Make Row2 Low
out keyport,temp ;Send to keyport
rcall read_col ;Read Columns
sbrc flags,pressed ;If key pressed
rjmp done ;Exit from routine
ldi keyval,$8 ;Scanning Row3
ldi temp,$DF ;Make Row3 Low
out keyport,temp ;Send to keyport
rcall read_col ;Read columns
sbrc flags,pressed ;If key pressed
rjmp done ;Exit the routine
ldi keyval,$C ;Scanning Row4
ldi temp,$EF ;Make Row4 Low
out keyport,temp ;send to keyport
rcall read_col ;Read columns
done:
ret
read_col:
cbr flags, (1<<pressed) ;Clear status flag
sbic PINA, col1 ;Check COL1
rjmp nextcol ;Go to COL2 if not low
hold:
sbis PINA, col1 ;Wait for key release
rjmp hold
sbr flags, (1<<pressed) ;Set status flag
ret ;key 1 pressed
nextcol:
sbic PINA,col2 ;Check COL2
rjmp nextcol1 ;Goto COL3 if not low
hold1:
sbis PINA, col2 ;Wait for key release
rjmp hold1
inc keyval ;Key 2 pressed
sbr flags,(1<<pressed) ;Set status flag
ret
nextcol1:
sbic PINA,col3 ;Check COL3
rjmp nextcol2 ;Goto COL4 if no pressed
hold2:
sbis PINA, col3 ;Wait for key release
rjmp hold2
inc keyval ;Key 3 pressed
inc keyval
sbr flags, (1<<pressed) ;Set status flag
ret
nextcol2:
sbic PINA,col4 ;Check COL4
rjmp exit ;Exit if not low
hold3:
sbis PINA, col4 ;Wait for key release
rjmp hold3
inc keyval ;Key 4 Pressed
inc keyval
inc keyval
sbr flags, (1<<pressed) ;Set status flag
ret
exit:
clr keyval ;reset keyval
cbr flags, (1<<pressed) ;No Key Pressed
ret
Code: Select all
#include <avr/io.h> // Include file for AVR
#define keyport PORTA //Keypad Port
#define keyportddr DDRA //Data Direction Register
#define keyportpin PINA //Keypad Port Pins
#define col1 PA0 //Column1 PortA.0
#define col2 PA1 //Column2 PortA.1
#define col3 PA2 //Column3 PortA.2
#define col4 PA3 //Column4 PortA.3
#define TRUE 1
#define FALSE 0
unsigned char keyval; //A variable
/*
+---------------------------------------+
| Prototype: void key_init(void); |
| Return Type: void |
| Arguments: None |
| Description: Initialize ports and |
| Keypad. |
+---------------------------------------+
*/
void key_init(){
keyportddr = 0xF0;
keyport = 0x0F;
}
/*
+-----------------------------------------------+
| Prototype: unsigned char get_key(void); |
| Return Type: unsigned char |
| Arguments: None |
| Description: To read key from the keypad |
+-----------------------------------------------+
*/
unsigned char get_key(){
unsigned char i,key=1;
for(i=0;i<4;i++){ //Loop for 4 rows
keyport &=~(0x80>>i); //Make rows low one by one
if(!(keyportpin & (1<<col1))){
//check COL1
while(!(keyportpin & (1<<col1)));
//wait for release
return key;
//return pressed key value
}
if(!(keyportpin & (1<<col2))){
//Check COL2
key += 1;
//Second key pressed
while(!(keyportpin & (1<<col2)));
//wait for release
return key;
//return key value
}
if(!(keyportpin & (1<<col3))){
//Check COL3
key += 2;
//Third key pressed
while(!(keyportpin & (1<<col3)));
//Wait for release
return key;
//Return value
}
if(!(keyportpin & (1<<col4))){
//check COL4
key += 3;
//Fourth key pressed
while(!(keyportpin & (1<<col4)));
//Wait for release
return key;
//Return key value
}
key +=4; //Next row
keyport |= 0x80>>i;
//make read row high again
}
return FALSE; //return false if no key pressed
}
Programming 8051 Microcontroller
ASM Code
Code: Select all
keyport equ P2 ;Keypad port connected here
col1 equ P2.0 ;Column 1
col2 equ P2.1 ;Column 2
col3 equ P2.2 ;Column 3
col4 equ P2.3 ;Column 4
keyval equ 30H ;To store key number
pressed bit 0H ;Flag
key_init:
mov keyport,#0FH ;Make rows as o/p and col as i/p
ret
get_key:
mov keyval,#0 ;reset the number
mov keyport,#7FH ;make Row1 low
acall read_col ;read columns
jb pressed, done ;check if flag is set
mov keyval,#4 ;if not then read next row
mov keyport,#0BFH ;make Row2 low
acall read_col ;read columns
jb pressed, done ;check if flag is set
mov keyval,#8 ;if not then read next row
mov keyport,#0DFH ;make row3 low
acall read_col ;read columns
jb pressed, done ;check if flag is set
mov keyval,#12 ;if not read row4
mov keyport,#0EFH ;make row4 low
acall read_col ;read columns
done:
ret
read_col: ;read columns routine
clr pressed ;reset the flag
jb col1, nextcol ;check if first key is pressed
jnb col1,$ ;if yes then wait for key release
setb pressed ;set the flag
ret
nextcol: ;read col2
jb col2, nextcol1 ;check if second key is pressed
jnb col2,$ ;if yes then wait for key release
inc keyval ;its key number 2
setb pressed ;set the flag
ret
nextcol1: ;read col3
jb col3, nextcol2 ;check if third key is pressed
jnb col3,$ ;if yes then wait for key release
inc keyval ;its key 3
inc keyval
setb pressed ;set the flag
ret
nextcol2: ;read column 4
jb col4, exit ;check if fourth key pressed
jnb col4,$ ;if yes then wait for key release
inc keyval ;its key 4
inc keyval
inc keyval
setb pressed ;set the flag
ret
exit: ;if no key is pressed
clr pressed ;clr the flag
clr keyval ;reset the number
ret
end
Code: Select all
#include <AT89X51.H> //Include file for 8051
#define keyport P2 //keypad connected to P2
#define col1 P2_0 //column 1
#define col2 P2_1 //column 2
#define col3 P2_2 //column 3
#define col4 P2_3 //column 4
#define TRUE 1 //some defines
#define FALSE 0
/*
+---------------------------------------+
| Prototype: void key_init(void); |
| Return Type: void |
| Arguments: None |
| Description: Initialize ports and |
| Keypad. |
+---------------------------------------+
*/
void key_init(){
keyport &=0x0F; //make Rows as o/p and cols are i/p
}
/*
+-----------------------------------------------+
| Prototype: unsigned char get_key(void); |
| Return Type: unsigned char |
| Arguments: None |
| Description: To read key from the keypad |
+-----------------------------------------------+
*/
unsigned char get_key(){
unsigned char i,k,key=0;
k=1;
for(i=0;i<4;i++){ //loop for 4 rows
keyport &=~(0x80>>i); //to make rows low 1 by 1
if(!col1){ //check if key1 is pressed
key = k+0; //set key number
while(!col1); //wait for release
return key; //return key number
}
if(!col2){ //check if key2 is pressed
key = k+1; //set key number
while(!col2); //wait for release
return key; //return key number
}
if(!col3){ //check if key3 is pressed
key = k+2; //set key number
while(!col3); //wait for release
return key; //return key number
}
if(!col4){ //check if key4 is pressed
key = k+3; //set key number
while(!col4); //wait for release
return key; //return key number
}
k+=4; //next row key number
keyport |= 0x80>>i; //make the row high again
}
return FALSE; //return false if no key pressed
}