Это реализуется в функции опроса и устранения дребезга, которая вызывается с определенным периодом (у меня обычно этот период в диапазоне 10мс-100мс). Алгоритм примерно такой
1. заполняем матрицу кнопок, опросам и проверяем нажата ли хоть одна клавиша? если нет, то выход
2. состояние (матрицы) кнопок по сравнению с предыдущим не изменилось? если изменилось, то запоминаем его и выход
3. раз состояние совпадает, то значит дребезг окончился, формируем код нажатой клавиши и проверяем совпадает ли он с предыдущим? если нет, то записываем его в буфер клавиатуры и на выход
4. раз код совпадает, то значит нужно формировать повтор. Проверяем флаг, окончания паузы перед началом повтором. Если флаг не установлен, то проверяем окончилась ли пауза
задержки начала формирования кода повтора, если не окончилась, то на выход, если же окончилась, то устанавливаем флаг повтора и записываем тот же код клавиши в буфер клавиатуры и фиксируем время формирования кода.
5. раз флаг уже установлен, то смотрим закончилось ли время
паузы между повторами. Если нет, то на выход
6. раз пауза между повторами закончилась, то записываем код клавиши в буфер, фиксируем отметку времени и на выход.
Вот здесь на 6 этапе, можно дополнительно фиксировать общее время, прошедшее с начала формирования кодов повтора и по истечении заданного периода изменять (уменьшать) паузы между повторами. Естественно, что фиксировать время начала повтора для этой функции (ускорения выдачи кодов повтора) нужно на этапе 4.
Т.е. структура клавиатуры примерно такая
Код
typedef struct kbd_t
{ unsigned int matrix; //состояние матрицы кнопок, формируется при каждом вызове функции
unsigned int state; //устойчивое состояние матрицы кнопок, после устранения дребезга
unsigned int bfrPause; //отметка времени (мс), для формирования задрежку перед началом повтора
unsigned int btwnPause; //отметка времени (мс), паузы между повторами
unsigned int wIdx; //индекс для записи скан-кодов в буфер клавиатуры
unsigned int rIdx; //индекс для извлечения скан-кодов из буфера клавиатуры
unsigned int cntr; //счетчик скан-кодов, находящихся в буфере клавиатуры
unsigned char key_code; //код последней нажатой клавиши, NULL если клавиша не нажата
unsigned char flg; //флаг или битовые флаги управления алгоритмом
unsigned char buf[MAXNUMKEY]; //буфер клавиатуры
} kbd_t;
Соответственно, изменяя в процессе вызова функции опроса и устранения дребезга, значения переменной btwnPause, вы сможете управлять скоростью выдачи повторных скан-кодов.
Два индекса потому, что я предполагаю использование циклического буфера. Если хочется, то вы можете использовать линейный буфер и избавится от одного индекса, используя вместо него счетчик скан-кодов. Только тогда нужно обеспечить атомарность одновременного сброса индекса и счетчика при полном опустошении буфера.