Есть такая логическая операция XOR - "исключающее ИЛИ". Результат операции лог.0, если аргументы одинаковы и лог.1, если аргументы разные. Применив побитовое XOR к переменным, отражающим предыдущее и текущее состояние матрицы клавиш, можно получить изменение в их состоянии. Ну, а уж проверка нажата или отпущена была клавиша это еще одна операция наложения маски по AND с текущими или предыдущим состоянием матрицы.
Пример.
Допустим имеем матрицу из 4-х клавиш.
Код
unsigned char preMatrix; // переменная состояния матрицы ПРЕДЫДУЩЕГО опроса
unsigned char curMatrix; // переменная состояния матрицы ТЕКУЩЕГО опроса
unsigned char press, release; //переменные результата, содержащие биты соответствующие нажатым и отжатым клавишам в матрице
press=(preMatrix^curMatrix)&curMatrix; //получение состояния клавиш, которые в предыдущем цикле опроса были НЕнажаты, а в текущем нажаты
release=(preMatrix^curMatrix)&preMatrix; //получение состояния клавиш, которые в предыдущем цикле опроса были нажаты, а в текущем отпущены
Естественно, что при этом переменные preMatrix и curMatrix должны содержать состояние матрицы
уже отфильтрованное от дребезга клавиш. Ну и дальше обычный цикл с побитовым сравнением переменных press и/или release для определения какие именно клавиши были нажаты или отпущены с формированием соответствующих скан-кодов.
Код
unsigned int cntr,
unsigned char mask=0x01;
for (cntr=0; cntr<4; cntr++)
{ if ((press&mask)!=0)
{ //здесь функция формирования скан-кода НАЖАТОЙ клавиши
}
if ((release&mask)!=0)
{ //здесь функция формирования скан-кода ОТЖАТОЙ клавиши
}
mask<<=1;
}