Tuto. 12 - Keypad

PIC tutorial 12 - Keypad

Print
Category: PIC Tutorials
Published Date Written by Francois

Tutorial 12

Fig. 1 Board 4 with keypad and graphic lcd display

Description:

It's time to start being able to interact the hardware. A basic way is with some buttons. We'll look at interfacing with a 16 keys keypad with a processor board.
The program will simply display the keys pressed on the LCD screen. You will need a processor board, a power supply, the graphical or alphanumeric display on port B and the keypad on port C. 

You can download the files for this tutorial in the zip file pic_tutorial12.zip.

The boards can be powered by one of the PSU boards (powered from USB port), or between 2.5 to 5V.

Requirements:

Processor boardAny board (board 4 used in example)

Extension(s)keypad

 alphanumeric or graphic LCD display

Power supplyPSU 1, 2 or 3. Depends on board used.

LanguageCCS C

ProgrammerPicKIT 2


Program:

#define board_id 4
#define display_type 2 // 1: alphanumeric display, 2: graphic display
#include "lib\mainboard.c" // Load board module
#include "lib\Kpad_lib.c"
#if (display_type == 1) // load alphanumeric display library
  #include "lib\lcd_lib.c"
#else // or graphic display
  #include "lib\nok3310_lib.c"
#endif
void main() {
  unsigned char key, count;
  boot_up(); // Initialise the processor board
  init_display(); // Initialise display
  count = 0;
  while (true) { // main loop
    key=read_kpad(); // read keyboard
    if(key!=0) { // if key pressed, display it
      display_putc(key); // display key on display
      count ++; // increment counter
      if (count > 19) { // if count up to 20
        count = 0; // reset count and erase screen
        display_putc('\f');
      }
    }
  }
}

This is a small program. First, as usual, the processor board used is defined with board_id. It then define which type of display is used: set to 1 for alphanumeric or 2 for graphical LCD display. The libraries as then loaded.

The main function initialise the processor board, the display and the counter to count the number of keys displayed. The screen will be erased after 20 keys are pressed.
For the main loop, we simply read the keypad. If a key was pressed, it is displayed on the screen. the counter is incremented. If the counter counted 20 keys, the counter is reset and the screen erased, resetting the cursor position to 0,0.

The keypad library is based on the keypad driver supplied with CCS compiler, but adapted for 16 or 12 keys keypad.

