//*************************************************************************** // // Author(s)...: Pashgan http://ChipEnable.Ru // // Target(s)...: ATMega8 // // Compiler....: IAR 5.11A // // Description.: Опрос матричной клавиатуры. Использование конечного автомата. // // Data........: 06.03.10 // //*************************************************************************** #include "keyboard.h" //хранит текущее состояние автомата unsigned char keyState; //хранит код нажатой кнопки unsigned char keyCode; //хранит символьное значение нажатой кнопки unsigned char keyValue; //флаговая переменная - устанавливается, если кнопка удерживается unsigned char keyDown; //флаговая переменная - устанавливается, когда нажата новая кнопка unsigned char keyNew; //таблица перекодировки __flash unsigned char keyTable[][2] = { { 0x11, '1'}, { 0x12, '2'}, { 0x14, '3'}, { 0x21, '4'}, { 0x22, '5'}, { 0x24, '6'}, { 0x41, '7'}, { 0x42, '8'}, { 0x44, '9'}, { 0x81, '*'}, { 0x82, '0'}, { 0x84, '#'} }; //прототипы функций используемых автоматом unsigned char AnyKey(void); unsigned char SameKey(void); void ScanKey(void); unsigned char FindKey(void); void ClearKey(void); //инициализация портов, обнуление переменных void InitKeyboard(void) { DDRD |= 0xf0; PORTD &= 0x0f; DDRC &= ~0x07; PORTC &= ~0x07; keyState = 0; keyCode = 0; keyValue = 0; keyDown = 0; keyNew = 0; } //автомат реализующий опрос клавиатуры, защиту от дребезга // и распознование нажатой кнопки void ScanKeyboard(void) { switch (keyState){ case 0: if (AnyKey()) { ScanKey(); keyState = 1; } break; case 1: if (SameKey()) { FindKey(); keyState = 2; } else keyState = 0; break; case 2: if (SameKey()){} else keyState = 3; break; case 3: if (SameKey()) { keyState = 2; } else { ClearKey(); keyState = 0; } break; default: break; } } //возвращает true если какая-нибудь кнопка нажата unsigned char AnyKey(void) { PORTD |= 0xf0; return (PINC & 0x07); } // возвращает true если удерживается та же кнопка //что и в предыдущем цикле опроса unsigned char SameKey(void) { PORTD = (PORTD & 0x0f) | ( keyCode & 0xf0); return ((PINC & keyCode) & 0x07); } //Генерирует нужные сигналы на линиях //считывает код нажатой кнопки void ScanKey(void) { unsigned char activeRow = (1<<4); while (activeRow) { PORTD = (PORTD & 0x0f)|activeRow; if (PINC & 0x07) { keyCode = (PINC & 0x07); keyCode |= (PORTD & 0xf0); } activeRow <<= 1; } } // преобразует код кнопки в соответствующий символ // устанавивает флаги unsigned char FindKey(void) { unsigned char index; for (index = 0; index < 12; index++) { if (keyTable [index][0] == keyCode) { keyValue = keyTable [index][1]; keyDown = 1; keyNew = 1; return 1; } } return 0; } //сбрасывает флаг void ClearKey(void) { keyDown = 0; } //если зафиксировано нажатие кнопки //возвращает ее код unsigned char GetKey(void) { if (keyNew){ keyNew = 0; return keyValue; } else return 0; }