Nov 06, 2024 19:45
При реализации очередного homemade проекта в который раз потребовался клавишный ввод, кнопок на 10-11. Числа оставшихся свободных пинов на BluePill не хватает для организации матрицы 4х3, да и дополнительная слесарка для встраивания "телефонной" клавиатуры в устройство не радует.
Прогрессистские решения типа управления с телефона по WiFi, по мне, излишне тяжелы в реализации (нужно осваивать целую новую для себя область).
К тому же по ТЗ требуется четкость срабатывания и короткое время реакции, поскольку управлять придется механизмами.
И я вспомнил о старой доброй PC-шной клавиатуре с интерфейсом PS/2. Да, такие клавы уже, наверное, не продаются и не выпускаются; но их ещё есть достаточно б/у; а переходники с USB клавиатур до сих пор доступны на Али.
Интерфейс там простейший, особенно если не требуется отправлять клавиатуре команды. По сути, это синхронный USART. Все его любительские реализации, встреченные мною в Интернетах, ссылались на документ AVR313. Ознакомился; и помог он мне чуть больше, чем ничем - указал, как не надо делать) Прерывание по обоим фронтам каждого синхроимпульса (а они идут с частотой 10-15 кГц), да ещё ради какой-то клавы - так себе идея в системе, управляющей несколькими шаговыми двигателями.
В итоге родился, как по мне, оптимальный вариант, простой и не жрущий лишних ресурсов. Который заинтересованным и рекомендую.
Для приема отправляемых клавиатурой кодов используем обычный USART, вход которого подключен к линии данных клавиатуры.
Линию CLK используем только для калибровки скорости этого USART. Для этого подключаем CLK к пину МК, способному генерировать прерывания по cпаду уровня (в STM32 годится любой пин GPIO).
Я сделал калибровку при старте системы, но тут возможны варианты. Клавиатура после подачи питания посылает байт готовности. В байтовой посылке 10 битовых интервалов. Подсчитали число периодов тактовой частоты за это время любым из таймеров (я использовал SysTick), загрузили соответствующее значение в прескалер USART - и вуаля. А дальше просто получаем байты с клавы в прерываниях от USART.
Корректная обработка кодовых последовательностей нажатия и отпускания, которые могут содержать от 1 до 3 байтов - чуть более сложная задача, решаемая организацией этого прерывания в виде стейт-машины, с обязательным использованием тайм-аутов. В любой системе полезен таймер с периодическими прерываниями для отсчета тайм-аутов и т.п. таймингов. Ядро Cortex имеет для этого SysTick, но стандартная частота его прерываний в 1 КГц маловата; я предпочитаю настраивать его на 10 КГц.
Больше всего крови мне выпил неотключаемый авто-повтор кода нажатой клавиши. В моём случае это оказалось вредной фитчей; но в конце концов придумал, как её обходить. Проблема и решение не универсальные, поэтому подробности опущу.
Может, изложение получилось слегка сумбурное, но, надеюсь, эти несколько идей облегчат кому-то решение весьма типовой задачи. А для начинающих такая инфа окажется полезнее, чем описание очередного метода мигать светодиодом)