Фото нашей клавиатуры (AK-1604-N-BBW (черн)):
Наша клавиатура представляет из себя 16 кнопок подключенных следующем образом:
Краткое описание опроса клавиатуры 4х4. 1)Устанавливаем ножки (PB0-PB3) в состояние 5V+подтягивающий резистор(встроенный в МК) 2)Устанавливаем ножки (PB4-PB7) в состояние 0V 3)Опрашиваем состояние ножек порта В при помощи регистра PINB. Если какая либо кнопка нажата, то одна из ножек нашего МК (PB0-PB4), будет притянута к земле (лог 0). В зависимости какая из ножек притянута к земле мы можем судить на какой из строк нажата кнопка. Запоминаем значение строки. 4)Теперь меняем установленные состояния ножек порта В на противоположные. Другими словами: а)Устанавливаем ножки (PB0-PB3) в состояние 0V б)Устанавливаем ножки (PB4-PB7) в состояние 5V+подтягивающий резистор(встроенный в МК) 5)Делаем анологичную процедуру из пункта (3). Таким образом определяем в каком из столбов нажата кнопка. Запоминаем значение столбца.
Вывод: Из пунктов (3) и (5) мы получили координаты нажатой кнопки (строка и столбец).
Наш код:
#define F_CPU 1000000UL #include <avr/io.h> #include <avr/interrupt.h>
#define STROKA 0 #define STOLB 1
void timer_init (void) { TCCR1B |= (1<<WGM12); // устанавливаем режим СТС (сброс по совпадению) TIMSK |= (1<<OCIE1A);// устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L) OCR1AH = 0b00000011;// определяем число сравнения. Определяем как часто делать прерывания OCR1AL = 0b11111111; TCCR1B |=(1<<CS11);//запуск таймера }
char T=0; //флаг опроса клавиатуры
ISR (TIMER1_COMPA_vect) //прерывание меняет флажок для опроса { T=1; }
char opros_str_stolb(char N) { if(N==STROKA) { DDRB=0xF0; // первые 4 бита для подачи 0и5 PORTB=0x0F; // последнии 4 бита для опроса if(PINB!=0x0F)//проверяем нажата ли кнопка return (~PINB)&0x0F; }else { DDRB=0x0F; // первые 4 бита для подачи 0и5 PORTB=0xF0; // последнии 4 бита для опроса if(PINB!=0xF0)//проверяем нажата ли кнопка return (~PINB)&0xF0; }return 0; }
char opros_4x4() //функция опроса строки и столбца { char T; //переменная которая будет хранить результат T=opros_str_stolb(STROKA);//опрос строки T<<4;//сдвиг результата в лево(в старшие биты) T|=opros_str_stolb(STOLB);//опрос столбца return T;//вернуть координаты нажатой кнопки }
int main(void) { timer_init();//инициализация таймера/счетчика DDRD=0xFF; // младшие биты 5в с подт PORTD=0×00; // старшие биты 0в sei(); // глобальное разрешение прерываний char E=0; while(1) { if(T) // сделать опрос клавиатуры по прерыванию { T=0; //обнуляем флажок E= opros_4x4(); //получаем координаты нажатой кнопки if(E) PORTD=E; //если кнопка была нажата вывести на порт } } }
|