Добавил:
Eatmore
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:отчеты по лабораторным работам / будильник / Alarm5 / SRC / keyboard
.c#include "async.h"
#include "max.h"
#include "lcd.h"
#include "led.h"
#define BUFFER_SIZE 30 // размер буфера 64 байта
#define ERR_OVERFLOW_STOPWATCH "\n\rOVERFLOW STOPWATCH\n\r\0"
int repeatDelay; // переменная для обработки задержки в первом повторе
int repeatSpeed; // переменная для обработки задержки во втором и последующих повторах
int delay; // счетчик задержки
char drebezgWait = 1; // флаг наличия дребезга
char firstRepeat = 1; // флаг первого повтора
char keyPress = 0; // флаг нажатия клавиши (1 - нажата, 0 - не нажата)
char firstPress = 1; // флаг первого нажатия (1 - клавиатура еще не использовалась)
// (0 - было хотя-бы одно нажатие на клавишу)
unsigned char key = 0; // переменная для хранения символа нажатой клавиши
unsigned char previousKey = 0; // предыдуая нажатая клавиша
unsigned char prevRow = 0xF0; // маска для обработки нажатия двух клавиш
unsigned char kbBuffer[BUFFER_SIZE]; // буфер клавиатуры
unsigned char kb_wp = 0; // указатель записи буфера клавиатуры
unsigned char kb_rp = 0; // указатель чтения буфера клавиатуры
int oldValue;
/*
Функция: сканирование клавиатуры
Входные параметры: key - указатель клавиши
Выходные параметры: нет
*/
char keyboardScan(unsigned char* key) {
unsigned char cols[4] = {0x0E, 0x0D, 0x0B, 0x07}; // массив столбцов
unsigned char row; // переменная, в которую читается ряд
int i; // счетчик для цикла for
unsigned char symb[16] = {'1','4','7','*','2','5','8','0','3','6','9','#','A','B','C','D'}; // массив символов
unsigned char symbInd; // индекс в массиве symb[]
symbInd = 0; // обнуляем индекс массива symb[]
*key = 0; // обнуляем указатель на область памяти для хранения нажатой кнопки
for (i = 0; i < 4; i++) {
writeMax(KB, cols[i]); // записываем значение столбца в младшие 4 бита регистра клавиатуры
row = readMax(KB) & 0xF0; // считываем значение ряда из регистра клавиатуры
// symbInd =0;
// какой ряд в столбце нажат?
switch (row) {
case 0xE0: prevRow = row; symbInd = symbInd + 1; break; // нажата клавиша в верхнем ряду
case 0xD0: prevRow = row; symbInd = symbInd + 2; break; // нажата клавиша во втором сверху ряду
case 0xB0: prevRow = row; symbInd = symbInd + 3; break; // нажата клавиша во втором снизу ряду
case 0x70: prevRow = row; symbInd = symbInd + 4; break; // нажата клавиша в нижнем ряду
// если нажаты сразу две клавиши, то default:
// побитово сравниваем текущий ряд с предыдущим нажатым рядом (row & prevRow),
// если они не равны предыдущему нажатому ряду( != prevRow), т.е. нажаты сразу две клавиши,
// то выводим ту, которая была нажата первой
default: if ((firstPress == 0) && ((row & prevRow) != prevRow)) {*key = previousKey; return 1;} break;
};
if (symbInd > 0) {
symbInd = symbInd + i*4 - 1; // вычисляем индекс элемента массива
*key = symb[symbInd]; // key = символ на клавише
return 1;
}
}
return 0;
}
/*
Функция: чтение буфера клавиатуры
Входные параметры: symbol - указатель читаемого символа
Выходные параметры: нет
*/
char readKeyBuffer(unsigned char* symbol) {
EA = 0; // запрещаем прерывания от всех источников
if ((kb_wp - kb_rp) > 0) {
*symbol = kbBuffer[kb_rp % BUFFER_SIZE]; // читаем из буфера клавиатуры
kb_rp++; // перемещаем указатель чтения буфера клавиатуры на 1 позицию
EA = 1; // разрешаем прерывания от всех источников
return 1;
}
else {
*symbol = 0; // ничего не считано
EA = 1; // разрешаем прерывания от всех источников
return 0;
}
}
/*
Функция: запись в буфер клавиатуры
Входные параметры: symbol - указатель на читаемый символ
Выходные параметры: нет
*/
void writeKeyBuffer(unsigned char symbol) {
EA = 0; // запрещаем прерывания от всех источников
if ((((kb_wp / BUFFER_SIZE) - (kb_rp / BUFFER_SIZE)) != 0) &&
((kb_wp % BUFFER_SIZE) == (kb_rp % BUFFER_SIZE))) return;
kbBuffer[kb_wp % BUFFER_SIZE] = symbol; // пишем в буфер клавиатуры
kb_wp++; // перемещаем указатель записи буфера клавиатуры на 1 позицию
EA = 1; // разрешаем прерывания от всех источников
}
/*
Функция: обработчик прерывания от таймера (обработчик нажатия на клавишу)
Входные параметры: нет
Выходные параметры: нет
*/
void cleanStopWatch(void)
{
unsigned char i;
for (i=1;i<6;i++)
{
if (i==3)
{
GOTOXY(i,1);
PRINTCHAR(0x3A );
}
else
{
GOTOXY(i,1);
PRINTCHAR(0x30);
}
}
}
unsigned char stop=0;
int value=0;
void timerHandler() interrupt 1 {
int i;
TH0 = 0xDC; // устанавливаем таймер 0 на отсчет 10 мс
TL0 = 0x32;
keyPress = keyboardScan(&key); // сканируем клавиатуру
// (keyPress = 1 -> клавиша нажата)
// (keyPress = 0 -> клавиша не нажата)
if (key != previousKey) delay = 0; // если клавиша не повторяется, то задержка
// (счетчик задержки) между повторами = 0
if (delay == 0) { // если счетчик задержки = 0, то
if (keyPress) { // если клавиша нажата, то
firstPress = 0; // сбрасываем флаг первого нажатия
previousKey = key; // запоминаем текущую нажатую кнопку
if (drebezgWait) drebezgWait = 0; // если установлен флаг наличия дребезга,
// то сбрасываем его
else { // если флаг дребезга не установлен, то
if (firstRepeat) { // если первый повтор клавиши (напр. АА), то
firstRepeat = 0; // сбрасываем флаг первого повтора
delay = repeatDelay; // счетчик задержки = задержка между 1 и 2 повторами
} // если не первый повтор клавиши (напр. ААА), то
else delay = repeatSpeed; // счетчик задержки = задержка между 2-3,3-4 и т.д. повторами
writeKeyBuffer(key); // записываем клавишу в буфер
}
}
else { // если клавиша не нажата, то
drebezgWait = 1; // устанавливаем флаг дребезга
firstRepeat = 1; // устанавливаем флаг первого повтора
}
}
else delay--; // если счетчик задержки не равен 0, то уменьшаем его (ждем)
}
/*
Функция: инициализация таймеров 0 и 1 и UART
таймер 1 - для UART
таймер 0 - для задержек при выводе символов (дребезг, повторы)
Входные параметры: repDelay - задержка между первыми двумя повторениями символа
repSpeed - задержка между последующими повторениями
Выходные параметры: нет
*/
void initTimer(int repDelay, int repSpeed) {
repeatDelay = repDelay;
repeatSpeed = repSpeed;
//EA = 0; // запрещаем прерывания от всех источников
TH0 = 0xDC; // настройка задержки 10 мс
TL0 = 0x32; //
TCON = 0x50; // запуск таймеров 0 и 1
//SCON = 0x54; // режим 1 (8 бит данных, асинхронный, переменная скорость, 1 стоп-бит, 1 старт-бит)
TMOD = 0x21; // таймер 1 работает в 8-битном режиме с автоперегрузкой
// таймер 0 работает в 16-битном режиме
//PCON &= 0x7F; // 9600 бод (SMOD = 0 -> нет удвоения скорости)
ET0 = 1; // разрешаем прерывания от таймера 0
//EA = 1; // разрешаем прерывания от всех источников
}
void initKeyboard() {
initTimer(100, 20); // устанавливаем таймер на задержки:
// 1 с - между первым и вторым повторами
// 0,2 с - между последующими повторами символов
setVector(0x200B, (void *) timerHandler); // устанавливаем вектор обработчика прерывания
}
Соседние файлы в папке SRC