реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Подключение клавиатуры, Не получается
SergeyM
сообщение Jun 15 2005, 17:09
Сообщение #1


Участник
*

Группа: Свой
Сообщений: 68
Регистрация: 1-05-05
Из: Снежинск
Пользователь №: 4 654



Всем привет wink.gif
Решил усовершенствовать свой проект и добавить клаву 4х4. Прочел AVR240 вроде так называлась статья, но реализовывал используя ЖК а не светодиодный индикатор. К тому же клаву подключил к одному порту, ЖК к другому и програмно отправляю символ нажатой клавиши. Все вроде работает но не доконца smile.gif символы выводятся но только по первому столбцу т.е. 7, 4, 1, С (это символы первого столбца в моей клаве). Пробовал по разному делать задержку для антидребезга, но чето никак. Вообще реализую так:
на порт выдаю 0xF0 и с помощью прерываний проверяю число на PIN если не равно 240, то значит нажали на кнопку и отправляюсь в функцию обработки нажатия:
Код
KeyPress(void){
//delay_ms(20); пробовал ее везде пихать :)
switch (PINB) {
   case 224: key = 0;
       delay_ms(10);
       break;
   case 208: key = 4;
       delay_ms(10);
       break;
   case 176: key = 8;
       delay_ms(10);
       break;
   case 112: key = 12;
       delay_ms(10);
       break;  
   };
PORTB = 0x0F;
DDRB = 0xF0;
delay_us(10);
switch (PINB) {
   case 7: key += 0;
       delay_ms(10);
       break;
   case 11: key += 1;
       delay_ms(10);
       break;
   case 13: key += 2;
       delay_ms(10);
       break;
   case 14: key += 3;
       delay_ms(10);
       break;  
   };
PORTB = 0xF0;
DDRB = 0x0F;
PORTA.2 = 1; типа флаг нажати ниче более мудрого сразу не пришло :)

}


Далее в бесконечном цикле проверяю флаг нажатия и отправляю на экран символ из "таблицы" в качестве которой использовал массив символов, а key это номер символа в массиве. Разумеется после отправки флаг сбрасываю.

PS Сильно не ругайте, а вот за дельный совет всегда благодарен буду.
Go to the top of the page
 
+Quote Post
rezident
сообщение Jun 15 2005, 17:57
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Немного не так это делается. По крайней мере я не так делаю.
Сделайте буфер нажатых клавиш. Реализуйте функции типа put_key, check_key и get_key.
put_key это функция сканирования клавиатуры, устранения дребезга и размещения в буфере клавиатуры скан-кода нажатой клавиши (проще всего по табличному принципу). Она же может реализовывать автоповтор нажатой клавиши и обработку нажатия нескольких клавиш (типа ALT + key, CTRL + key и т.п). Количество клавиш ограничено только аппартной реализацией клавиатуры. Буфер клавитуры может иметь любой размер. Буфер циклический. Для помещения и извлечения кодов клавиш используется счетчик скан-кодов и указатель на текущий скан-код. Естественно указатели ограничиваются сверху размером буфера. При равенстве счетчика и указателя (все коды из буфера извлечены) их значения устанавливаются на начало буфера.
Вызывается putkey желательно не менее 6 раз/сек, но не чаще длительности дребезга клавиш (обычно не чаще 100 раз/сек, т.к. чаще ни одна даже профессиональная машинистка не сможет нажимать ИМХО smile.gif). Вызов ее на какое-нибудь прерывание с подходящим периодом подвешивают.
check_key возвращает NULL если в буфере нет ни одного кода клавиши или текущий код клавиши. Указатель на текущий скан-код в буфере и счетчик кодов при этом не изменяется.
get_key возвращает NULL если в буфере нет ни одного кода клавиши или текущий код клавиши. Указатель на текущий скан-код в буфере и счетчик кодов при этом изменяются.
Я не привожу здесь какого-либо программного кода по двум причинам. Во-первых, нет под рукой. Во-вторых, считаю, что лучше уяснить принцип и хотя бы один раз написать самому для полного понимания wink.gif
Go to the top of the page
 
