Wednesday 7 May 2014

Interface keypad with AVR microcontroller



Keypad is most widely used input device to provide input from the outside world to the microcontroller. The keypad makes an application more users interactive. The concept of interfacing a keypad with the ATmega16 is similar to interfacing it with any other microcontroller. The article of Interfacing keypad with 8051 can be referred for detailed description of the methodology used here. This article explains the interfacing of a 4x4 keypad with AVR Microcontroller (ATmega16) and displaying the output on a LCD.
The algorithm and detailed explanation for keypad interfacing is given in above mentioned article. The brief steps to interface the keypad with AVR are written below:
1. Configure the row pins or column pins.
2. Make all output pins to low and input pins to high.
3. Keep monitoring the port value, where the key pad is connected.  
4.  If there is any change in port value, make one of the output pin of port to zero and rest all high.
5.  If any of input pin found zero, write the particular pin data to LCD, else continue with the step (4).




Program:


#include <avr/io.h> 
#include <util/delay.h> // used for _delay_ms()
#include "lcd.c"

/************ Constant definitions *****************************************/

// Keypad constants
#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

unsigned char keyval;   //A variable

void key_init(void)
{
        keyportddr = 0xF0;   // 1111 0000
        keyport = 0x0F;   // 0000 1111
}

unsigned char get_key(void)
{
  unsigned char key=0;
  
  // Make rows low one by one (check for press, wait for release, return key)
  // First Row
  PORTA = 0b01111111;
  if (!bit_is_set(PINA, 0)) {while(!bit_is_set(PINA, 0)); key = 1;}
  if (!bit_is_set(PINA, 1)) {while(!bit_is_set(PINA, 0)); key = 2;}
  if (!bit_is_set(PINA, 2)) {while(!bit_is_set(PINA, 0)); key = 3;}
  if (!bit_is_set(PINA, 3)) {while(!bit_is_set(PINA, 0)); key = 4;}
  
  // Second Row
  PORTA = 0b10111111;
  if (!bit_is_set(PINA, 0)) {while(!bit_is_set(PINA, 0)); key = 5;}
  if (!bit_is_set(PINA, 1)) {while(!bit_is_set(PINA, 0)); key = 6;}
  if (!bit_is_set(PINA, 2)) {while(!bit_is_set(PINA, 0)); key = 7;}
  if (!bit_is_set(PINA, 3)) {while(!bit_is_set(PINA, 0)); key = 8;}
  
  // Third Row
  PORTA = 0b11011111;
  if (!bit_is_set(PINA, 0)) {while(!bit_is_set(PINA, 0)); key = 9;}
  if (!bit_is_set(PINA, 1)) {while(!bit_is_set(PINA, 0)); key = 10;}
  if (!bit_is_set(PINA, 2)) {while(!bit_is_set(PINA, 0)); key = 11;}
  if (!bit_is_set(PINA, 3)) {while(!bit_is_set(PINA, 0)); key = 12;}
  
  // Forth Row
  PORTA = 0b11101111;
  if (!bit_is_set(PINA, 0)) {while(!bit_is_set(PINA, 0)); key = 13;} // Column 1
  if (!bit_is_set(PINA, 1)) {while(!bit_is_set(PINA, 0)); key = 14;} // Column 2
  if (!bit_is_set(PINA, 2)) {while(!bit_is_set(PINA, 0)); key = 15;} // Column 3
  if (!bit_is_set(PINA, 3)) {while(!bit_is_set(PINA, 0)); key = 16;} // Column 4

  // Reset key ports
  key_init();
          return key;   //return false if no key pressed
}

int main (void) 
 // Init keys
 keyval = 0;  // Start with key value = 0 (ie.. not pressed)
 key_init();

 //Initialize LCD module
 LCDInit(LS_BLINK|LS_ULINE);

 //Clear the screen
 LCDClear();

 //Simple string printing
 LCDWriteString("Congrats ");

 //A string on line 2
 LCDWriteStringXY(0,1,"Loading ");
 _delay_ms(1000);
 LCDClear();

 LCDWriteString("press a key");

 LCDCmd(0xc0); // Line 2

 while (1)   // Loop forever
 {
  // Check for a key press
  keyval = get_key();
  
  if (keyval != 0)
  {
    //LCDClear();
    LCDWriteInt(keyval,2);
  }
   
  // Reset keyval before checking again
  keyval = 0;  
 }
       

Download the code here 

No comments:

Post a Comment