Так опрос клавиатуры, когда процессору ну совсем нет времени на основной цикл main, всё время то в IRQ, то в FIQ. Говорю про ARM7. В моём случае на main уходит менее 1% времени. Код (C++): //========== параметры интерфейса клавиатуры ===================================== unsigned char Key_Old; //прошлый код клавиши char key; uint8_t keyloop; uint8_t kMatrix[4]; void GetKey(void) { switch(keyloop) { //------ out _KEY2_2 ----- //K_KEY1 case 0: PORT_KEYBOARD_S_OUT = _KEY2_2 << 16; //установка высокого уровня keyloop++; break; case 1: if(PORT_KEYBOARD_IN & _KEY1_1) kMatrix[0] |= 0x0F; else kMatrix[0] &= (~(0x0F)); if(PORT_KEYBOARD_IN & _KEY1_2) kMatrix[1] |= 0x0F; else kMatrix[1] &= (~(0x0F)); PORT_KEYBOARD_C_OUT = _KEY2_2 << 16; //установка низкого уровня keyloop++; break; case 2: if(!(PORT_KEYBOARD_IN & _KEY1_1)) kMatrix[0] |= 0xF0; else kMatrix[0] &= (~(0xF0)); if(!(PORT_KEYBOARD_IN & _KEY1_2)) kMatrix[1] |= 0xF0; else kMatrix[1] &= (~(0xF0)); PORT_KEYBOARD_S_OUT = _KEY2_3 << 16; //установка высокого уровня keyloop++; break; case 3: if(PORT_KEYBOARD_IN & _KEY1_1) kMatrix[2] |= 0x0F; else kMatrix[2] &= (~(0x0F)); if(PORT_KEYBOARD_IN & _KEY1_2) kMatrix[3] |= 0x0F; else kMatrix[3] &= (~(0x0F)); PORT_KEYBOARD_C_OUT = _KEY2_3 << 16; //установка низкого уровня keyloop++; break; case 4: if(!(PORT_KEYBOARD_IN & _KEY1_1)) kMatrix[2] |= 0xF0; else kMatrix[2] &= (~(0xF0)); if(!(PORT_KEYBOARD_IN & _KEY1_2)) kMatrix[3] |= 0xF0; else kMatrix[3] &= (~(0xF0)); keyloop++; break; case 5: if(kMatrix[0] == 0xFF) { key = K_KEY1; TCK_L = 0; //Обнуление таймера подсветки } else if(kMatrix[1] == 0xFF) { key = K_KEY2; TCK_L = 0; //Обнуление таймера подсветки } else if(kMatrix[2] == 0xFF) { key = K_KEY3; TCK_L = 0; //Обнуление таймера подсветки } else if(kMatrix[3] == 0xFF) { key = K_KEY4; TCK_L = 0; //Обнуление таймера подсветки } else key = NO_KEY; keyloop = 0; break; default: PORT_KEYBOARD_C_OUT = _KEY2_2 << 16; //установка низкого уровня PORT_KEYBOARD_C_OUT = _KEY2_3 << 16; //установка низкого уровня keyloop = 0; break; } } // // Опрос клавиатуры char Inkey(void) { if((key != NO_KEY) && (key != Key_Old)) { Key_Old = key; return key; } else { Key_Old = key; return NO_KEY; } } Потому как реализация выходного сигнала (синтезатор на ШИМ по огибающей) на FIQ, измерения и коррекция сигнала, обслуживание периферии, пересчёт выжных параметров на IRQ. на main и времени уже нет. Так что в main только Inkey, а работа с клавой как периферия GetKey. И тормоз с вводом пропал. Кстати сканирование клавы 2х2 идёт как по высокому, так и по низкому уровню, то есть если случайные наводки и т.п. В смысле опрос: 1 подаём низкий, при нажатии должен прочитан быть низкий 2 подаём высокий при нажатии должен прочитан быть высокий 3 при выполнении п 1 и 2 клавиша считается нажатой
А что бы не тратить память, можно обойтись и одним байтом - как метод флагов. вот это: Код (C++): kMatrix[2] |= 0x0F; поменять на это: Код (C++): kMatrixByte |= 0x01; //для одного опроса (по высокому) kMatrixByte |= 0x02; //тогда для низкого //остальное аналогично //ну и проверка if((kMatrixByte & 0x03) == 0x03) //клавиша нажата Ну если занимать не матрицу как ранее, а один байт, то анализировать надо конкретно биты. Как раз выходит, что на переменную в 1байт определяются состояния 4-х кнопок в помехоустойчивом варианте. Процедуру GetKey повесить надо на прерывание по любому таймеру. Тогда в цикле main ну или loop просто читать код клавиши. Клавиша будет прочитана и дребезга с параметром OldKey для функции Inkey не будет - испытано.