Фильтрация нескольких случайных нажатий одной кнопки.
Фильтрация нескольких случайных нажатий одной кнопки.
С какой частотой обычно происходят эти нажатия?
Сферический ламер в вакууме
Ну это же абсолютно бессистемно, на то он и дребезг. Фильтровать (если) надо нажатия чаще герц наверное 10-20 -- за три-четыре прерывания.
у ужасма все инициализировано. тем он и хорош
обычно сразу после срабатывания в течение единиц-десятков мс могут быть многократные замыкания-размыкания. для хороших клавиатур достаточно опрашивать раз в прерывание (не чаще!), для плохих - и того реже. у меня была одна такая клава - многие проги с ней глючили, нажимаешь 1 раз, срабатывает 10 раз, ввести ничего невозможно. но это исключение.
да и не везде нужен антидребезг, так-то.
Я чаще раза в прерывание и не буду, вы что.
Я думаю либо раз в прерывание опрашивать, а обрабатывать раз в кадр все 4--5 дампов,
или вообще опрашивать раз в кадр.
---------- Post added at 22:08 ---------- Previous post was at 21:53 ----------
Я решил перед написанием ZXeretic-а сделать другую игру, попроще, не 3D.
И обкатать часть процедур на ней.
---------- Post added 29.09.2013 at 00:00 ---------- Previous post was 28.09.2013 at 22:08 ----------
А как в аласме записать код на диск?
Сферический ламер в вакууме
Смотри, вот кусок кода, которым я опрашиваю клаву на контроллере.
Его можно свободно портировать под нужды спектрума.
Вот здесь:Код:#define KDAT_PORT PORTC #define KDAT_DIR DDRC #define KDAT_PIN PINC #define KROW_PORT PORTB #define KROW_DIR DDRB #define KROW_PIN PINB #define DEBOUNCE_MASK 7 // Keyboard de-bouncing, as larger is bitmask as stronger is de-bouncing, but longer key response (1 to 7 LSBs) #define KDB_DELAY 4 // Delay in microseconds so voltage from address line could propagate #define MAX_KEYS 37 volatile U8 key[MAX_KEYS]; void poll_kbd(void) { U8 i, j, k, key_pin; U8 row = 1; U8 key_num = 0; for (i = 0; i < 8; i++) { KROW_PORT = row; // assert address line */ delay_us(KDB_DELAY); key_pin = KDAT_PIN; // poll keyboard data */ KROW_PORT = 0; // deassert address line to reduce current */ row <<= 1; for (j = 0; j < 8; j++) { k = key[key_num]; k = (k & 0x80) | ((k << 1) & 0x7E) | (key_pin & 1); key_pin >>= 1; if (!(k & DEBOUNCE_MASK) && (k & 0x80)) { /* key was pressed */ send_note_on(key_num); k &= 0x7F; } else if (!(~k & DEBOUNCE_MASK) && !(k & 0x80)) { /* key was released */ send_note_off(key_num); k |= 0x80; } key[key_num++] = k; if (key_num == MAX_KEYS) break; } if (key_num == MAX_KEYS) break; } }
k = (k & 0x80) | ((k << 1) & 0x7E) | (key_pin & 1);
происходит вдвиг бита статуса клавиши в переменную, после чего по маске определяется - считать ли клавишу нажатой или отжатой (все N бит по маске должны быть либо 0, либо 1), при этом старший бит определяет разовость этого события.
Выбирая маску, можно добиться нужной дребезгоустойчивости.
Блин, тут даже меня сподобило задуматься...
На самом деле, антидребезг жизненно необходим, если:
- с клавиатуры редактируется текст;
- для переназначения кнопок в частности;
- если в программе критично каждое отдельное нажатие на кнопку, а не общее время нажатия.
Антидребезг совсем не нужен если прога ориенитирована на эмулятор или на PC-клавиатуру.
Одним из лучших антидребезговых механизмов на Спекртуме признан метод опроса кнопок в ПЗУ. Если убрать из него всякую гибкость, то суть примерно такова: если порт полуряда в течение 5 прерываний подряд возвращает одну и ту же комбинацию нажатых клавиш, это означает, что нажатие действительно произошло и колебательные процессы на контактах кончились.
А смотря что тебе надо. Смотри help'ы по таким командам:
SAVEBIN - сохраняет код в файл в файловую систему PC;
SAVESNA - сохраняет код в снапшот с инициализированными системными переменными;
SAVEHOB - сохраняет код в HOBETA-файл;
SAVETRD - добавляет код как ZX-файл к существующему TRD-файлу;
Ну покажи, где там проверяется 5 прерываний. Не важно чего.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)