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

 
 
> обработка повторных нажатий клавиатуры, atmega32+4x4 kbd
GoodNews
сообщение Feb 21 2010, 18:50
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 88
Регистрация: 12-01-09
Из: Minsk (BY)
Пользователь №: 43 259



Драйвер клавиатуры построен на базе атмеловского апноута AVR245. Есть одно но - повторные нажатия клавиш не могу реализовать. Т.е. теоретически представляю как это должно выглядеть, но на практике не получается. Я думал вначале использовать сравнение состояний порта клавиатуры. Т.е. при инициализации драйвера берём объявляем некоторую статическую переменную, в которую загружаем значение порта (все клавиши отпущены), затем в функции обработки клавиш считываем текущее состояние порта и сравниваем со значением по-умолчанию. Если не совпадает, то выводим значение, если совпадает - пропускаем. Также по идее должно проверяться была ли физически отпущена клавиша. Посоветуйте плиз как можно выйти из данного положения.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
sigmaN
сообщение Feb 21 2010, 19:57
Сообщение #2


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Сам я не видел никогда апноута AVR245, так что мой совет может оказаться совсем не в тему.
Как насчёт сделать так, чтобы нажатия и отпускания клавиш приводили к возникновению прерывания?
Ежели это будет весьма накладно и неудобно - нужно сделать чтобы клавиатура опрашивалась по таймеру(т.е. опять таки прерывание).
Сохраняя каждый раз last state и сравнивая его с только что считанным значением можно всегда понять было ли что-то отпущено или нажато....

Вопрос задан как-то не совсем ясно...приходится заниматься телепатией sad.gif
Цитата
Есть одно но - повторные нажатия клавиш не могу реализовать.
это что значит? Как в компе, нажал кнопку и держишь, сначала печатеается одна буква, потом некоторая задержка, а потом буковка начинает повторятся, пока кнопочку не отпустишь? Это имеется ввиду?

Или же нужно что-то типа подавления дребезга контактов?
Нужно чтобы топикстартер всё это прояснил.

Клавиатура с точки зрения железа как построена?

Лень мне искать аппноут smile.gif


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
GoodNews
сообщение Feb 21 2010, 21:40
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 88
Регистрация: 12-01-09
Из: Minsk (BY)
Пользователь №: 43 259



Цитата(sigmaN @ Feb 21 2010, 21:57) *
Клавиатура с точки зрения железа как построена?

Лень мне искать аппноут smile.gif

AVR245: Code Lock with 4x4 Keypad and I2C™ LCD
Сорри. Неправильно написал. Имел ввиду, что не могу понять, как реализовать обработку повторных нажатий (чтобы их избежать).
Вот как код выглядит.
kbd.c
CODE
#include <avr/io.h>
#include <avr/interrupt.h>
#include "kbd.h"

unsigned char KBD_KeyPressed;
unsigned char KBD_LastKey;
unsigned char KBD_ScanRow;
unsigned char KBD_KeyDown;
//Потом убрать
unsigned char KBD_LastRow;
volatile unsigned char column;

//Обработка переполнения Timer1
ISR(TIMER1_OVF_vect)
{
if (!KBD_KeyDown)
{
KBD_PORT |= (0x10<<KBD_ScanRow);
if (++KBD_ScanRow > 3)
KBD_ScanRow = 0;
KBD_PORT &= ~(0x10<<KBD_ScanRow);
asm("nop");
column = (~KBD_PIN) & 0x0f;
}
}

//Считываем значение Timer1
uint16_t read_TCNT1(void)
{
uint16_t i;
unsigned char sreg;

sreg = SREG; //запоминаем состояние бита I (остальные биты нам в общем то побоку)
asm("cli"); //убедимся что флаг I сброшен
i = TCNT1; //читаем TCNT1
SREG = sreg; //востанавливаем состояние бита I
//(если он был сброшен до входа в процедуру то эта операция не даст никакого эффекта)
return i;
}