+Quote Post
Make_Pic
сообщение Jun 15 2005, 18:11
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 779
Регистрация: 9-10-04
Из: Россия, Пермь
Пользователь №: 828



Цитата(rezident @ Jun 15 2005, 20:57)
Немного не так это делается. По крайней мере я не так делаю.
Сделайте буфер нажатых клавиш.
*

...


Код в студию! wink.gif
Go to the top of the page
 
+Quote Post
vet
сообщение Jun 15 2005, 18:24
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



Цитата(SergeyM @ Jun 15 2005, 21:09)

на мой взгляд, какая-то неочевидная реализация, я бы сделал проще: единожды настроенный порт далее не трогал бы, а в процедуре опроса клавиш гасил бы столбцы поодиночке и сканировал бы строки на лог.ноль.
Примерно так:
Код
//коды клавиш построчно
flash byte Keys[4][4]={{1,2,3,12},{4,5,6,13},{7,8,9,14},{10,0,11,15}};
char CurrKey;

//опрос
void ProcessKbd(void) {
   char i,j;

   CurrKey = 0xFF; //считаем, что ничего не нажато
   for (i=0;i<4;i++) { //по очереди выводим лог.0 на столбцы
     CLR_KBD_COL(i);
     #asm("nop")
     #asm("nop")
     //опрос входов (строк)
     for (j=0;j<4;j++)
       if (READ_KBD_ROW(j)==0) CurrKey = Keys[j][i];
   }
   //CurrKey - код
   //дальше при желании вешается антидребезг
}


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
yung
сообщение Jun 16 2005, 04:41
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 207
Регистрация: 25-03-05
Из: Рязань
Пользователь №: 3 669



[quote=vet,Jun 15 2005, 21:24]
[quote=SergeyM,Jun 15 2005, 21:09][/quote]
а в процедуре опроса клавиш гасил бы столбцы поодиночке и сканировал бы строки на лог.ноль.

и это правильно, да-ду-да-ду-да.
Go to the top of the page
 
+Quote Post
SergeyM
сообщение Jun 16 2005, 05:01
Сообщение #6


Участник
*

Группа: Свой
Сообщений: 68
Регистрация: 1-05-05
Из: Снежинск
Пользователь №: 4 654



Цитата(rezident @ Jun 15 2005, 20:57)
Немного не так это делается. По крайней мере я не так делаю.
Сделайте буфер нажатых клавиш. Реализуйте функции типа put_key, check_key и get_key.
*


Цитата(vet)
на мой взгляд, какая-то неочевидная реализация, я бы сделал проще: единожды настроенный порт далее не трогал бы, а в процедуре опроса клавиш гасил бы столбцы поодиночке и сканировал бы строки на лог.ноль.


А какое у вас начальное значение выводов или по какому принципу вы определяете что клавиша нажата? Или у вас всегда опрашиваются все клавиши?
Go to the top of the page
 
+Quote Post
yung
сообщение Jun 16 2005, 05:21
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 207
Регистрация: 25-03-05
Из: Рязань
Пользователь №: 3 669



Обычно делается так. Строки определяются как выходы, столбцы как входы (или наоборот, но рассмотрим этот вариант). Столбцы неплохо бы внешними резисторами к + подтянуть (внутренний pull-up не всегда помогает). В исходном состоянии строки установлены в 1. По таймеру каждые, к примеру, 30 мс переводим очередную строку в 0, возвращая предыдующую в 1. Читаем состояние столбцов. Когда столбец равен 0, то нажата клавиша на пересечении столбца и строки. Для верности дожидаемся следующего прохода через эту строку, и в случае, когда там опять 0, считаем клавишу нажатой. Это простейший путь защиты от дребезга, но обычно его достаточно.
Go to the top of the page
 
