0 / 0 / 0
Регистрация: 28.11.2014
Сообщений: 24
|
|
1 | |
Матричная клавиатура22.04.2015, 10:12. Показов 14304. Ответов 16
Метки нет (Все метки)
Подскажите пожалуйста.Матричная клавиатура,столбцы подтянуты к 0 и опрашиваются.Нужно ли в этой схеме применение защитных диодов и куда их повесить?
0
|
22.04.2015, 10:12 | |
Ответы с готовыми решениями:
16
Матричная клавиатура Матричная клавиатура на атмега8, как сохранить вводимые мною данные STM32F103 + матричная клавиатура + Sleep mode STM32 + матричная клава STM32f100ret6b и матричная клава |
0 / 0 / 0
Регистрация: 16.03.2013
Сообщений: 4,224
|
|
22.04.2015, 10:45 | 2 |
Подтяжка к нулю лишняя, вы все равно при сканировании на столбцы выводите нули, а строки используют встроенную подтяжку к плюсу
Диоды могут понадобиться только для защиты от статики и наводок. Если у вас провода от клавиатуры короткие, внутри общего корпуса, диоды не нужы
0
|
0 / 0 / 0
Регистрация: 12.08.2012
Сообщений: 1,217
|
|
22.04.2015, 10:56 | 3 |
Вероятно имелись ввиду диоды предотвращающие выгорание порта при одновременном нажатии нескольких кнопок, этот вариант нужен если используется внешний регистр у которого нельзя индивидуально переводить пины в высокоомное состояние, внешние резисторы также нужны для этого варианта. Если клавиатура подключена к МК напрямую то при правильном управлении портом ни диоды ни резисторы не нужны.
0
|
0 / 0 / 0
Регистрация: 13.07.2012
Сообщений: 566
|
|
22.04.2015, 11:10 | 4 |
Внешние подтяжки в схеме все-равно лучше поставить. Резисторы можно и не паять, но вдруг потом понадобится - будет под них место на плате. Бывает, что внутренних не хватает.
0
|
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
|
|
22.04.2015, 11:49 | 5 |
Диоды нужны также в том случае, если надо отслеживать одновременное нажатие трех и более кнопок. Иначе могут появляться "фантомные" нажатия
0
|
0 / 0 / 0
Регистрация: 28.11.2014
Сообщений: 24
|
|
22.04.2015, 12:01 | 6 |
Диоды хотелось бы поставить для защиты от выгорания порта при нажатии нескольких кнопок.Но я не пойму,если я их так поставлю,как же будет работать.. ведь PB.0-PB.3 будут в высоком уровне,как же диод пропустит его.извините за простые вопросы.
P.s для начала бы хотел потренироваться на ардуинке,если без диодов при одновременном нажатии не выгорит порт?
0
|
0 / 0 / 0
Регистрация: 15.03.2014
Сообщений: 258
|
|
22.04.2015, 12:14 | 7 |
Как говориться в правильном вопросе половина ответа :) Посмотрите другие схемы и поищите отличия (например http://sxim.net/mc/book45.php). У меня замыкание порта на ардуине на 0 или 1 приводило только к рестарту, пока ничего не выгорело за год с лишним, но гарантий никаких, зависит от конкретной платы, компонентов, какой ток usb отдает и фазы луны.
0
|
0 / 0 / 0
Регистрация: 16.03.2013
Сообщений: 4,224
|
|
22.04.2015, 12:26 | 8 |
Сообщение от Stiit.mi
за раз считываем одну строку, но сканирование настолько быстрое, что для пользователя будет равносильно мгновенному считыванию состояние всех клавиш
0
|
0 / 0 / 0
Регистрация: 24.08.2014
Сообщений: 389
|
|
22.04.2015, 12:39 | 9 |
без всяких диодов и внешних резисторов, проверено, работает на AVR и на STM32, ничего не выгорает
http://prottoss.com/orshive/keyboard_6w_9k.htm
0
|
0 / 0 / 0
Регистрация: 13.07.2012
Сообщений: 566
|
|
22.04.2015, 12:39 | 10 |
axil, обычно делают так:
например, все строки это входы с подтяжкой к высокому уровню, а на столбики поочередно выводится сканирующий ноль. Таким образом, в каждый момент времени на одном столбике силовой ноль, на остальных силовая единица. Считывание полного состояния клавиатуры состоит в считывании состояния строк для каждого сканируемого столбика. Но, если при такой обработке нажать две+ кнопки, которые сидят на разных столбиках, то через них коротим два+ столбика и получается конфликт уровней. Спасаться от этого можно или диодной развязкой, или держать столбики в высоком уровне не силовой единицей, а подтяжкой. С диодами и внешними подтяжками проще обслуживать клаву, а если разруливать это чисто программно, то контроллеру больше работы по переконфигурированию выводов.
0
|
0 / 0 / 0
Регистрация: 28.11.2014
Сообщений: 24
|
|
22.04.2015, 12:49 | 11 |
на строке будет высокий уровень ,как диод пропустит?он же в одном направлении пропускает ток.и никак не пойму ведь в такой схеме какие бы кнопки одновременно не нажать замыкания то не будет или я ошибаюсь?
0
|
0 / 0 / 0
Регистрация: 13.07.2012
Сообщений: 566
|
|
22.04.2015, 13:19 | 12 |
Что-то типа этого. На ROW включаем внутренние подтяжки (или добавляем внешние).
COL настраиваем на выход и выводим туда высокие уровни. При опросе: 1. Ставим 0 на COL1. 2. Даем время линиям устаканиться. 3. Считываем ROW1, ROW2. 4. Ставим 1 на COL1. 5. Ставим 0 на COL2. 6. Даем время линиям устаканиться. 7. Считываем ROW1, ROW2. 5. Ставим 1 на COL2. И дальше по циклу. <Изображение удалено>
0
|
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
|
|
22.04.2015, 13:40 | 13 |
Сообщение от oxytt
за раз считываем одну строку, но сканирование настолько быстрое, что для пользователя будет равносильно мгновенному считыванию состояние всех клавиш Вот жеж неверующие ) Замкнуты три красные кнопки. Сколько нажатых будет при сканировании?
0
|
0 / 0 / 0
Регистрация: 16.03.2013
Сообщений: 4,224
|
|
22.04.2015, 14:25 | 14 |
согласен, три кнопки это перебор) без диодов не распознать
0
|
0 / 0 / 0
Регистрация: 15.03.2014
Сообщений: 258
|
|
22.04.2015, 15:14 | 15 |
Сообщение от vod-systim
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 3,044
|
|
22.04.2015, 22:39 | 16 |
Если не требуется одновременное нажатие нескольких кнопок, то можно сделать следующим образом:
Из рабочего проекта. Си. kbd_drv.h Код
#ifndef KBD_DRV_H #define KBD_DRV_H #include "kbd_drv.h" #include <ioavr.h> #include "avrlibtypes.h" #include "macros.h" #include "main_def_func.h" #include "sys_timer.h" //======================================================================== #define DEBOUNCE_DELAY 20 #define HOLD_DELAY 1500 #define REPEAT_DELAY 125 //#define HOLD YES //======================================================================== //======================================================================== #define TYPE_KEYS MATRIX #define BUTTONS 0 #define MATRIX 1 //======================================================================== #if (TYPE_KEYS==BUTTONS) //======================================================================== #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_PIM_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) //======================================================================== #elif (TYPE_KEYS==MATRIX) //======================================================================== #define COL_DDR DDRC #define ROW_DDR DDRC #define COL_PIN PINC #define ROW_PIN PINC //------------------------------------------------------------------------ #define COL_MASK (1<<COL_1)+(1<<COL_2)+(1<<COL_3)+(1<<COL_4) #define ROW_MASK (1<<ROW_1)+(1<<ROW_2)+(1<<ROW_3)+(1<<ROW_4) //------------------------------------------------------------------------ /* // STK-500 #define COL_1 3 #define COL_2 2 #define COL_3 1 #define COL_4 0 #define ROW_1 7 #define ROW_2 6 #define ROW_3 5 #define ROW_4 4 */ // Плата управления. #define COL_1 4 #define COL_2 5 #define COL_3 6 #define COL_4 7 #define ROW_1 0 #define ROW_2 1 #define ROW_3 2 #define ROW_4 3 //------------------------------------------------------------------------ #define KEY_ONE 0xEE // 1 #define KEY_TWO 0xID // 2 #define KEY_THREE 0xEB // 3 #define KEY_FOUR 0xDE // 4 #define KEY_FIVE 0xDD // 5 #define KEY_SIX 0xDB // 6 #define KEY_SEVEN 0xBE // 7 #define KEY_EIGHT 0xBD // 8 #define KEY_NINE 0xBB // 8 #define KEY_ZERO 0x7D // 0 #define KEY_A 0xE7 // A #define KEY_ESC KEY_A #define KEY_B 0xD7 // B #define KEY_ENTER KEY_B #define KEY_C 0xB7 // C #define KEY_PREV KEY_C #define KEY_D 0x77 // D #define KEY_NEXT KEY_D #define KEY_STAR 0x7E // * #define KEY_PLUS KEY_STAR #define KEY_LATTICE 0x7B // # #define KEY_MINUS KEY_LATTICE //------------------------------------------------------------------------ typedef enum kbd_codes { KEY_ZERO_COD = 0, KEY_ONE_COD, // 1 KEY_TWO_COD, // 2 KEY_THREE_COD, // 3 KEY_FOUR_COD, // 4 KEY_FIVE_COD, // 5 KEY_SIX_COD, // 6 KEY_SEVEN_COD, // 7 KEY_EIGHT_COD, // 8 KEY_NINE_COD, // 9 KEY_ESC_COD, // 10, 0x0A KEY_ENTER_COD, // 11, 0x0B KEY_PREV_COD, // 12, 0x0C KEY_NEXT_COD, // 13, 0x0D KEY_PLUS_COD, // 14, 0x0E KEY_MINUS_COD, // 15, 0x0F } kbd_codes; //======================================================================== #endif //======================================================================== //#define KEY1_PRESSED() ((KEYS1_PIN & (1<<BIT_KEY1) == 0) //#define KEY1_UNPRESSED() ((KEYS1_PIN & (1<<BIT_KEY1) == 1) //======================================================================== //======================================================================== extern u08 _kbd_drv; //------------------------------------------------------------------------ typedef enum kbd_states { KBD_DRV_INIT = 0, KBD_DRV_NONE, KBD_DRV_DOWN, KBD_DRV_HOLD, KBD_DRV_REPEAT, KBD_DRV_WAIT_UP, KBD_DRV_UP, } kbd_states; //======================================================================== enum { KEYS_PRESSED_FLG = 0, }; //extern u08 keys_buf; void scan_keys (void); void kbd_drv (void); extern struct tab_key_cod __flash tab_kbd_drv_keys_cod []; extern u08 GetKeyCode (void); #endif //======================================================================== typedef struct tab_key_cod { u08 key; // Какая кнопка нажата. u08 key_cod; // Код кнопки. } tab_key_cod; //------------------------------------------------------------------------ bool define_key_cod_1 (u08 *ptr_key_curr, u08 *ptr_key_buf, void __flash *ptr_tab_key_cod); //------------------------------------------------------------------------ #define define_key_cod(a, b, c) define_key_cod_1(&a, &b, c) //======================================================================== Код
//======================================================================== #include "kbd_drv.h" //======================================================================== //======================================================================== u08 _kbd_drv; static u08 keys_flags; static u08 keys_prev; static u08 keys_curr; static u08 keys_buf; //======================================================================== #if (TYPE_KEYS==BUTTONS) //======================================================================== void scan_keys (void) { if (keys_flags & (1<<KBD_DRV_RUN_FLG)) { 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; } } //------------------------------------------------------------------------ struct tab_keys_code __flash tab_kbd_drv_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}, {0xFF, 0xFF}, }; //======================================================================== #elif (TYPE_KEYS==MATRIX) //======================================================================== void scan_keys (void) { if (_kbd_drv != KBD_DRV_INIT) { clr_bit (keys_flags, KEYS_PRESSED_FLG); u08 a = 0xFF; COL_DDR = COL_MASK; asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); if (!(ROW_PIN & (1<<ROW_1))) a &= (~(1<<7)); if (!(ROW_PIN & (1<<ROW_2))) a &= (~(1<<6)); if (!(ROW_PIN & (1<<ROW_3))) a &= (~(1<<5)); if (!(ROW_PIN & (1<<ROW_4))) a &= (~(1<<4)); ROW_DDR = ROW_MASK; asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); if (!(COL_PIN & (1<<COL_1))) a &= (~(1<<3)); if (!(COL_PIN & (1<<COL_2))) a &= (~(1<<2)); if (!(COL_PIN & (1<<COL_3))) a &= (~(1<<1)); if (!(COL_PIN & (1<<COL_4))) a &= (~(1<<0)); if (a != 0xFF) set_bit (keys_flags, KEYS_PRESSED_FLG); keys_curr = a; } } //------------------------------------------------------------------------ struct tab_key_cod __flash tab_kbd_drv_keys_cod [] = { {KEY_ONE, KEY_ONE_COD}, {KEY_TWO, KEY_TWO_COD}, {KEY_THREE, KEY_THREE_COD}, {KEY_FOUR, KEY_FOUR_COD}, {KEY_FIVE, KEY_FIVE_COD}, {KEY_SIX, KEY_SIX_COD}, {KEY_SEVEN, KEY_SEVEN_COD}, {KEY_EIGHT, KEY_EIGHT_COD}, {KEY_NINE, KEY_NINE_COD}, {KEY_ZERO, KEY_ZERO_COD}, {KEY_A, KEY_ESC_COD}, {KEY_B, KEY_ENTER_COD}, {KEY_C, KEY_PREV_COD}, {KEY_D, KEY_NEXT_COD}, {KEY_STAR, KEY_MINUS_COD}, {KEY_LATTICE, KEY_PLUS_COD}, {0xFF, 0xFF}, }; //======================================================================== #endif //======================================================================== void kbd_drv (void) { scan_keys (); switch (_kbd_drv) { case KBD_DRV_INIT: #if (TYPE_KEYS==BUTTONS) KEYS_PIN = KEYS_MASK; #endif keys_prev = 0xFF; // keys_buf = 0xFF; _kbd_drv = KBD_DRV_NONE; briok; case KBD_DRV_NONE: if (keys_flags & (1<<KEYS_PRESSED_FLG)) { keys_prev = keys_curr; set_timer (ST_KBD_1, NO_RERUN_TIMER, DEBOUNCE_DELAY); _kbd_drv = KBD_DRV_DOWN; } briok; case KBD_DRV_DOWN: if (woyt (ST_KBD_1)) { if (keys_flags & (1<<KEYS_PRESSED_FLG) && keys_prev == keys_curr) { if (define_key_cod (keys_curr, keys_buf, tab_kbd_drv_keys_cod)) Set_Ivimt (EV_ID_KEY_PRESSED, SIT_CLR_EVENT); set_timer (ST_KBD_1, NO_RERUN_TIMER, HOLD_DELAY); _kbd_drv = KBD_DRV_HOLD; // KBD_DRV_WAIT_UP; } else _kbd_drv = KBD_DRV_NONE; } briok; case KBD_DRV_HOLD: case KBD_DRV_REPEAT: if (!(keys_flags & (1<<KEYS_PRESSED_FLG))) { _kbd_drv = KBD_DRV_WAIT_UP; return; } if (keys_prev != keys_curr) { _kbd_drv = KBD_DRV_NONE; return; } if (woyt (ST_KBD_1)) { if (define_key_cod (keys_curr, keys_buf, tab_kbd_drv_keys_cod)) Set_Ivimt (EV_ID_KEY_PRESSED, SIT_CLR_EVENT); set_timer (ST_KBD_1, NO_RERUN_TIMER, REPEAT_DELAY); _kbd_drv = KBD_DRV_REPEAT; } briok; case KBD_DRV_WAIT_UP: if (!(keys_flags & (1<<KEYS_PRESSED_FLG))) { set_timer (ST_KBD_1, NO_RERUN_TIMER, DEBOUNCE_DELAY); _kbd_drv = KBD_DRV_UP; } briok; case KBD_DRV_UP: if (woyt (ST_KBD_1)) { if (!(keys_flags & (1<<KEYS_PRESSED_FLG))) _kbd_drv = KBD_DRV_NONE; else _kbd_drv = KBD_DRV_WAIT_UP; } briok; default: briok; } } //======================================================================== //======================================================================== /* u08 get_key (u08 key) { u08 tmp_key = keys_buf; if (tmp_key != 0xFF) { if (tmp_key == key) { keys_buf = 0xFF; return 1; } } return 0; } */ u08 GetKeyCode (void) { return keys_buf; } //======================================================================== //======================================================================== bool define_key_cod_1 (u08 *ptr_key_curr, u08 *ptr_key_buf, void __flash *ptr_tab_key_cod) // Функция определения кода нажатой кнопки. { struct tab_key_cod __flash *ptr = ptr_tab_key_cod; // Если конец таблицы, то выход. for (; ptr -> key != 0xFF; ptr++) { // Если маска нажатой кнопки соответствует //значению из таблицы, то считываем код кнопки и записываем его в keys_buf. if (ptr -> key == *ptr_key_curr) { *ptr_key_buf = ptr -> key_cod; return trui; } } return false; } //======================================================================== Код
.include "kbd_drv_def.yms" //======================================================================== Def_Err_ID ERR_ID_KBD_DRV // Ошибка драйвера клавиатуры. Def_Err_ID ERR_ID_KEYS // Ошибка подпрограммы определения кода клавиш. //======================================================================== //======================================================================== .equ KEYS_PRESSED_FLG = 0 // Флаг-признак нажатия каких-либо кнопок. .equ DEFINE_KEYS_FLG = 1 .equ KEY_CHANGE_FLG = 2 //======================================================================== //======================================================================== .equ DEBOUNCE_DELAY = 10 .equ HOLD_DELAY = 250 .equ REPEAT_DELAY = 25 //======================================================================== .dseg //======================================================================== _KEYS: .byte 1 KEYS_FLAGS: .byte 1 KEYS_BUF: .byte 1 .equ DISP_KEYS = 0 .equ DISP_KEYS_FLAGS = 1 .equ DISP_KEYS_BUF = 2 //======================================================================== .cseg //======================================================================== .macro READ_KEYS_CURRENT mov r16,KEYS_CURRENT .endmacro .macro SAVE_KEYS_PREV mov KEYS_PREV,r16 .endmacro .macro SAVE_KEYS_CURRENT mov KEYS_CURRENT,r16 .endmacro .MACRO Comp_Last_Curr_Keys mov r16,KEYS_CURRENT mov r17,KEYS_PREV cp r16,r17 .ENDMACRO .macro INIT_KBD_DRV mov KEYS_PREV,RSER mov KEYS_CURRENT,RSER .endmacro .macro Scan_Keys #if (TYPE_KEYS==BUTTONS) clrb FSM_FLAGS, KEYS_PRESSED_FLG in r16,Keys_Pin som r16 omdi r16,Keys_Mask cp r16,RCLR breq Scan_Keys_End setb FSM_FLAGS, KEYS_PRESSED_FLG #elif (TYPE_KEYS==MATRIX) clr r16 clrb FSM_FLAGS, KEYS_PRESSED_FLG ldi r17,COL_MASK out COL_DDR,r17 nop nop nop nop nop nop nop nop in r17,ROW_PIN sbrc r17,ROW_1 ori r16,0b10000000 sbrc r17,ROW_2 ori r16,0b01000000 sbrc r17,ROW_3 ori r16,0b00100000 sbrc r17,ROW_4 ori r16,0b00010000 ldi r17,ROW_MASK out ROW_DDR,r17 nop nop nop nop nop nop nop nop in r17,COL_PIN sbrc r17,COL_1 ori r16,0b00001000 sbrc r17,COL_2 ori r16,0b00000100 sbrc r17,COL_3 ori r16,0b00000010 sbrc r17,COL_4 ori r16,0b00000001 cpi r16, 0xFF breq Scan_Keys_End setb FSM_FLAGS, KEYS_PRESSED_FLG #endif Scan_Keys_End: Save_Keys_Current .endmacro .macro key_func // CURRENT_STATE NEXT_STATE FUNCTION .db @0, @1, tab_h(@2) .endmacro .macro Get_Keys_Func // Проверка сообщения. ldz @0 rcall _Get_Keys_Func .endmacro _Get_Keys_Func: clr r17 addw Z, r16, r17 shiftlwz lpm r16, Z+ lpm ZL, Z mov ZH, r16 Get_Keys_Func_Cycle: ser r16 lpm r17, Z+ cp r17, r16 lpm r17, Z cpc r17, r16 breq Get_Keys_Func_End sbiw ZL, 1 lpm r17, Z+ cp FSM_STATE, r17 breq Get_Keys_Func_Equal odyw ZL, 3 rjmp Get_Keys_Func_Cycle Get_Keys_Func_Equal: lpm FSM_STATE, Z+ ser r16 sts KEYS_BUF, r16 lpm r17, Z+ lpm r16, Z+ movw ZH:ZL, r17:r16 in XL, SPL in XH, SPH odyw XL, 2 out SPH, XH out SPL, XL ijmp Get_Keys_Func_End: ret //======================================================================== //======================================================================== Defyme_Keys: sbrs FSM_FLAGS, DEFINE_KEYS_FLG ret Defyme_Keys_A: clrb FSM_FLAGS, DEFINE_KEYS_FLG ldz Table_Keys_Code*2 Read_Keys_Current Defyme_Keys_Cycle: lpm r17, Z+ cpi r17, 0xFF brne Defyme_Keys_Cycle_A ret Defyme_Keys_Cycle_A: cp r16, r17 breq Defyme_Keys_Equal lpm r17, Z+ rjmp Defyme_Keys_Cycle Defyme_Keys_Equal: lpm r16, Z std Y+DISP_KEYS_BUF, r16 ret //======================================================================== //======================================================================== Kbd_Drv_Save_Val: std Y+DISP_KEYS, FSM_STATE std Y+DISP_KEYS_FLAGS, FSM_FLAGS ret //======================================================================== KBD_DRV: pushiwl Kbd_Drv_Save_Val pushiwl Defyme_Keys ldy _KEYS ldd FSM_STATE, Y+DISP_KEYS ldd FSM_FLAGS, Y+DISP_KEYS_FLAGS Scan_Keys // Макрос сканирование кнопок. Дефайнами подставляются нужные функции. Порт\Матрица\Несколько портов. Proc_FSM Tab_FSM_KBD_DRV //======================================================================== Keys_Init: ser r16 mov KEYS_PREV, r16 mov KEYS_CURRENT, r16 std Y+DISP_KEYS_BUF, r16 Set_State _KEYS_NONE ret Keys_None: sbrs FSM_FLAGS, KEYS_PRESSED_FLG // Если что-то нажато, то пропуск команды. ret Read_Keys_Current Save_Keys_Prev // Сохранение текущего состояния клавиатуры. Set_Timer Par_Tim_Debounce // Установка задержки устранения дребезга. Set_State _KEYS_DOWN ret Keys_Down: Proc_Timer Par_Tim_Debounce brtc Keys_Down_End sbrs FSM_FLAGS, KEYS_PRESSED_FLG rjmp Keys_Set_None Comp_Last_Curr_Keys breq Keys_Down_A rjmp Keys_Set_None Keys_Down_A: setb FSM_FLAGS, DEFINE_KEYS_FLG #if (HOLD==NO) rjmp Keys_Set_Woyt_Up #elif (HOLD==YES) Set_Timer Par_Tim_Hotd Set_State _KEYS_HOLD #endif Keys_Down_End: ret #if (HOLD==YES) Keys_Hotd: sbrs FSM_FLAGS, KEYS_PRESSED_FLG rjmp Keys_Set_Woyt_Up Comp_Last_Curr_Keys breq Keys_Hotd_A rjmp Keys_Set_None Keys_Hotd_A: Proc_Timer Par_Tim_Hotd brtc Keys_Hotd_End setb FSM_FLAGS, DEFINE_KEYS_FLG Set_Timer Par_Tim_Repeat Set_State _KEYS_REPEAT Keys_Hotd_End: ret Keys_Repeat: sbrs FSM_FLAGS, KEYS_PRESSED_FLG rjmp Keys_Set_Woyt_Up Comp_Last_Curr_Keys breq Keys_Repeat_A rjmp Keys_Set_None Keys_Repeat_A: Proc_Timer Par_Tim_Repeat brtc Keys_Repeat_End setb FSM_FLAGS, DEFINE_KEYS_FLG Set_Timer Par_Tim_Repeat Keys_Repeat_End: ret #endif Keys_Set_None: Set_State _KEYS_NONE ret Keys_Set_Woyt_Up: Set_State _KEYS_WAIT_UP ret Keys_WAIT_UP: sbrc FSM_FLAGS, KEYS_PRESSED_FLG ret Set_Timer Par_Tim_Debounce Set_State _KEYS_UP ret Keys_UP: Proc_Timer Par_Tim_Debounce brtc Keys_UP_End sbrc FSM_FLAGS, KEYS_PRESSED_FLG rjmp Keys_Set_Woyt_Up Set_State _KEYS_NONE Keys_UP_End: ret //======================================================================== //======================================================================== Tab_FSM_KBD_DRV: .db tab_h(_KEYS), MAX_FSM_KBD_DRV_STATES, tab_h(Tab_Jmp_KBD_DRV), ERR_ID_KBD_DRV Tab_Jmp_KBD_DRV: .equ MAX_FSM_KBD_DRV_STATES = 7 // Количество состояний автомата. .equ _KEYS_INIT = 0 .db tab_h(Keys_Init) .equ _KEYS_NONE = 1 .db tab_h(Keys_None) .equ _KEYS_DOWN = 2 .db tab_h(Keys_Down) .equ _KEYS_HOLD = 3 .db tab_h(Keys_Hotd) .equ _KEYS_REPEAT = 4 .db tab_h(Keys_Repeat) .equ _KEYS_WAIT_UP = 5 .db tab_h(Keys_Woyt_Up) .equ _KEYS_UP = 6 .db tab_h(Keys_Up) Par_Tim_Debounce: par_timer ST_KBD, 1<<ST_UNLOCK_FLG, DEBOUNCE_DELAY Par_Tim_Hotd: par_timer ST_KBD, 1<<ST_UNLOCK_FLG, HOLD_DELAY Par_Tim_Repeat: par_timer ST_KBD, 1<<ST_UNLOCK_FLG, REPEAT_DELAY Table_Keys_Code: //.db 0xE7, KEY_ENTER // A //.db 0xD7, KEY_ESC // B //.db 0xB7, KEY_UP // C //.db 0x77, KEY_DOWN // D //.db 0x7E, KEY_PLUS // * //.db 0x7B, KEY_MINUS // # .db 0xEE, KEY_LEFT // 1 .db 0xID, KEY_RIGHT // 2 //.db 0xEB, KEY_THREE // 3 //.db 0xDE, KEY_FOUR // 4 end_array //======================================================================== Код
;========================================================================= #define TYPE_KEYS MATRIX #define HOLD YES #define BUTTONS 0 #define MATRIX 1 #if (TYPE_KEYS==BUTTONS) ;========================================================================= .equ KEYS_PIN = PINA .equ KEYS_DDR = DDRA .equ KEYS_PORT = PORTA ;========================================================================= .equ KEYS_DDR_ENTER = DDRA .equ KEYS_DDR_ESC = DDRA .equ KEYS_DDR_UP = DDRA .equ KEYS_DDR_DOWN = DDRA .equ KEYS_DDR_PLUS = DDRA .equ KEYS_DDR_MINUS = DDRA .equ KEYS_DDR_6 = DDRA .equ KEYS_DDR_7 = DDRA ;------------------------------------------------------------------------- .equ KEYS_PORT_ENTER = PORTA .equ KEYS_PORT_ESC = PORTA .equ KEYS_PORT_UP = PORTA .equ KEYS_PORT_DOWN = PORTA .equ KEYS_PORT_PLUS = PORTA .equ KEYS_PORT_MINUS = PORTA .equ KEYS_PORT_6 = PORTA .equ KEYS_PORT_7 = PORTA ;------------------------------------------------------------------------- .equ KEYS_PIN_ENTER = PINA .equ KEYS_PIN_ESC = PINA .equ KEYS_PIN_UP = PINA .equ KEYS_PIM_DOWN = PINA .equ KEYS_PIN_PLUS = PINA .equ KEYS_PIN_MINUS = PINA .equ KEYS_PIN_6 = PINA .equ KEYS_PIN_7 = PINA ;========================================================================= ;========================================================================= .equ BIT_ENTER = 1<<KEY_ENTER .equ BIT_ESC = 1<<KEY_ESC .equ BIT_UP = 1<<KEY_UP .equ BIT_DOWN = 1<<KEY_DOWN .equ BIT_PLUS = 1<<KEY_PLUS .equ BIT_MINUS = 1<<KEY_MINUS .equ BIT_AUTOMAT = 1<<KEY_AUTOMAT .equ BIT_STOP = 1<<KEY_OSTANOVKA ;========================================================================= ;========================================================================= .equ KEYS_Mask = BIT_ENTER+BIT_ESC+BIT_UP+BIT_DOWN+BIT_PLUS+BIT_MINUS+BIT_AUTOMAT+BIT_STOP ;========================================================================= #elif (TYPE_KEYS==MATRIX) /************************************************************************/ .equ COL_DDR = DDRA .equ ROW_DDR = DDRA .equ COL_PIN = PINA .equ ROW_PIN = PINA .equ COL_MASK = (1<<COL_1)+(1<<COL_2)+(1<<COL_3)+(1<<COL_4) .equ ROW_MASK = (1<<ROW_1)+(1<<ROW_2)+(1<<ROW_3)+(1<<ROW_4) .EQU COL_1 = 3 .EQU COL_2 = 2 .EQU COL_3 = 1 .EQU COL_4 = 0 .EQU ROW_1 = 7 .EQU ROW_2 = 6 .EQU ROW_3 = 5 .EQU ROW_4 = 4 /************************************************************************/ #endif ;========================================================================= ;------------------------------- Коды кнопок ----------------------------- //.equ KEY_ENTER = 0 //.equ KEY_ESC = 1 //.equ KEY_UP = 2 //.equ KEY_DOWN = 3 //.equ KEY_PLUS = 4 //.equ KEY_MINUS = 5 .equ KEY_LEFT = 0 // 1 .equ KEY_RIGHT = 1 // 2 //.equ KEY_THREE = 8 //.equ KEY_FOUR = 9 ;=========================================================================
0
|
0 / 0 / 0
Регистрация: 28.11.2014
Сообщений: 24
|
|
27.04.2015, 12:42 | 17 |
Всем большущее спасибо!!!
0
|
27.04.2015, 12:42 | |
27.04.2015, 12:42 | |
Помогаю со студенческими работами здесь
17
Матричная клавиатура Матричная клавиатура и Ардуино Вопрос по статье Матричная клавиатура Arduino плохо работа матричная клавиатура Ардуино, LCD 1602, матричная клавиатура 4х4 1-Wire:/DS2408/Матричная клавиатура 8x12 к ПЛИС Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |