feat(keypad): опрос шести кнопок с антидребезгом и автоповтором

Перенесён из KONOR_ds18b20/lib/keypad; в OpticalTester лежала такая же копия.

О портах и таймерах библиотека не знает: уровни приходят обратным вызовом
read(), время — параметром Keypad_Poll(). События складываются в очередь
на восемь штук, поэтому быстрое нажатие не теряется, пока приложение
перерисовывает экран.
This commit is contained in:
2026-08-23 01:15:11 +03:00
parent c7798c02db
commit 54f0ba7b0e
3 changed files with 377 additions and 0 deletions

59
c/keypad/README.md Normal file
View File

@@ -0,0 +1,59 @@
# keypad
Опрос шести кнопок навигации с антидребезгом, автоповтором и удержанием.
Библиотека не знает ни о портах, ни о таймерах: уровни кнопок приходят через
обратный вызов порта, время — параметром `Keypad_Poll()`. События складываются
в короткую очередь, поэтому быстрое нажатие не теряется, пока приложение
перерисовывает экран.
```
порт платы keypad.c приложение
read(key) ──────► антидребезг, автоповтор ──► Keypad_GetEvent()
удержание, очередь на 8
```
## Состав
| Файл | Что делает | Зависимости |
|---|---|---|
| `keypad.h`, `keypad.c` | шесть кнопок, антидребезг, автоповтор, длинное нажатие, очередь событий | `stdint.h` |
Кнопок ровно шесть: четыре направления, ввод и возврат — набор покрывает
навигацию по меню без матрицы и сдвиговых регистров.
## Что нужно от платформы
Один вызов и монотонное время в миллисекундах:
```c
uint8_t read(void *ctx, uint8_t key); /* 1 — кнопка нажата */
```
## Быстрый старт
```c
Keypad keypad;
Keypad_Config config = { .read = board_key_read, .context = &board };
/* нулевые поля заменяются умолчаниями: дребезг 20 мс, автоповтор 400/120 мс,
удержание 800 мс, автоповтор только для стрелок */
Keypad_Init(&keypad, &config);
for (;;) {
Keypad_Poll(&keypad, board_millis());
Keypad_Event event;
while (Keypad_GetEvent(&keypad, &event)) {
if (event.type == KEYPAD_EVENT_PRESS) { /* ... */ }
}
}
```
Опрашивать `Keypad_Poll()` достаточно раз в 1..5 мс — из основного цикла
или из системного тика.
## Проверено в проектах
`KONOR_ds18b20`, `OpticalTester`. Естественная пара — [`menu`](../menu):
`Keypad_Key` отображается в `Menu_Key` один в один.