# 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` один в один.