+Quote Post
rezident
сообщение Jun 16 2005, 15:52
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(SergeyM @ Jun 16 2005, 11:01)
А какое у вас начальное значение выводов или по какому принципу вы определяете что клавиша нажата? Или у вас всегда опрашиваются все клавиши?
*

Обычно используем матрицу 4х4 или 2х4. Соответственно четыре сканирующие линии (выходы с ОК или обычные выходы с диодами) и четыре считывающие линии (входы с pull-up резисторами). В памяти хранится предыдущее состояние матрицы кнопок. 16 кнопок - одно слово. Установленному биту соответствует нажатая клавиша. Если предыдущее состояние равно 0x0000, то перед полным сканированием достаточно проверить нажата ли хоть одна клавиша. Для этого все сканирующие линии можно враз активировать. Если хоть одна кнопка нажата, но начинается полноценная процедура сканирования каждой линии. В результате получаем матрицу текущего состояния кнопок. XORим две матрицы и получаем изменение между двумя состояниями. Если результат XORения равен нулю, то состояние устойчивое и можно определять код нажатой клавиши. Затем запоминаем текущее состояние для использования в следующем цикле сканирования как предыдущее состояние. В цикле накладываем маску вида (1<<i) на маску состояния клавиш и при совпадении получаем смещение (i) в таблице скан-кодов. Вот и все в общих чертах. Далее идут всякие усовершенствования с автоповтором нажатой клавиши, с определением нескольких нажатых клавиш и т.д и т.п.
P.S. Забыл уточнить, что меня обычно интересует только нажатая клавиша, хотя никто не мешает в этом алгоритме сделать и скан-коды отпускания.
P.P.S. Иногда бывает важным, чтобы не все кнопки имели функцию автоповтора. У меня обычно SET и ESC не имеют этой функции, все остальные для удобства навигации в меню и редактирования имеют автоповтор с программируемой паузой и частотой автоповтора.
Go to the top of the page
 
+Quote Post
SergeyM
сообщение Jun 16 2005, 16:07
Сообщение #9


Участник
*

Группа: Свой
Сообщений: 68
Регистрация: 1-05-05
Из: Снежинск
Пользователь №: 4 654



Цитата(rezident @ Jun 16 2005, 18:52)
Обычно используем матрицу 4х4 или 2х4. Соответственно четыре сканирующие линии (выходы с ОК или обычные выходы с диодами) и четыре .......
*


Слушай это все пока что очень сильно для меня, я хотел бы попросить код для анализа и изучения.
Go to the top of the page
 
+Quote Post
SergeyM
сообщение Jun 16 2005, 16:17
Сообщение #10


Участник
*

Группа: Свой
Сообщений: 68
Регистрация: 1-05-05
Из: Снежинск
Пользователь №: 4 654



Цитата(vet @ Jun 15 2005, 21:24)
Код
//коды клавиш построчно
flash byte Keys[4][4]={{1,2,3,12},{4,5,6,13},{7,8,9,14},{10,0,11,15}};
char CurrKey;

*


У меня что то на строку с flash byte ругается (использую cvavr)
Go to the top of the page
 
+Quote Post
rezident
сообщение Jun 16 2005, 16:29
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(SergeyM @ Jun 16 2005, 22:17)
Цитата(vet @ Jun 15 2005, 21:24)
Код
//коды клавиш построчно
flash byte Keys[4][4]={{1,2,3,12},{4,5,6,13},{7,8,9,14},{10,0,11,15}};
char CurrKey;

*


У меня что то на строку с flash byte ругается (использую cvavr)
*


Дык зачем массив-то? Достаточно линейную таблицу.
Я с AVR и CVAVR не работал, но ИМХО директива должна как __flash выглядеть.
Код дома есть, но я забыл его на флешку записать сегодня. Только он для MSP430, а не для AVR.
Go to the top of the page
 
+Quote Post
vet
сообщение Jun 16 2005, 16:35
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