#ifndef _KPAD_LIB
  #define _KPAD_LIB
  #ifndef kpad_keys // 12 or 16 keys keypad
    #define kpad_keys 16
  #endif
  #byte kpad = pc // keypad plugged in port C
  #define set_tris_kpad(x) set_tris_c(x)
  #define COL0 (1 << 4) // Col0 is bit 4
  #define COL1 (1 << 5) // Col1 is bit 5
  #define COL2 (1 << 6) // ...
  #if (kpad_keys == 16) // if 16 keys, manage the 4th column
    #define COL3 (1 << 7)
  #endif
  #define ROW0 (1 << 0) // Row 0 is bit 0
  #define ROW1 (1 << 1) // Row 1 is bit 1
  #define ROW2 (1 << 2) // ...
  #define ROW3 (1 << 3)
  #define ALL_ROWS (ROW0|ROW1|ROW2|ROW3) // macro to set all rows to 1
  #if (kpad_keys == 16) // macro to set all pins connected to the keypad to 1
    #define ALL_PINS (ALL_ROWS|COL0|COL1|COL2|COL3)
  #else
    #define ALL_PINS (ALL_ROWS|COL0|COL1|COL2)
  #endif
  #if (kpad_keys == 16) // Keypad layout for 16 or 12 keys keypad
    unsigned char const KEYS[4][4] = {
      {'0','1','2','3'},
      {'4','5','6','7'},
      {'8','9','A','B'},
      {'C','D','E','F'}
    };
  #else
    unsigned char const KEYS[4][3] = {
      {'1','2','3'},
      {'4','5','6'},
      {'7','8','9'},
      {'*','0','#'}
    };
  #endif
  unsigned char read_kpad( ) { // function to read keypad. returns key pressed or \0 if no key pressed
    static unsigned char kpad_call_count; // holds the number of times the function was called for debouncing keys
    static short int kpad_down; // bit to indicate if key is pressed (1 when true)
    static unsigned char last_key; // store last key detected for debouncing
    static unsigned char col; // Column counter to scan each column
    unsigned char row; // Row counter to scan each row
    unsigned char kchar; // chareacter to return
    kchar='\0'; // initialise character for no key pressed
    if(++kpad_call_count>12) { // scan 12 columns (4 full scans on 12 keys, 3 on 16 keys)
      switch (col) { // read column indicated by col
        case 0 : set_tris_kpad(ALL_PINS&~COL0); // set keypad port inputs/outputs (all pins as input except current row
          kpad=~COL0&ALL_PINS; // write 1 to keypad port except current row as 0
          break;
        case 1 : set_tris_kpad(ALL_PINS&~COL1);
          kpad=~COL1&ALL_PINS;
          break;
        case 2 : set_tris_kpad(ALL_PINS&~COL2);
          kpad=~COL2&ALL_PINS;
          break;
        case 3 : set_tris_kpad(ALL_PINS&~COL3);
          kpad=~COL3&ALL_PINS;
          break;
      }
      if(kpad_down) { // if key was pressed
        if((kpad & (ALL_ROWS))==(ALL_ROWS)) { // check if key is now released
          kpad_down=FALSE; // if so, reset flag and prepare return value
          kchar=last_key;
          last_key='\0';
        }
      } else { // if no key was detected
        if((kpad & (ALL_ROWS))!=(ALL_ROWS)) { // check if key pressed in current column
          if((kpad & ROW0)==0) // set row where key was detected
            row=0;
          else if((kpad & ROW1)==0)
            row=1;
          else if((kpad & ROW2)==0)
            row=2;
          else if((kpad & ROW3)==0)
            row=3;
          last_key =KEYS[row][col]; // get character from keypad layout at current column and row
          kpad_down = TRUE; // update flag as key was detected
        } else { // if no key detected, scan next column
          ++col;
          #if (kpad_keys == 16) // reset column number when all column were scanned
            if(col==4) col=0;
          #else
            if(col==3) col=0;
          #endif
        }
      }
      kpad_call_count=0; // reset deboucing counter
    }
    set_tris_kpad(ALL_PINS); // all keypad port pins as inputs
    return(kchar); // return key detected
  }
#endif

First we check if we have the number of keys on the keypad (12 or 16). If not, we default it to 16. Then we tell where the keypad is plugged in (port C).
Then we describe how the keypad is connected: each column and each row is assigned a bit. Then macros are defined to help setting the pins to input or output when scanning each column of the keypad.
We then have the layout of the keypad: its a table of keys, with the location as row/column. This is critical in matching the right key when detecting which key was pressed.

All details about the keypad is known. The funstion to read the keypad follows. Each time the function is called, it scans a row of the keypad. The function needs to be called several times to scan fully the keypad. We'll call the function 12 times before returning the key pressed. It means the keypad is scanned fully 3 or 4 times, for 16 or 12 way.
The bit of the column scanned is set to 0. If a key is pressed, the corresponding row would read 0.
If a key had been detected on a previous scan, we check if it was released. If so, the flag to say a key was detected is reset, and the key detected stored. If no key was previously pressed, we check if one is pressed in the current column. If so, we detect what row it is at and get from the lookup table the character stored at this row/column and set the flag to say a key was detected.
If no key was pressed, we increment the column counter to scan the next column the next time the funciton is called.

If the 12 scans were done, we set all pin where the keypad is connected as input and return the value read.. 

Compile the project and program the target with a PicKIT 2 programmer for example. Connect the processor board to the keypad on port C, the display on port B (make sure you use the display selected by the variable display_type. Power up the boards.
Each time you press a key, its character is displayed on the screen. After 20 keys were pressed, the screen is erased, and the next key will be displayed on the top left of the display.


Files and links:

Tutorial 12 source files.
Processor board 4.
graphic LCD display.
Keypad board.

Post your comments...

    Copyright 2011. Poker Games. Copyright © 2012 riaDesign