John23 0 22 февраля, 2008 Опубликовано 22 февраля, 2008 · Жалоба Здравствуйте уважаемые знатоки. Зарание извиняюсь за банальный вопрос, но он возник и никак не могу с ним справится. У меня всё та же ATmega128, к ней подключена матричная клавиатура на 4 строки и 6 столбцов. На стороках PORTE4-7, на столбцах PORTB0-5. Проблема в том что прерывания при нажании на клавиши возникают и выводится текст на экранчик, авот как определить столбец не понятно. так как никакие значния в прте В не изменяются. Клавиатура расчитана на одиночные нажатия. Подскажите пожалуйста как быть. Я уже кажеться все варианты перепробывал. Самое здравое что пришло- это в обработчике прерывания поменять направления столбцов и строк и увидеть уже какой столбец задействован, но ничего не вышло. Вот код, посмотрите пожалуйста. Закоментирована последняя неудачная попытка. void InitKB(void) { DDRE =0x0F; PORTE=0xF0; DDRB =0x3F; //0b00111111; PORTB =0xC0 // 0b11000000; cli(); EICRB=0; EIMSK=0xF0; } SIGNAL(SIG_INTERRUPT4) { Btn=PINB; int j =1; LCDputs("Џђ…ђ›‚ЂЌ?…=4",12,0); _delay_ms(5000); LCDsendCommand(0x01); /* if(flag==1) { //BtnFlag=EIFR; DDRB=0xC0; PORTB=0x3F; DDRE =0xF0; //BtnFlag;//0xF0; PORTE =0x0F;//0x0F; // Btn=PINB; // BtnFlag=PORTB; flag=0; } else { Btn=PINB; BtnFlag=PORTB; DDRE =0x0F; PORTE =0xF0; DDRB =0x3F; //0b00111111; PORTB =0xC0; // 0b11000000 flag=1; } */ } SIGNAL(SIG_INTERRUPT5) { Btn=PINB; int j =1; LCDputs("Џђ…ђ›‚ЂЌ?…=5",12,0); _delay_ms(5000); LCDsendCommand(0b00000001); } SIGNAL(SIG_INTERRUPT6) { Btn=PINB; int j =1; LCDputs("Џђ…ђ›‚ЂЌ?…=6",12,0); _delay_ms(5000); LCDsendCommand(0b00000001); } SIGNAL(SIG_INTERRUPT7) { Btn=PINB; int j =1; // DDRB = 0x3F; //PORTB =0xC0; LCDputs("Џђ…ђ›‚ЂЌ?…=7",12,0); _delay_ms(5000); LCDsendCommand(0b00000001); } int main(void) { LCDinit(); InitKB(); sei(); for(;;) { sec=0; Btn=0; } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aai_m 0 22 февраля, 2008 Опубликовано 22 февраля, 2008 · Жалоба Использую мембранную клавиатуру(6х3) SK 16 фирмы "Testa Standart" http://www.agalsea.com/ms/testa_st.html. По трем столбцам организован "бегущий 0", читаем соответственно 6 строк одновременно. Используется клавиша "SHIFT" , есть борьба с дребезгом. Функция GetChar() взята из рабочего проета. Смотрите Джон23. GetChar.txt Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladimirYU 0 22 февраля, 2008 Опубликовано 22 февраля, 2008 · Жалоба DDRE =0x0F; PORTE=0xF0; DDRB =0x3F; //0b00111111; PORTB =0xC0 // 0b11000000; //???????? cli(); EICRB=0; EIMSK=0xF0; 1. Как Вам уже ответил aai_m лучше использовать бегущий ноль, тогда при инициализации выделенная строка должна быть PORTB =0xff // 0b11000000; 2. Не связывайтесь с внешними прерываниями, в данном случае это ни к чему, я предполагаю что прерывания у Вас возникают по отпусканию кнопки и конечно Вы не можете определить столбец, т. к. все вернулось в исходное состояние. Лучше с определенной периодичностью сдвигаете 0 в PORTB и читайте PINE и спокойно определите нажатую клавишу (см. 1.). 3. Алгоритмы подавления дребезга обсуждались неоднократно, поищите. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vitko 0 22 февраля, 2008 Опубликовано 22 февраля, 2008 (изменено) · Жалоба Как делать на внешнем прерывании (одном) хорошо написано в аппноте AVR240 - примерно так как делаете вы. Плюс побороть дребезг. Изменено 22 февраля, 2008 пользователем vitko Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться