
/*----------------------------------------------------------------------------------*/
/* File Name	: Keypad
/* Processor	: 87C752
/* ToolChain	: Keil C51 V8.0
/* Author	: T.L
/* Version	: 1.0
/* Date		: 08/22/06
/*----------------------------------------------------------------------------------*/

#pragma code
#pragma aregs
#pragma db

#include <Reg752.h>
#include <Delay.h>

/*----------------------------------------------------------------------------------*/
/* Global Constants
/*----------------------------------------------------------------------------------*/

#define	SysClk		12000000		// 12MHz
#define True		1
#define	False		0
#define Num_Col		4
#define Num_Row		4
#define Lcd_Kp		P3

const char code row_scan[4] = {0x0e, 0x0d, 0x0b, 0x07};

const char code col_val[16] = {0x00, 0x00, 0x01, 0x00,
			       0x02, 0x02, 0x00, 0x00,
			       0x03, 0x00, 0x00, 0x00,
			       0x00, 0x00, 0x00, 0x00};

const char code key_code[16] = {'1', '2', '3', 'A',
			        '4', '5', '6', 'B',
			        '7', '8', '9', 'C',
			        '*', '0', '#', 'D'};

extern bit flag;
extern unsigned char valid_key;

/*----------------------------------------------------------------------------------*/
/* Function prototypes
/*----------------------------------------------------------------------------------*/

void Keypad (void);

/*----------------------------------------------------------------------------------*/

void Keypad (void)
{
	unsigned char col, row, key;
	static unsigned char cnt, key_save = 0x00;

	Lcd_Kp = 0xf0;				  //Set P3 high nibble as input

	for (row = 0; row < 4; row++)
	{
		Lcd_Kp = Lcd_Kp | row_scan[row];  //Sequentially set row0 to row 4 low

		col = Lcd_Kp;			  //Read port

		col = ((col & 0xf0) ^ 0xf0) >> 4; //Mask high nibble then shift to low

	// In order to get correct keycode col values are modified by col_val table
	// col_val table needs only 9 values corresponding to col values 1, 2, 4, 8.
	// The first value of the table is null value = 0.
	// Keycodes are found based on the formula:
	// Key = col + (row * 4).
	// Where: 4 = number of columns.
	// 	  col = 0 -> 3
	// 	  row = 0 -> 3
 
		if (col != 0)
		{
			key = (col_val[col] + (row * Num_Col));

			key = key_code[key];

	// Key debounce is done by comparing 10 conseccutive values stored in key
	// and key_save variables. Every time the routine is called it will compare
	// these values. If they are equaled then cnt increases by 1. After 10 time
	// the key is register to valid_key and visible to the calling routine and
	// cnt is reset to 0. 

			if (key != key_save)
			{ 
				key_save = key;

				cnt = 1;
			}

			else if ((key == key_save) && (cnt < 10))
			{
				cnt++;

			}

			else
			{
				valid_key = key_save;

				cnt = 0;

				flag = 1;
			}
		}
		Lcd_Kp = 0xf0;
	}
}

/*----------------------------------------------------------------------------------*/
