Пленочная клавиатура 3*4


Вот такая простенькая клавиатура – вроде бы вещь стандартная, но мне захотелось сделать подключение ее к МК без диодов (защита от одновременного нажатия двух кнопок). Получилось, правда, одновременное нажатие программой не распознается.  Зато подключается очень просто.

Вот сама подпрограмма.

////////////////////////////////////////////////////////////////////////////////
//
// Опрос клавиатуры, матрица 3*4. Требование – 4 линии “выодных” должны быть
// на одном порту, биты могут быть понему “рассыпаны”.И три линии входных
// тоже на одном порту (могут, конечно, и все 7 на одном быть)
// Порты и пины описываются так:
//
//#define IPIN PINB
//#define IPORT PORTB
//#define OPORT PORTA
//#define ODDR DDRA
//#define OPIN PINA

// OUT1 = pin7
//#define OUT1 7
//#define OUT2 5
//#define OUT3 3
//#define OUT4 1
// INP1 = pin3 и далее
//#define INP1 0
//#define INP2 2
//#define INP3 4
//
//
// коды кнопок #=12,*=11,0=10
//
////////////////////////////////////////////////////////////////////////////////

signed char getkey()
{
signed char rez = 0;
//————
// на всякий влючить подпорку входов
IPORT |= ((1<<INP1)|(1<<INP2)|(1<<INP3));
//—— 1 ——
// включить 0 на выход 1 (на остальные подать 1)
ODDR &= ~((1<<OUT2)|(1<<OUT3)|(1<<OUT4));
OPORT |= ((1<<OUT2)|(1<<OUT3)|(1<<OUT4));
OPORT &= ~(1<<OUT1);
ODDR |= (1<<OUT1);
// Читаем входы выходов(ну скзанул…)
__delay_cycles(15);
char T = ~(OPIN);// 1-нажатые
if (T & ((1<<OUT2)|(1<<OUT3)|(1<<OUT4))) { rez = -1; goto exit; } //двойное, неопределенность
// Читаем вход
T = ~(IPIN);// 1-нажатые
if (T & (1<<INP1)) { rez = 1; goto exit; }
if (T & (1<<INP2)) { rez = 2; goto exit; }
if (T & (1<<INP3)) { rez = 3; goto exit; }

//—— 2 ——
// включить 0 на выход 2 (на остальные подать 1)
ODDR &= ~((1<<OUT1)|(1<<OUT3)|(1<<OUT4));
OPORT |= ((1<<OUT1)|(1<<OUT3)|(1<<OUT4));
OPORT &= ~(1<<OUT2);
ODDR |= (1<<OUT2);
__delay_cycles(15);
// Читаем входы выходов(ну скзанул…)
T = ~(OPIN);// 1-нажатые
if (T & ((1<<OUT1)|(1<<OUT3)|(1<<OUT4))) { rez = -1; goto exit; } //двойное, неопределенность
// Читаем вход
T = ~(IPIN);// 1-нажатые
if (T & (1<<INP1)) { rez = 4; goto exit; }
if (T & (1<<INP2)) { rez = 5; goto exit; }
if (T & (1<<INP3)) { rez = 6; goto exit; }

//—— 3 ——
// включить 0 на выход 3 (на остальные подать 1)
ODDR &= ~((1<<OUT1)|(1<<OUT2)|(1<<OUT4));
OPORT |= ((1<<OUT1)|(1<<OUT2)|(1<<OUT4));
OPORT &= ~(1<<OUT3);
ODDR |= (1<<OUT3);
// Читаем входы выходов(ну скзанул…)
__delay_cycles(15);
T = ~(OPIN);// 1-нажатые
if (T & ((1<<OUT1)|(1<<OUT2)|(1<<OUT4))) { rez = -1; goto exit; }//двойное, неопределенность
// Читаем вход
T = ~(IPIN);// 1-нажатые
if (T & (1<<INP1)) { rez = 7; goto exit; }
if (T & (1<<INP2)) { rez = 8; goto exit; }
if (T & (1<<INP3)) { rez = 9; goto exit; }

//—— 4 ——
// включить 0 на выход 4 (на остальные подать 1)
ODDR &= ~((1<<OUT1)|(1<<OUT2)|(1<<OUT3));
OPORT |= ((1<<OUT1)|(1<<OUT2)|(1<<OUT3));
OPORT &= ~(1<<OUT4);
ODDR |= (1<<OUT4);
// Читаем входы выходов(ну скзанул…)
__delay_cycles(15);
T = ~(OPIN);// 1-нажатые
if (T & ((1<<OUT1)|(1<<OUT2)|(1<<OUT3))) { rez = -1; goto exit; }//двойное, неопределенность
// Читаем вход
T = ~(IPIN);// 1-нажатые
if (T & (1<<INP1)) { rez = 11; goto exit; }
if (T & (1<<INP2)) { rez = 10; goto exit; }
if (T & (1<<INP3)) { rez = 12; goto exit; }
//——-Все!—–
exit:

ODDR &= ~(1<<OUT1)|(1<<OUT2)|(1<<OUT3)|(1<<OUT4);
OPORT|= (1<<OUT1)|(1<<OUT2)|(1<<OUT3)|(1<<OUT4); // в нейтральное
// ————–
return(rez);
}////////////////////////////////////////////////////////////////////////////////

Нажатая кнопка Возвращаемый код
1 – 9 1 – 9
0 10
# 11
* 12
Нет нажатых 0
Нажаты несколько -1