Скачиваний:
29
Добавлен:
09.05.2014
Размер:
7.59 Кб
Скачать
#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
  • #
    09.05.201451.64 Кб29i2c.lst
  • #
    09.05.20148.07 Кб29i2c.rel
  • #
    09.05.201451.64 Кб29i2c.rst
  • #
    09.05.201440.56 Кб29i2c.sym
  • #
    09.05.201427.28 Кб29keyboard.asm
  • #
    09.05.20147.59 Кб29keyboard.c
  • #
    09.05.201410.18 Кб29keyboard.c~
  • #
    09.05.201463.57 Кб29keyboard.lst
  • #
    09.05.201413.07 Кб29keyboard.rel
  • #
    09.05.201463.57 Кб30keyboard.rst
  • #
    09.05.201442.72 Кб29keyboard.sym