Выкладываю конечный код, дабы начинающие такие как я не задавали глупые вопросы :). Считаю данный код прост для понимания, и удовлетворит начальный интерес к работе с кнопками. <c>
/*===========================================
определения для линий матричной клавиатуры
===========================================*/
// определения портов клавиатуры
// порты строк
#define KB_PORT_ROW PORTD
#define KB_PIN_ROW PIND
#define KB_DDR_ROW DDRD
// порты столбцов
#define KB_PORT_COL PORTD
#define KB_PIN_COL PIND
#define KB_DDR_COL DDRD
// линии строк
#define KB_ROW_WIRES ((1 << PD1) | (1 << PD2))
#define KB_ROW_SHIFT 1 // количество сдвигов вправо кода строк при формировании кода кнопки
// линии столбцов
#define KB_COL_WIRES ((1 << PD5) | (1 << PD6) | (1 << PD7))
char scan; // Код нажатой клавиши, формируется KB_Read_2x3
/******************************************************************************
Опрос клавиатуры. Возвращает код нажатой кнопки в переменную scan.
В старшей тетраде – состояние линий строк, в младшей тетраде – состояние линий столбцов
Если в одной из тетрад кода кнопки более одного нуля, код не действительный
******************************************************************************/
// Прерывание TIMER 0 для опроса клавиатуры каждые 32 ms
interrupt [TIM0_OVF] void KB_Read_2x3(void)
{
char code1, code2;
static char press;
KB_DDR_ROW &= ~KB_ROW_WIRES; // порт строк на ввод
KB_PORT_ROW |= KB_ROW_WIRES; // к выводам порта строк подключаем pull-up резисторы
KB_DDR_COL |= KB_COL_WIRES; // порт столбцов на вывод
KB_PORT_COL &= ~KB_COL_WIRES; // на всех выводах порта столбцов лог "0"
#asm("nop") // задержка на один такт, для установления сигналов на выводах порта
code1 = (KB_PIN_ROW >> KB_ROW_SHIFT) & 0x3; // считываем состояние линий строк и преобразуем в код
KB_DDR_COL &= ~KB_COL_WIRES; // порт столбцов на ввод
KB_PORT_COL |= KB_COL_WIRES; // к выводам порта столбцов подключаем pull-up резисторы
KB_DDR_ROW |= KB_ROW_WIRES; // устанавливаем направление порта строк на вывод
KB_PORT_ROW &= ~KB_ROW_WIRES; // на всех линиях порта строк лог "0"
#asm("nop") // задержка на один такт, для установления сигналов на выводах порта
code2 = (KB_PIN_COL & 0xE0); // считываем состояние линий столбцов и преобразуем в код
/* Устранение дребезга.
Алгоритм устранения сводится к сравнению двух сканов,
если они равны, значит состояние устойчивое, сохраняем код.
Иначе код равен нулю.*/
code2|=code1|0x1C; // Формируем код кнопки и сохраняем в code2
scan=(~(press^code2))&press; // возвращаем полученные коды состояний столбцов и строк если совпали два соседних скана
press=code2; // Сохраняем предыдущий скан
}
/******************************************************************************
Функция проверки новых нажатий, возвращает код нажатой кнопки. Активный ноль.
******************************************************************************/
char inkey(void)
{
static char pressOld; // Переменная для хранения предыдущего состояния клавиатуры
char code; // Код нажатой кнопки - активный ноль
if(!(scan^pressOld)) // Если нет нажатых кнопок
{code=0; // Код равен нулю
pressOld=scan; // Сохраняем текущий скан
return code; // Возвращаем код=0
}
code=scan; // Если есть новое нажатие
pressOld=scan; // Сохраняем текущий скан
return code; // Возвращаем код нажатой кнопки
}
// Функция инициализации таймера
// Вызывает прерывание каждые 32 мс.
timer_init(void)
{
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
TCCR0=0x05;
TCNT0=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;
#asm("sei")
}
</c>
-
- ИМХО, inkey() можно покрасивше написать ReAl(639 знак., 28.07.2007 15:32)
- Да это покрасивее будет:) Я вот думаю, а почему все делают if(old^New) code=New? Ведь код можно вычислить проще code=old&(~New).
А unsigned не пишу, так как у меня char по умолчанию unsigned. - Dany(28.07.2007 15:55, )
- ИМХО наиболее удачная функция inkey(). Коротко и лаконично, как следствие -красиво. Принята за конечную:) Dany(327 знак., 30.07.2007 09:59, )
- Да это покрасивее будет:) Я вот думаю, а почему все делают if(old^New) code=New? Ведь код можно вычислить проще code=old&(~New).
А unsigned не пишу, так как у меня char по умолчанию unsigned. - Dany(28.07.2007 15:55, )
- ИМХО, inkey() можно покрасивше написать ReAl(639 знак., 28.07.2007 15:32)