Sie sind auf Seite 1von 9

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


Constuction 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 constuct 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 coloums 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 coloums. Lets say we first make Row1 low, then read the columns. If any of the key in row1 is pressed will make the corrosponding 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 corrosponding 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...

Martix Keypad Interfacing with Microcontrollers: Connection Diagram

Keypad Connections with AVR Microcontroller


[lightbox=keypad-avr.gif|Keypad connections with AVR Microcontroller|Keypad Interfacing]

Please click on the image to enlarge it

[/lightbox]

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


[lightbox=keypad-8051.gif|Keypad connections with 8051 Microcontroller|Keypad Interfacing]

[/lightbox] Please click on the image to enlarge it 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.

Introduction | 8051 Program

Programming AVR Microcontroller


AVR Assembly Programming for 4x4 Keypad Matrix CODE:

.include "8515def.inc" .equ .equ .equ .equ col1 col2 col3 col4 = = = = PINA0 PINA1 PINA2 PINA3

.def keyval = r16 .def temp = r17 .def flags = r18 .equ keyport = PORTA .equ pressed = 0 key_init: ldi out ldi out ret get_key: ldi keyval,$0 ldi temp,$7F out keyport,temp rcall read_col sbrc flags,pressed rjmp done ldi keyval,$4 ldi temp,$BF out keyport,temp rcall read_col sbrc flags,pressed rjmp done ldi keyval,$8 ldi temp,$DF out keyport,temp rcall read_col sbrc flags,pressed rjmp done ldi keyval,$C ldi temp,$EF ;Scanning Row1 ;Make Row1 low ;Send to keyport ;Read Columns ;If key pressed ;Exit the routine ;Scanning Row2 ;Make Row2 Low ;Send to keyport ;Read Columns ;If key pressed ;Exit from routine ;Scanning Row3 ;Make Row3 Low ;Send to keyport ;Read columns ;If key pressed ;Exit the routine ;Scanning Row4 ;Make Row4 Low keyval,$F0 DDRA, keyval keyval,$0F keyport, keyval ;Make Cols as i/p ;and Rows as o/p ;Enable pullups ;on columns

out keyport,temp rcall read_col done: ret

;send to keyport ;Read columns

read_col: cbr flags, (1<<pressed) ;Clear status flag sbic PINA, col1 rjmp nextcol hold: ;Check COL1 ;Go to COL2 if not low

nextcol:

sbis PINA, col1 ;Wait for key release rjmp hold sbr flags, (1<<pressed) ;Set status flag ret ;key 1 pressed sbic PINA,col2 rjmp nextcol1 ;Check COL2 ;Goto COL3 if not low ;Wait for key release ;Key 2 pressed ;Set status flag ;Check COL3 ;Goto COL4 if no pressed ;Wait for key release ;Key 3 pressed ;Set status flag ;Check COL4 ;Exit if not low

hold1: sbis PINA, col2 rjmp hold1 inc keyval sbr flags,(1<<pressed) ret nextcol1: sbic PINA,col3 rjmp nextcol2 hold2: sbis PINA, col3 rjmp hold2 inc keyval inc keyval sbr flags, (1<<pressed) ret nextcol2: sbic PINA,col4 rjmp exit 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 clr keyval ;reset keyval cbr flags, (1<<pressed) ;No Key Pressed ret

exit:

Programming AVR in C for 4x4 Keypad Matrix CODE:

#include <avr/io.h> #define keyport PORTA #define keyportddr DDRA #define keyportpin PINA #define #define #define #define col1 col2 col3 col4 PA0 PA1 PA2 PA3

// Include file for AVR //Keypad Port //Data Direction Register //Keypad Port Pins //Column1 //Column2 //Column3 //Column4 PortA.0 PortA.1 PortA.2 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

Using these keypad routines is really simple.. here is a simple example that shows how to convert the key numbers to displayable ascii characters. CODE:

unsigned char translate(unsigned char keyval) { if(keyval<10) return keyval+'0'; else if(keyval>=10 && keyval < 16) return keyval - 10 + 'A'; else return '?'; } /* usage */ ascii_key = translate(get_key()); /* * ascii_key will have the ascii equivalent of key pressed on the keypad * i.e. 0, 1, 2, 3, 4,...., A, B, C, D, E, F */

However the above function is just an example of how to use get_key function, you can define any translate function as per your requirement.

The next section of the tutorial will cover the programming of 8051. The usage example will apply to 8051 too.

Programming 8051 Microcontroller

8051 Assembly Program for 4x4 Keypad Matrix

CODE:

keyport equ P2 col1 equ P2.0 col2 equ P2.1 col3 equ P2.2 col4 equ P2.3 keyval equ 30H pressed bit 0H key_init: mov keyport,#0FH ret get_key: mov keyval,#0 mov keyport,#7FH acall read_col jb pressed, done mov keyval,#4 mov keyport,#0BFH acall read_col jb pressed, done mov keyval,#8 mov keyport,#0DFH acall read_col jb pressed, done mov keyval,#12 mov keyport,#0EFH acall read_col done: ret read_col: clr pressed jb col1, nextcol jnb col1,$ setb pressed ret nextcol: jb col2, nextcol1 jnb col2,$ inc keyval setb pressed

;Keypad ;Column ;Column ;Column ;Column

port connected here 1 2 3 4

;To store key number ;Flag ;Make rows as o/p and col as i/p

;reset the number ;make Row1 low ;read columns ;check if flag is set ;if not then read next row ;make Row2 low ;read columns ;check if flag is set ;if not then read next row ;make row3 low ;read columns ;check if flag is set ;if not read row4 ;make row4 low ;read columns

;read columns routine ;reset the flag ;check if first key is pressed ;if yes then wait for key release ;set the flag ;read col2 ;check if second key is pressed ;if yes then wait for key release ;its key number 2 ;set the flag

ret nextcol1: jb col3, nextcol2 jnb col3,$ inc keyval inc keyval setb pressed ret nextcol2: jb col4, exit jnb col4,$ inc keyval inc keyval inc keyval setb pressed ret exit: clr pressed clr keyval ret end ;read col3 ;check if third key is pressed ;if yes then wait for key release ;its key 3 ;set the flag ;read column 4 ;check if fourth key pressed ;if yes then wait for key release ;its key 4 ;set the flag ;if no key is pressed ;clr the flag ;reset the number

C Program for 4x4 Keypad Matrix CODE:

#include <AT89X51.H> #define keyport P2 #define col1 P2_0 #define col2 P2_1 #define col3 P2_2 #define col4 P2_3 #define TRUE 1 #define FALSE 0

//Include file for 8051 //keypad connected to P2 //column 1 //column 2 //column 3 //column 4 //some defines

/* +---------------------------------------+ | 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 }

Example of how to use the above functions is given here.

Das könnte Ihnen auch gefallen