unsigned char KBD_GetKey(void)
{
unsigned char sreg;
sreg = SREG;
asm("cli");
switch (column)
{
case 0x00:
KBD_KeyDown = 0;
break;
case 0x01:
KBD_LastKey = KBD_Array[KBD_ScanRow][0];
KBD_LastRow = KBD_ScanRow;
if (!KBD_KeyDown)
KBD_KeyPressed = 1;
KBD_KeyDown = 1;
break;
case 0x02:
KBD_LastKey = KBD_Array[KBD_ScanRow][1];
KBD_LastRow = KBD_ScanRow;
if (!KBD_KeyDown)
KBD_KeyPressed = 1;
KBD_KeyDown = 1;
break;
case 0x04:
KBD_LastKey = KBD_Array[KBD_ScanRow][2];
KBD_LastRow = KBD_ScanRow;
if (!KBD_KeyDown)
KBD_KeyPressed = 1;
KBD_KeyDown = 1;
break;
case 0x08:
KBD_LastKey = KBD_Array[KBD_ScanRow][3];
KBD_LastRow = KBD_ScanRow;
if (!KBD_KeyDown)
KBD_KeyPressed = 1;
KBD_KeyDown = 1;
break;
default:
KBD_LastKey = 0;
KBD_KeyPressed = 0;
}

SREG = sreg;
if (KBD_KeyPressed)
{
KBD_KeyDown = 0;
KBD_KeyPressed = 0;
return (KBD_LastKey);
} else return (NO_KEY);
}

//Конфигурирования контроллера для работы с клавиатурой
void KBD_init(void)
{
//Конфигурируем порт клаваиатуры
KBD_REG |= (X1|X2|X3|X4);
KBD_REG &= ~(Y1|Y2|Y3|Y4);

//Конфигурирем выводы клавиатуры
//X1-X4 - выходы, высокий уровень
//Y1-Y4 - входы, высокий уровень, pull-up активен
KBD_PORT |= (X1|X2|X3|X4|Y1|Y2|Y3|Y4);

//Конфигурация таймеров
TCNT0 = 0x00;
TCNT1 = 0x1FF;
TIMSK = (1<<TOIE1); //Включить прерывание по переполнению для Timer1
TCCR1A = 0x00;
TCCR1B = (1<<CS11); //Включаем делитель /8

//Включаем обработку прерываний
asm("sei");
}

kbd.h
CODE
#ifndef _KBD_H
#define _KBD_H
#endif
#include <avr/io.h>

//Столбцы клавиатуры
#define Y1 (1<<0)
#define Y2 (1<<1)
#define Y3 (1<<2)
#define Y4 (1<<3)

//Строки клавиатуры
#define X1 (1<<4)
#define X2 (1<<5)
#define X3 (1<<6)
#define X4 (1<<7)

//Порт клавиатуры
#define KBD_PORT PORTB
#define KBD_PIN PINB

//Конфигурация порта клавиатуры
#define KBD_REG DDRB

void KBD_init(void);
unsigned char KBD_GetKey(void);
uint16_t read_TCNT1(void);

//Если ни одна клавиша не была нажата, то возвращаем значение -1
static uint8_t NO_KEY = -1;

//Массив определяющий значения клавиш
static uint8_t KBD_Array[4][4]=
{
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
extern volatile unsigned char column;
extern unsigned char KBD_LastRow;

Как я уже сказал, идея в том, что надо нажать кнопку, напечатается один символ. Второй символ напечатается после того, как кнопка будет отпущена. А вот уже этим вторым символом может быть эта же кнопка ну и т.д. Т.е. нужно пройти через факт "одно нажатие - один символ".

Цитата(rezident @ Feb 21 2010, 23:08) *
Все правильно вы мыслите.

smile.gif верной дорогой значит! Автоповтор в принципе я не планирую использовать. Клавиатура используется для прямого ввода значений частоты и управления меню (меню пока ещё на стадии планирования, поэтому пока даже и не рассматривается). Надо переварить супчик smile.gif Спасибо за наводку на мысль smile.gif

Сообщение отредактировал rezident - Feb 21 2010, 22:17
Причина редактирования: Нарушение п.3.4 Правил форума.
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 3rd August 2025 - 14:50
Рейтинг@Mail.ru


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