Не вдаваясь в разбор вашего исходника, попробую пояснить на "пальцах". Для обслуживания матричной клавиатуры нужно реализовать как минимум три функции. Функция №1. Сканирование матрицы, устранение дребезга, определение нажатых/отпущенных клавиш, формирование соответствующих скан-кодов, помещение скан-кодов в буфер клавиатуры. Функция №2. Выдача текущего скан-кода без извлечения его из буфера. Функция №3. Выдача текущего скан-кода с извлечением его из буфера. Функция №1 обычно вызывается по прерыванию от таймера с равномерным интервалом времени (от 5мс до 100мс). Чаще, чем 200 раз в секунду вызывать ее нет смысла: а) никакая супер-пупер-машинистка не сможет с такой частотой колотить по клавишам; б) дребезг многих кнопок как раз порядка 1мс...10мс. Реже 10 раз в секунду тоже вызывать не желательно, т.к. будет значительная задержка генерации скан-кодов, а пользователю придется довольно долго удерживать клавиши для устойчивого определения нажатия их в программе. Лично я использую период 10...20мс. Буфер нужен в любом случае. Хотя бы даже из одного байта буфер. Потому, что процесс опроса матрицы клавиш и процесс использования полученного скан-кода в общем случае асинхронные. Асинхронные процессы синхронизируются с помощью буферов. Буфер для кодов клавиатуры может быть линейным или циклическим. В первом случае используются две переменных: счетчик количества скан-кодов, находящихся в буфере и указатель на текущий скан-код. Во-втором случае нужны три переменных: тоже счетчик скан-кодов, указатель на позицию скан-кода, предназначенного для извлечения из буфера и указатель на позицию для записи следующего скан-кода. В первом случае необходимо строго следить за атомарностью (одновременностью) обнуления счетчика и указателя при извлечении всех скан-кодов. Потому, что Функции №2, 3 (чтение/извлечение скан-кода из буфера) могут быть прерваны Функцией №1. Попробуйте пока осознать хотя бы это краткое описание. И на его основе реализовать свою программу.
|