|
发表于 2006-12-22 08:03:09
|
显示全部楼层
对应3楼的源代码
/***********************************************************************/
/* */
/* PROJECT :Atmel AVR Design Contest 2006: AT3244 */
/* FILE :KeyPad.c */
/* DATE :April 27, 2006 */
/* DESCRIPTION :This file contains the basic set of functions to */
/* input data from the keypad. */
/* */
/***********************************************************************/
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "usbdrv.h"
#include "KeyPad.h"
#include "LCD.h"
#include "ADC.h"
#include "ISO7816.h"
const char KeyPad[10][10] PROGMEM = {
{'@', '0', '#', '_', '&', '$', '.', '(', ')', '\0'}, // Keypad '0'
{' ', '1', '*', '+', '-', '/', '?', '!', '%', '\0'}, // Keypad '1'
{'a', 'b', 'c', '2', 'A', 'B', 'C', '\0', '\0', '\0'}, // Keypad '2'
{'d', 'e', 'f', '3', 'D', 'E', 'F', '\0', '\0', '\0'}, // Keypad '3'
{'g', 'h', 'i', '4', 'G', 'H', 'I', '\0', '\0', '\0'}, // Keypad '4'
{'j', 'k', 'l', '5', 'J', 'K', 'L', '\0', '\0', '\0'}, // Keypad '5'
{'m', 'n', 'o', '6', 'M', 'N', 'O', '\0', '\0', '\0'}, // Keypad '6'
{'p', 'q', 'r', 's', '7', 'P', 'Q', 'R', 'S', '\0'}, // Keypad '7'
{'t', 'u', 'v', '8', 'T', 'U', 'V', '\0', '\0', '\0'}, // Keypad '8'
{'w', 'x', 'y', 'z', '9', 'W', 'X', 'Y', 'Z', '\0'}, // Keypad '9'
};
/*****************************************************************************
Name: KeyPad_GetKey
Parameters: None
Returns: Key pressed coded in BCD (16 keys)
Description: This function gets a key from a 16-key keypad using the ADC
converter. To improve the reliability it takes two samples
before deciding on the key value
*****************************************************************************/
unsigned char KeyPad_GetKey (void)
{
unsigned char i;
unsigned short raw[KEYPAD_MAX_SAMPLES];
do {
for (i = 0; i < KEYPAD_MAX_SAMPLES; i++) {
raw = ADC_Read (KBD); // Get raw ADC converter value
if (raw >= KEYPAD_RAW_NO_KEY) { // Lower digital Limit for checking the
// corresponding digital value of 'NO KEY'
return KEYPAD_NO_KEY; // Return 'NO KEY' pressed code
}
else if (raw >= KEYPAD_RAW_D) { // Lower digital Limit for checking the
// corresponding digital value of 'D' key
raw = KEYPAD_D; // Key 'D' code in BCD
continue; // Try again
}
else if (raw >= KEYPAD_RAW_C) { // Lower digital Limit for checking the
// corresponding digital value of 'C' key
raw = KEYPAD_C; // Key 'C' code in BCD
continue; // Try again
}
else if (raw >= KEYPAD_RAW_B) { // Lower digital Limit for checking the
// corresponding digital value of 'B' key
raw = KEYPAD_B; // Key 'B' code in BCD
continue; // Try again
}
else if (raw >= KEYPAD_RAW_A) { // Lower digital Limit for checking the
// corresponding digital value of 'A' key
raw = KEYPAD_A; // Key 'A' code in BCD
continue; // Try again
}
else if (raw >= KEYPAD_RAW_ENTER) { // Lower digital Limit for checking the
// corresponding digital value of 'ENTER' key
raw = KEYPAD_ENTER; // Key 'ENTER' code in BCD
continue; // Try again
}
else if (raw >= KEYPAD_RAW_9) { // Lower digital Limit for checking the
// corresponding digital value of '9' key
raw = KEYPAD_9; // Key '9' code in BCD
continue; // Try again
}
else if (raw >= KEYPAD_RAW_6) { // Lower digital Limit for checking the
// corresponding digital value of '6' key
raw = KEYPAD_6; // Key '6' code in BCD
continue; // Try again
}
else if (raw >= KEYPAD_RAW_3) { // Lower digital Limit for checking the
// corresponding digital value of '3' key
raw = KEYPAD_3; // Key '3' code in BCD
continue; // Try again
}
else if (raw >= KEYPAD_RAW_0) { // Lower digital Limit for checking the
// corresponding digital value of '0' key
raw = KEYPAD_0; // Key '0' code in BCD
continue; // Try again
}
else if (raw >= KEYPAD_RAW_8) { // Lower digital Limit for checking the
// corresponding digital value of '8' key
raw = KEYPAD_8; // Key '8' code in BCD
continue; // Try again
}
else if (raw >= KEYPAD_RAW_5) { // Lower digital Limit for checking the
// corresponding digital value of '5' key
raw = KEYPAD_5; // Key '5' code in BCD
continue; // Try again
}
else if (raw >= KEYPAD_RAW_2) { // Lower digital Limit for checking the
// corresponding digital value of '2' key
raw = KEYPAD_2; // Key '2' code in BCD
continue; // Try again
}
else if (raw >= KEYPAD_RAW_ESC) { // Lower digital Limit for checking the
// corresponding digital value of 'ESC' key
raw = KEYPAD_ESC; // Key 'ESC' code in BCD
continue; // Try again
}
else if (raw >= KEYPAD_RAW_7) { // Lower digital Limit for checking the
// corresponding digital value of '7' key
raw = KEYPAD_7; // Key '7' code in BCD
continue; // Try again
}
else if (raw >= KEYPAD_RAW_4) { // Lower digital Limit for checking the
// corresponding digital value of '4' key
raw = KEYPAD_4; // Key '4' code in BCD
continue; // Try again
}
else { // Lower digital Limit for checking the
// corresponding digital value of '1' key
raw = KEYPAD_1; // Key '1' code in BCD
}
}
} while (raw[0] != raw[1]); // Repeat until both samples are equal
return raw[1]; // Return key code in BCD
}
/*****************************************************************************
Name: KeyPad_WaitKeyRelease
Parameters: None
Returns: None
Description: This function waits for a key release
*****************************************************************************/
void KeyPad_WaitKeyRelease (void)
{
unsigned char key = KEYPAD_NO_KEY;
do { // Wait until the key has been released
key = KeyPad_GetKey(); // Sample keypad
} while ((key < KEYPAD_NO_KEY) && ISO7816_SmartCardReady());
}
/*****************************************************************************
Name: KeyPad_GetDigit
Parameters: key_buff -> keys pressed string in ASCII
digits -> number of digits to read
mode -> KEY_HIDE (1): show asterisks instead of digits
KEY_SHOW (0): show the entered numbers
Returns: None
Description: This function waits for a numeric input from the keypad and
at the same time displays the key pressed on the LCD. Depending
on the mode (HIDE / SHOW) the key is masked or not with '*'
*****************************************************************************/
void KeyPad_GetDigit (unsigned char *digit_buff, unsigned char digits, unsigned char mode)
{
unsigned char i = 0;
unsigned char state = KEYPAD_WAIT_STATE;
unsigned char key = KEYPAD_NO_KEY;
unsigned char last_key = KEYPAD_NO_KEY;
unsigned char lcd_buff [LCD_CHARS_PER_LINE + 1];
*digit_buff = '\0'; // Initialize display buffers
*lcd_buff = '\0';
if (mode)
LCD_String (LCD_LINE2, lcd_buff); // Display value masked with asterisks or
else
LCD_String (LCD_LINE2, digit_buff); // Display plain value
LCD_Cursor (LCD_CURSOR_ON); // Show cursor
while (ISO7816_SmartCardReady() && (i < LCD_CHARS_PER_LINE)) {
switch (state) {
case KEYPAD_WAIT_STATE: // Wait for a numeric key press
do {
usbPoll(); // Refresh USB connection
key = KeyPad_GetKey(); // Sample keypad
} while ((key > KEYPAD_ENTER) && ISO7816_SmartCardReady());
if (!ISO7816_SmartCardReady()) { // If the smart card is removed
*digit_buff = '\0'; // Clear display buffers
*lcd_buff = '\0';
LCD_Cursor (LCD_CURSOR_OFF); // Hide cursor
return; // Exit
}
state = KEYPAD_HANDLING_STATE; // Set next keypad state
break;
case KEYPAD_HANDLING_STATE: // Key handling
switch (key) {
case KEYPAD_ESC: // Delete previous number
if (i > 0) { // If cursor position other than first
i--;
}
*(digit_buff + i) = ' ';
*(digit_buff + i + 1) = '\0';
*(lcd_buff + i) = ' ';
*(lcd_buff + i + 1) = '\0';
break;
case KEYPAD_ENTER: // Enter key
*(digit_buff + i) = '\0'; // Finish the input string
*(lcd_buff + i) = '\0';
LCD_Cursor (LCD_CURSOR_OFF); // Hide cursor
return;
default: // Numeric key: 0 to 9
if (i < digits) { // Convert to ASCII
*(digit_buff + i) = (char)(key + '0');
*(digit_buff + i + 1) = '\0';
*(lcd_buff + i) = '*'; // Display asterisk
*(lcd_buff + i + 1) = '\0';
i++;
}
break;
}
last_key = key; // Save the last key pressed value
if (mode)
LCD_String (LCD_LINE2, lcd_buff); // Display value masked with asterisk
else
LCD_String (LCD_LINE2, digit_buff); // Display plain value
if (key == KEYPAD_ESC) // If the DEL/ESC key was pressed
LCD_Cursor (LCD_CURSOR_LEFT); // Move cursor to the left
state = KEYPAD_PRESSED_STATE; // Set next keypad state
break;
case KEYPAD_PRESSED_STATE: // Wait for numeric key release
do {
key = KeyPad_GetKey(); // Sample keypad
} while ((key <= KEYPAD_ENTER) && ISO7816_SmartCardReady());
if (!ISO7816_SmartCardReady()) { // If smart card withdrawal
*digit_buff = '\0'; // Discard buffer contents
*lcd_buff = '\0';
LCD_Cursor (LCD_CURSOR_OFF); // Hide cursor
return; // Exit
}
state = KEYPAD_WAIT_STATE; // Re-initialize state machine
break;
}
}
LCD_Cursor (LCD_CURSOR_OFF); // Hide cursor
}
/*****************************************************************************
Name: KeyPad_GetAlpha
Parameters: alpha_buff -> keys pressed string in ASCII
letters -> number of alphanumeric characters to read
Returns: None
Description: This function waits for an alphanumeric input from the keypad and
at the same time displays the key pressed on the LCD. The
alphanumeric data is entered using a multiple keystroke algorithm
similar to the input mechanism found on a cellular phone.
*****************************************************************************/
void KeyPad_GetAlpha (unsigned char *alpha_buff, unsigned char letters)
{
unsigned char i = 0;
unsigned char j = 0;
unsigned char key = KEYPAD_NO_KEY;
unsigned char last_key = KEYPAD_NO_KEY;
unsigned long int timeout = 1000;
unsigned char state = KEYPAD_WAIT_STATE;
*alpha_buff = '\0'; // Initialize display buffer
LCD_String (LCD_LINE2, alpha_buff); // Display string
LCD_Cursor (LCD_CURSOR_ON); // Show cursor
while (ISO7816_SmartCardReady() && (i < LCD_CHARS_PER_LINE)) {
switch (state) {
case KEYPAD_WAIT_STATE: // Wait for a numeric key press
do {
key = KeyPad_GetKey(); // Sample keypad
} while ((key > KEYPAD_ENTER) && ISO7816_SmartCardReady());
if (!ISO7816_SmartCardReady()) { // If the smart card is removed
*alpha_buff = '\0'; // Clear display buffers
LCD_Cursor (LCD_CURSOR_OFF); // Hide cursor
return; // Exit
}
state = KEYPAD_HANDLING_STATE; // Set next keypad state
break;
case KEYPAD_HANDLING_STATE: // Key handling
switch (key) {
case KEYPAD_ESC: // If DEL/ESC key pressed
if (i > 0) {
i--; // Clear previous character
}
*(alpha_buff + i) = ' '; // Delete with white space
*(alpha_buff + i + 1) = '\0';
LCD_Cursor (LCD_CURSOR_LEFT); // Move cursor to the left
break;
case KEYPAD_ENTER:
*(alpha_buff + i) = '\0'; // Finish the input string
LCD_Cursor (LCD_CURSOR_OFF); // Hide cursor
return; // Exit
default:
if (i < letters) { // Get first character of the key
*(alpha_buff + i) = pgm_read_byte (&KeyPad[key][0]);
*(alpha_buff + i + 1) = '\0';
j = 0;
}
break;
}
if (i < letters) {
last_key = key; // Save value of last key pressed
LCD_String (LCD_LINE2, alpha_buff); // Display letter
LCD_Cursor (LCD_CURSOR_LEFT); // Move cursor to the left
}
state = KEYPAD_PRESSED_STATE; // Set next keypad state
break;
case KEYPAD_PRESSED_STATE: // Key release
timeout = 1000; // Set timeout
do { // Do until key is released or timeout
key = KeyPad_GetKey(); // Sample keypad
} while ((key <= KEYPAD_ENTER) && (--timeout) && ISO7816_SmartCardReady()); // Release
if (!ISO7816_SmartCardReady()) { // If the smart card is removed
*alpha_buff = '\0'; // Clear display
LCD_Cursor (LCD_CURSOR_OFF); // Hide cursor
return; // Exit
}
state = KEYPAD_PRESSED_TIMEOUT_STATE; // Set next keypad state
break;
case KEYPAD_PRESSED_TIMEOUT_STATE:
if (timeout == 0) { // If key is still pressed
if (key == KEYPAD_ESC) { // And the key pressed is ESC key
*alpha_buff = '\0'; // Clear the LCD display
LCD_String (LCD_LINE2, " ");
LCD_String (LCD_LINE2, alpha_buff);
i = 0;
}
else {
if (i < letters) { // Display numeric value of the key pressed
*(alpha_buff + i) = (char)(key + '0'); // Convert to ASCII
*(alpha_buff + i + 1) = '\0';
LCD_String (LCD_LINE2, alpha_buff); // Display value
i++;
}
}
do { // Wait until key is released
key = KeyPad_GetKey(); // Sample keypad
} while ((key <= KEYPAD_ENTER) && ISO7816_SmartCardReady());
if (!ISO7816_SmartCardReady()) { // If the smart card is removed
*alpha_buff = '\0'; // Clear display
LCD_Cursor (LCD_CURSOR_OFF); // Hide cursor
return; // Exit
}
state = KEYPAD_WAIT_STATE; // Set next keypad state
}
else {
if ((last_key == KEYPAD_ESC) || (i >= letters)) {
state = KEYPAD_WAIT_STATE; // Set next keypad state
}
else {
state = KEYPAD_RELEASE_STATE; // Set next keypad state
}
}
break;
case KEYPAD_RELEASE_STATE:
timeout = 1000; // Set timeout
do { // Wait for a key press or timeout
key = KeyPad_GetKey(); // Sample keypad
} while ((key > KEYPAD_ENTER) && (--timeout) && ISO7816_SmartCardReady());
if (!ISO7816_SmartCardReady()) { // If the smart card is removed
*alpha_buff = '\0'; // Clear display
LCD_Cursor (LCD_CURSOR_OFF); // Hide cursor
return; // Exit
}
state = KEYPAD_RELEASE_TIMEOUT_STATE; // Set next keypad state
break;
case KEYPAD_RELEASE_TIMEOUT_STATE:
if (timeout == 0) { // If no key is pressed
i++; // Increment display index
state = KEYPAD_WAIT_STATE; // Set next keypad state
LCD_Cursor (LCD_CURSOR_RIGHT); // Move cursor to the right
}
else { // If a key pressed within timeout
j++; // Select next character of key
state = KEYPAD_NEXT_CHAR_STATE; // Set next keypad state
}
break;
case KEYPAD_NEXT_CHAR_STATE:
if (key == last_key) { // If key pressed is the same key
*(alpha_buff + i) = pgm_read_byte (&KeyPad[key][j % strlen_P (KeyPad[key])]);//KeyPad[key][j % strlen (KeyPad[key])];
*(alpha_buff + i + 1) = '\0';
LCD_String (LCD_LINE2, alpha_buff); // Display value
LCD_Cursor (LCD_CURSOR_LEFT); // Move cursor to the left
state = KEYPAD_PRESSED_STATE; // Set next keypad state
}
else { // If key different from previous key
i++;
state = KEYPAD_HANDLING_STATE; // Set next keypad state
LCD_Cursor (LCD_CURSOR_RIGHT); // Move cursor to the right
}
break;
}
}
LCD_Cursor (LCD_CURSOR_OFF); // Hide cursor
} |
|