Цитата(rezident @ Jun 16 2005, 20:29)
Цитата(SergeyM @ Jun 16 2005, 22:17)
Цитата(vet @ Jun 15 2005, 21:24)
Код
//коды клавиш построчно
flash byte Keys[4][4]={{1,2,3,12},{4,5,6,13},{7,8,9,14},{10,0,11,15}};
char CurrKey;

*


У меня что то на строку с flash byte ругается (использую cvavr)
*


Дык зачем массив-то? Достаточно линейную таблицу.

А так читабельнее. Можно, конечно.

Цитата(rezident @ Jun 16 2005, 20:29)
Я с AVR и CVAVR не работал, но ИМХО директива должна как __flash выглядеть.
*

Нет, именно так. Я только забыл свой typedef-нный тип убрать, так что вместо byte пишем char.


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
SergeyM
сообщение Jun 16 2005, 16:43
Сообщение #13


Участник
*

Группа: Свой
Сообщений: 68
Регистрация: 1-05-05
Из: Снежинск
Пользователь №: 4 654



Цитата(rezident)


Ниче страшного самое главное суть, давай код
Go to the top of the page
 
+Quote Post
rezident
сообщение Jun 16 2005, 18:29
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(SergeyM @ Jun 16 2005, 22:43)
Цитата(rezident)


Ниче страшного самое главное суть, давай код
*


Суть, то бишь сам алгоритм я уже описал выше wink.gif
Go to the top of the page
 
+Quote Post
AndyBig
сообщение Jun 16 2005, 20:00
Сообщение #15


Иногдящий
****

Группа: Свой
Сообщений: 691
Регистрация: 28-02-05
Пользователь №: 2 931



Я делаю по тому же принципу, что описал vet:
Цитата
единожды настроенный порт далее не трогал бы, а в процедуре опроса клавиш гасил бы столбцы поодиночке и сканировал бы строки на лог.ноль

Но хранение состояний клавиш немного более разветвленное.
У меня хранятся:
1. Текущее состояние (Не нажата, Преднажата, Нажата, Долго нажата, Отпущена) state
2. Значение сантисекунд, когда было выставлено последнее состояние time
3. Флаг ее обработки worked
4. Счетчик повторений count

Упрощенный алгоритм опроса клавиш таков:
Код
- С клавиатуры считывается состояние кнопки.
- Если она не нажата, то:
{
   - если state не равно "Отпущена" или "Не нажата", то установить state в "Отпущена" и worked в "ложь"
}
- Иначе:
{
   switch()
   {
     - Если state равно "Преднажата", установить state в "Нажата", worked в "ложь" и time в текущие сантисекунды
     - Если ее состояние равно "Нажата" и разница между текущими сантисекундами и time больше 50 (пол-секунды), установить state в "Долго нажата", worked в "ложь", time в текущие сантисекунды, count в 1
     - Если ее состояние равно "Долго нажата" и разница между текущими сантисекундами и time больше 10, установить worked в "ложь", инкрементировать count
   }
}
Повторить для всех клавиш



Вот... А в главном цикле просто проверяются флаги worked, и если у какой-то клавиши он установлен в "ложь", то в зависимости от state производятся каки-либо действия, после чего флаг worked сбрасывается в "истина" (а если клавиша была в состоянии "Отпущена", то и состояние сбрасывается в "Не нажата").

Довольно простой алгоритм, позволяющий обрабатывать нажатия кнопок как угодно - одиночные нажатия, долгие нажатия с периодом автонажатия, отпускания...

Да, кстати... период опроса клавиш у меня обычно 10 милисекунд (1 сантисекунда), с одной стороны для антидребезга этого вполне достаточно, с другой стороны - позволяет реагировать на довольно краткие нажатия клавиш.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 11th July 2025 - 16:12
Рейтинг@Mail.ru


Страница сгенерированна за 0.0153 секунд с 7
ELECTRONIX ©2004-2016