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

 
 
> обработка повторных нажатий клавиатуры, 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
Ответов
GoodNews
сообщение Feb 24 2010, 19:55
Сообщение #2


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

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



Итак, вот что получилось.
kbd.c
CODE

#include <avr/io.h>
#include <avr/interrupt.h>
#include "kbd.h"
#define READ_KEY_COL() ((~KBD_PIN) & 0x0f)
enum {
STATE_WAIT,
STATE_DEBOUNCE,
STATE_WAITKEYUP
};
static uint8_t KBD_PrevKey;
static uint8_t KBD_LastKey;
uint8_t KBD_ScanRow;
uint8_t KBD_KeyDown = 0;
uint8_t KEY_STATE = STATE_WAIT;
uint8_t COLUMN_DEFAULT_STATE = 0x00;
volatile uint16_t time = 0;
volatile unsigned char column;

volatile uint8_t isKeyInBuffer = 0;
volatile uint8_t columnInBuffer;
volatile uint8_t rowInBuffer;

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

void KBD_TASK(void)
{
switch (KEY_STATE)
{
//case 0 - ожидание нажатия клавиши
case STATE_WAIT:
if (READ_KEY_COL() == COLUMN_DEFAULT_STATE)
{
KBD_KeyDown = 0;
break;
}
KBD_PrevKey = READ_KEY_COL();
time = 0;
KEY_STATE = STATE_DEBOUNCE;
break;
//Убираем дребезг
case STATE_DEBOUNCE:
KBD_LastKey = READ_KEY_COL();
if (KBD_LastKey != KBD_PrevKey)
{
time = 0;
KBD_KeyDown = 0;
KEY_STATE = STATE_WAIT;
break;
}
if (time > 40)
{
columnInBuffer = KBD_LastKey;
rowInBuffer = KBD_ScanRow;
isKeyInBuffer = 1;
KEY_STATE = STATE_WAITKEYUP; //Всё-таки нажатие не случайное
}
break;
//Ожидание отжатия клавиши
case STATE_WAITKEYUP:
if (READ_KEY_COL() != COLUMN_DEFAULT_STATE)
{
time = 0;
break; //Клавишу не отпустили
}
if (time > 1024)
{
KEY_STATE = STATE_WAIT; //Клавишу отпустили
KBD_KeyDown = 0;
}
}
}
unsigned char KBD_GetKey(void)
{
unsigned char KBD_PressedKey = NO_KEY;
if (isKeyInBuffer)
{
switch (columnInBuffer)
{
case 0x00:
KBD_PressedKey = NO_KEY;
break;
case 0x01:
KBD_PressedKey = KBD_Array[rowInBuffer][0];
break;
case 0x02:
KBD_PressedKey = KBD_Array[rowInBuffer][1];
break;
case 0x04:
KBD_PressedKey = KBD_Array[rowInBuffer][2];
break;
case 0x08:
KBD_PressedKey = KBD_Array[rowInBuffer][3];
break;
default:
KBD_PressedKey = NO_KEY;
}
isKeyInBuffer = 0;
}
return (KBD_PressedKey);
}

//Обработка переполнения Timer1
ISR(TIMER1_OVF_vect)
{
TCNT1 = TMR1_CNT;
time++;

if (!KBD_KeyDown)
{
KBD_PORT |= (0x10<<KBD_ScanRow);
if (++KBD_ScanRow > 3)
KBD_ScanRow = 0;
KBD_PORT &= ~(0x10<<KBD_ScanRow);
asm("nop");
column = READ_KEY_COL();
if (COLUMN_DEFAULT_STATE != READ_KEY_COL())
KBD_KeyDown = 1;
} else
KBD_TASK();
}

//Конфигурирования контроллера для работы с клавиатурой
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 = TMR1_CNT;
TIMSK = (1<<TOIE1); //Включить прерывание по переполнению для Timer1
TCCR1A = 0x00;
TCCR1B = (1<<CS12)|(1<<CS10); //Включаем делитель /1024

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

kbd.h
CODE

#ifndef _KBD_H
#define _KBD_H
#endif
#include

//Столбцы клавиатуры
#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

//Если ни одна клавиша не была нажата, то возвращаем значение 0
#define NO_KEY 0

//Состояние выходов порта клавиатуры при отжатых клавишах
#define KBD_DEFAULT_STATE 0xff

//Timer1 стартует с позиции 0xffff (MAX)
#define TMR1_CNT 0xffff

void KBD_init(void);
unsigned char KBD_GetKey(void);
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 19:58
Рейтинг@Mail.ru


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