ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Вторник
23 апреля
95181 Топик полностью
rezident (25.07.2007 14:47, просмотров: 1) ответил Dany на Не вижу принципиальной разницы...
Принципиальная разница в том, что сканирование происходит за известное конечное время, которое гораздо меньше периода сканирования. Если ждать отпускания кнопки, то можно попасть на вложенные прерывания и/или вообще не дождаться отпускания кнопки. Вот пример программы. Функция drvKbdInit вызывается однократно при инициализации устройств. Функция drvKbdPutKey вызывается из перывания с периодом 10-50мс. Имеет функцию автоповтора кодов клавиш перемещения (стрелки). При одновременном нажатии нескольких клавиш формируется только один код клавиши, но можно изменить чтобы формировались несколько. <c> //==============================================// // обработка матричной клавиатуры до 16 кнопок // // содержит функции: // // -инициализации // // -сканирования // //==============================================// // Автор - rezident (rezident@rbcmail.ru) // // сopyright (c) февраль, 2005 год // //==============================================// #include "..\_INC\drvKBDdef.h" #include "..\..\_xCOMMON\_LIB\KBD\xKBD_Buf.c" //==============================================// // Функция инициализации клавиатуры //----------------------------------------------- //аргументы: указатель на структуру переменных // клавиатуры, // указатель на стуктуру констант // клавиатуры, // указатель на буфер драйвера клавиатуры //возвращает:ошибку, если нет клавиатуры //=============================================== xByte drvKbdInit(xVT_KBD_Data *pd, st_drvKBD_Loc *pc, xByte *pKbBuf) { st_drvKBD_Data *drv=(st_drvKBD_Data *)&pd->drvData; if (drvKbdHardInit()!=0) //нет железа или клав-ры? { return(1); //возвращ. ошибку (нет клав-ы) } drv->matrix=0; //сбросим состояние матрицы drv->status=0; //сбросим устойчивое состояние drv->autoKey=KB_NULL; //предуст.код автоповтора drv->autoDly=pc->dly; //предустановим счетчик за- //держки автоповтора drv->autoRpt=0; //сбросим счетчик паузы //автоповтора drv->cData=(st_drvKBD_Loc *)pc; //указатель на сегмент констант pd->flags=drvKBTYPE; //здесь установим тип клав-ры pd->NumKey=0; //сбросим число кодов в буфере pd->IdKey=0; //сбросим индекс записи кода в буфере pd->RdIdxKey=0; //обнулим индекс чтения кода в буфере pd->LastKey=KB_NULL; //код последней извлеч.клавиши pd->pBuf=pKbBuf; //указатель на буфер клав-ры pd->SzBuf=drvKB_MAXBUFSIZE; //уст. размер буфера клавитуры if (pc->time==0) pd->flags|=VT_FKBD_M_H_LOCKAUTO; //блокируем автоповтор return(0); } //================================================ // Функция сканирования виртуальной клавиатуры //------------------------------------------------ //аргументы: указатель на структуру клавиатуры //возвращает:нет //================================================ void drvKbdPutKey(xVT_KBD_Data *dbuf) { st_drvKBD_Data *pd=(st_drvKBD_Data *)&dbuf->drvData; st_drvKBD_Loc *pc=(st_drvKBD_Loc *)pd->cData; xWord tmp1=0, tmp2=0; xByte key; tmp1=drvKbdHardScan(); //сканирование клав-ры if ((pd->matrix^tmp1)==0) //предыд. и текущ. состояния //матрицы совпадают? { //да, состояние ее устойчивое tmp2=pd->status^tmp1; //проверим изменения if (tmp2!=0) //есть изменения? { //да,требуется обработка pd->autoKey=KB_NULL; //предустановим кодом //ненажатой клавиши xWord mask=1; //маска для идентификации for (xWord i=0; i<drvKB_MAXKEYNUM; i++) //цикл для идентиф. нажатия { if ((tmp2&mask)!=0) //сост. этой клав. изменилось? { if ((tmp1&mask)!=0) //да, а она нажата? { //да, надо писать код в буфер if ((dbuf->flags&VT_FKBD_M_H_LOCK)==0) //клавиатура не заблокирована? { key=pc->Tab[i]; //код клавиши из таблицы if ((key!=KB_NULL)&&(dbuf->NumKey<dbuf->SzBuf))//код верный и { //место в буфере имеется? dbuf->pBuf[dbuf->IdKey]=key; if (dbuf->IdKey<(dbuf->SzBuf-1)) dbuf->IdKey++; else dbuf->IdKey=0; dbuf->NumKey++; pd->autoKey=key; //запомним как последний код pd->autoRpt=0; //сбросим счетчик паузы //автоповтора pd->autoDly=pc->dly; //предустановим счетчик //задержки автоповтора if ((pd->ctrl&drvKBD_SIGNALBLOCK)==0)//блокировка сигнала есть? { pd->ctrl|=drvKBD_SIGNALON; //нету, поморгаем или побибикаем } } i=dbuf->SzBuf; //закончим цикл } } //нет, кнопка была отжата } mask<<=1; //модифицируем маску бита } } else //нет, устойчивое сост. не //изменилось, но клавиша-то //нажата! if (((dbuf->flags&VT_FKBD_M_H_LOCKAUTO)==0)&& //автоповтор разрешен? (tmp1!=0) //клавиша нажата ) { key=pd->autoKey; if ((key==KB_UP) || (key==KB_DOWN)|| (key==KB_LEFT)|| (key==KB_RIGHT) ) //код клавиши со стрелками? { //нет, будем повторять его if (pd->autoDly>0) //задержка автоповтора уже //закончилась? { pd->autoDly-=1; //еще нет, уменьшим счетчик } else //да, задержка закончилась if (pd->autoRpt>0) //пауза между автоповторами //закончилась? { //нет, не окончилась pd->autoRpt-=1; //уменьшим счетчик } else //да, пауза закончилась { if ((dbuf->flags&VT_FKBD_M_H_LOCK)==0) //клавиатура не заблокирована? { if ((key!=KB_NULL)&&(dbuf->NumKey<dbuf->SzBuf))//код верный и { //место в буфере имеется? dbuf->pBuf[dbuf->IdKey]=key; if (dbuf->IdKey<(dbuf->SzBuf-1)) dbuf->IdKey++; else dbuf->IdKey=0; dbuf->NumKey++; } if ((pd->ctrl&drvKBD_SIGNALBLOCK)==0) //блокировка сигнала есть? { pd->ctrl|=drvKBD_SIGNALON; //нету, поморгаем или побикаем } } pd->autoRpt=pc->time; //установим счетчик паузы } //автоповтора } } pd->status=tmp1; //обновим устойчивое состояние } //матрицы клавиатуры pd->matrix=tmp1; //запомним текущ. состояние } //матрицы </c>