Меня пока это устраивает: kbd_drv.h:
#ifndef KBD_DRV_H
#define KBD_DRV_H
#include "kbd_drv.h"
#include <avr/io.h>
#include "avrlibtypes.h"
#include "macros.h"
#include "sys_timer.h"
#include "char_display.h"
#include "prgmem_lib.h"
//========================================================================
#define DEBOUNCE_DELAY 20
//#define HOLD YES
//========================================================================
//========================================================================
#define KEYS_PIN PINA
#define KEYS_DDR DDRA
#define KEYS_PORT PORTA
//========================================================================
#define KEYS_DDR_ESC DDRA
#define KEYS_DDR_ENTER DDRA
#define KEYS_DDR_UP DDRA
#define KEYS_DDR_DOWN DDRA
#define KEYS_DDR_PLUS DDRA
#define KEYS_DDR_MINUS DDRA
#define KEYS_DDR_6 DDRA
#define KEYS_DDR_7 DDRA
//------------------------------------------------------------------------
#define KEYS_PORT_ESC PORTA
#define KEYS_PORT_ENTER PORTA
#define KEYS_PORT_UP PORTA
#define KEYS_PORT_DOWN PORTA
#define KEYS_PORT_PLUS PORTA
#define KEYS_PORT_MINUS PORTA
#define KEYS_PORT_6 PORTA
#define KEYS_PORT_7 PORTA
//------------------------------------------------------------------------
#define KEYS_PIN_ESC PINA
#define KEYS_PIN_ENTER PINA
#define KEYS_PIN_UP PINA
#define KEYS_PIN_DOWN PINA
#define KEYS_PIN_PLUS PINA
#define KEYS_PIN_MINUS PINA
#define KEYS_PIN_6 PINA
#define KEYS_PIN_7 PINA
//------------------------------------------------------------------------
#define KEY_ESC_PIN 0
#define KEY_ENTER_PIN 1
#define KEY_UP_PIN 2
#define KEY_DOWN_PIN 3
#define KEY_PLUS_PIN 4
#define KEY_MINUS_PIN 5
//------------------------------------------------------------------------
#define KEY_ESC_BIT 1<<KEY_ESC_PIN
#define KEY_ENTER_BIT 1<<KEY_ENTER_PIN
#define KEY_UP_BIT 1<<KEY_UP_PIN
#define KEY_DOWN_BIT 1<<KEY_DOWN_PIN
#define KEY_PLUS_BIT 1<<KEY_PLUS_PIN
#define KEY_MINUS_BIT 1<<KEY_MINUS_PIN
#define KEY_ESC_COD 0
#define KEY_ENTER_COD 1
#define KEY_UP_COD 2
#define KEY_DOWN_COD 3
#define KEY_PLUS_COD 4
#define KEY_MINUS_COD 5
//========================================================================
//========================================================================
#define KEYS_MASK (KEY_ESC_BIT | KEY_ENTER_BIT | KEY_UP_BIT | KEY_DOWN_BIT | KEY_PLUS_BIT | KEY_MINUS_BIT)
//========================================================================
//#define KEY1_PRESSED() ((KEYS1_PIN & (1<<BIT_KEY1) == 0)
//#define KEY1_UNPRESSED() ((KEYS1_PIN & (1<<BIT_KEY1) == 1)
extern u08 keys_buf;
typedef enum kbd_states
{
KEYS_INIT=0,
KEYS_NONE,
KEYS_DOWN,
KEYS_WAIT_UP,
KEYS_UP,
} kbd_states;
void scan_keys (void);
void kbd_drv (void);
void (define_keys) (void);
#endif
kbd_drv.c:
//========================================================================
#include "kbd_drv.h"
//========================================================================
static u08 keys_flags;
#define KEYS_PRESSED_FLG 0
#define DEFINE_KEYS_FLG 1
static u08 keys_curr;
u08 keys_buf;
//========================================================================
typedef struct PROGMEM
{
u08 key; // Какая кнопка нажата.
u08 key_cod; // Код кнопки
} str_key_cod;
str_key_cod tab_keys_code [] =
{
{KEY_ESC_BIT, KEY_ESC_COD},
{KEY_ENTER_BIT, KEY_ENTER_COD},
{KEY_UP_BIT, KEY_UP_COD},
{KEY_DOWN_BIT, KEY_DOWN_COD},
{KEY_PLUS_BIT, KEY_PLUS_COD},
{KEY_MINUS_BIT, KEY_MINUS_COD},
};
//------------------------------------------------------------------------
void (define_keys) (void) // Функция определения кода нажатой кнопки.
{
if (keys_flags & 1<<DEFINE_KEYS_FLG) // Если установлен этот флаг, определение кнопки, иначе выход.
{
clrb (keys_flags, DEFINE_KEYS_FLG); // Сброс флага.
u08 i;
// Если конец таблицы, то выход.
for (i=0; prw (tab_keys_code [i]) != sizeof (tab_keys_code); i++)
{
// Если маска нажатой кнопки соответствует
//значению из таблицы, то считываем код кнопки и записываем его в keys_buf.
if (prb (tab_keys_code [i].key) == keys_curr)
{
keys_buf = prb (tab_keys_code [i].key_cod);
DDRD = prb (tab_keys_code [i].key_cod); // test!!!
break;
}
}
}
}
//========================================================================
void scan_keys (void)
{
clrb (keys_flags, KEYS_PRESSED_FLG);
u08 a;
a = ~KEYS_PIN;
a &= KEYS_MASK;
if (a != 0)
{
setb (keys_flags, KEYS_PRESSED_FLG);
}
keys_curr = a;
}
//========================================================================
void kbd_drv(void)
{
static u08 _keys;
static u08 keys_prev;
scan_keys ();
switch (_keys)
{
case KEYS_INIT:
keys_prev = 0xFF;
keys_curr = 0xFF;
keys_buf = 0xFF;
_keys = KEYS_NONE;
break;
case KEYS_NONE:
if (keys_flags & (1<<KEYS_PRESSED_FLG))
{
keys_prev = keys_curr;
set_timer (ST_KBD, 1<<TMR_UNLOCK_FLG, DEBOUNCE_DELAY);
_keys = KEYS_DOWN;
}
break;
case KEYS_DOWN:
if (wait (ST_KBD))
{
if (keys_flags & (1<<KEYS_PRESSED_FLG) && keys_prev == keys_curr)
{
setb (keys_flags, DEFINE_KEYS_FLG);
_keys = KEYS_WAIT_UP;
// set_timer (ST_KBD, 1<<TMR_UNLOCK_FLG, HOLD_DELAY);
// _keys = KEYS_HOLD;
}
else
_keys = KEYS_NONE;
}
break;
case KEYS_WAIT_UP:
if (!(keys_flags & (1<<KEYS_PRESSED_FLG)))
{
set_timer (ST_KBD, 1<<TMR_UNLOCK_FLG, DEBOUNCE_DELAY);
_keys = KEYS_UP;
}
break;
case KEYS_UP:
if (wait (ST_KBD))
{
if (!(keys_flags & (1<<KEYS_PRESSED_FLG)))
_keys = KEYS_NONE;
else
_keys = KEYS_WAIT_UP;
}
break;
default:
_keys = KEYS_INIT;
break;
}
define_keys();
}
//========================================================================
-
- Оформлено уже достаточно симпатично. SciFi(1286 знак., 19.09.2013 12:45 - 12:55)
- Оппа, а как вы сделали обращение к портам по указателю? Если я правильно понял, конечно. - Mazur(19.09.2013 13:25)
- Почему бы и нет? IO-порты находятся в общем адресном пространстве. Можете почитать Apтём(161 знак., 19.09.2013 16:02)
- Я с этими вашими аврами дела не имел, но интернеты подсказывают, что и там можно -> - SciFi(19.09.2013 14:44, ссылка)
- можно. только у IAR и WinAVR выглядит по-разному. - Vit(19.09.2013 16:48)
- В чём разница? Apтём(132 знак., 19.09.2013 17:05)
- Скомпилировать может и получится. У IAR там struct/union @address, а у AVR_GCC смещение 0x20 макросом _SFR_IO8() запихивается Vit(100 знак., 19.09.2013 17:42)
- В чём разница? Apтём(132 знак., 19.09.2013 17:05)
- Можно. Мне приходилось так делать. - Bill(19.09.2013 15:58)
- можно. только у IAR и WinAVR выглядит по-разному. - Vit(19.09.2013 16:48)
- Оппа, а как вы сделали обращение к портам по указателю? Если я правильно понял, конечно. - Mazur(19.09.2013 13:25)
- Оформлено уже достаточно симпатично. SciFi(1286 знак., 19.09.2013 12:45 - 12:55)