4x4 Keypad interfacing with AVR ATmega16/ATmega32

4x4 Keypad interfacing with AVR ATmega16/ATmega32

Introduction

Keypad is used as an input device to read the key pressed by user and to process it.
4x4 keypad consists of 4 rows and 4 columns. Switches are placed between the rows and columns. A key press establishes a connection between corresponding row and column between which the switch is placed.
In order to read the key press we need to configure the rows as outputs and columns as inputs.
Columns are read after applying signals to the rows in order to determine whether or not a key is pressed and if pressed, which key is pressed.
For more information about keypad and how to use it, refer the topic 4x4 Keypad in the sensors and modules section.
4x4 Keypad
4x4 Keypad

Interfacing Diagram

Keypad Interfacing with ATmega microcontroller
Keypad Interfacing with ATmega16/32

Example

Here, we are going to interface 4x4 keypad with AVR ATmega16/ATmega32 and will display pressed key on LCD16x2.
LCD16x2 used here in 4-bit mode.
Program
/*
   4x4 Keypad Interfacing with ATmega16/32
   http://www.electronicwings.com
 */ 
#include "LCD16x2_4bit.h"
#include <avr/io.h>
#include <util/delay.h>


#define KEY_PRT  PORTA
#define KEY_DDR  DDRA
#define KEY_PIN  PINA

unsigned char keypad[4][4] = { {'7','8','9','/'},
    {'4','5','6','*'},
    {'1','2','3','-'},
    {' ','0','=','+'}};

unsigned char colloc, rowloc;

char keyfind()
{
 while(1)
 {
     KEY_DDR = 0xF0;           /* set port direction as input-output */
     KEY_PRT = 0xFF;

     do
     {
  KEY_PRT &= 0x0F;      /* mask PORT for column read only */
  asm("NOP");
  colloc = (KEY_PIN & 0x0F); /* read status of column */
     }while(colloc != 0x0F);
  
     do
     {
  do
  {
             _delay_ms(20);             /* 20ms key debounce time */
      colloc = (KEY_PIN & 0x0F); /* read status of column */
  }while(colloc == 0x0F);        /* check for any key press */
   
  _delay_ms (40);             /* 20 ms key debounce time */
  colloc = (KEY_PIN & 0x0F);
     }while(colloc == 0x0F);

    /* now check for rows */
     KEY_PRT = 0xEF;            /* check for pressed key in 1st row */
     asm("NOP");
     colloc = (KEY_PIN & 0x0F);
     if(colloc != 0x0F)
            {
  rowloc = 0;
  break;
     }

     KEY_PRT = 0xDF;  /* check for pressed key in 2nd row */
     asm("NOP");
     colloc = (KEY_PIN & 0x0F);
     if(colloc != 0x0F)
     {
  rowloc = 1;
  break;
     }
  
     KEY_PRT = 0xBF;  /* check for pressed key in 3rd row */
     asm("NOP");
            colloc = (KEY_PIN & 0x0F);
     if(colloc != 0x0F)
     {
  rowloc = 2;
  break;
     }

     KEY_PRT = 0x7F;  /* check for pressed key in 4th row */
     asm("NOP");
     colloc = (KEY_PIN & 0x0F);
     if(colloc != 0x0F)
     {
  rowloc = 3;
  break;
     }
 }

 if(colloc == 0x0E)
    return(keypad[rowloc][0]);
 else if(colloc == 0x0D)
    return(keypad[rowloc][1]);
 else if(colloc == 0x0B)
    return(keypad[rowloc][2]);
 else
    return(keypad[rowloc][3]);
}

int main(void)
{
 LCD_Init();
 LCD_String_xy(1,0,"Press a key");
    while(1)
 {
     LCD_Command(0xc0);
     LCD_Char(keyfind());       /* Display which key is pressed */
 }
}

No comments:

Post a Comment