Автор |
Сообщение |
|
|
Заголовок сообщения: |
Re: *обработка клавиатуры |
|
|
Вставлю свой грошик. Давным-давно, в далекой-далекой...отставить. В свое время для задачи защиты от дребезга выбрал следующее решение: дребезг контактов фильтруется периодическим (10~20миллисекунд) вызовом (по прерыванию от таймера) п\п ( здесь - check-keys) считывания порта, к которому пристегнуты кнопочки. Код - для иллюстрации, кнопочки: нажата=1, не нажата=0, подробности - в комментариях. Код: : BIN DECIMAL 2 BASE ! ; : .bin-byte ( c -- ) BASE @ >R BIN 0 <# # # # # # # # # #> TYPE SPACE R> BASE ! ;
MARKER keys-task
0 VALUE keys-last \ состояние кнопов прочитанное в предыдущий раз 0 VALUE keys-stat \ предыдущее изменение состояния кнопов 0 VALUE keys-flag \ кнопы готовые для обработки
: check-keys ( c -- ) \ keys-last OVER XOR \ текущее изменеение состояния кнопов keys-stat OVER XOR \ отфильтровали дребезг кнопов keys-stat AND \ отфильтровали актуальныей кнопы TO keys-flag TO keys-stat TO keys-last ;
: keys-done 0 TO keys-flag ;
: keys-tst. CR ." keys :" SPACE keys-last .bin-byte CR ." stat :" SPACE keys-stat .bin-byte CR ." ready;" SPACE keys-flag .bin-byte CR ;
Тогда это писалось на ассемблере, работало в нескольких проектах, какие-либо претензии к эксплуатации кода не запомнились, видимо работало нормально. Код: SP-FORTH - ANS FORTH 94 for Win95/98/Me/NT/2k/XP/Vista Open source project at http://spf.sf.net Russian FIG at http://www.forth.org.ru ; Started by A.Cherezov Version 4.20 Build 001 at 21.Jan.2009
>RunScript Ok >BIN Ok >00000000 check-keys keys-tst. keys-done
keys : 00000000 stat : 00000000 ready; 00000000 Ok >11000000 check-keys keys-tst. keys-done
keys : 11000000 stat : 11000000 ready; 00000000 Ok >10000000 check-keys keys-tst. keys-done
keys : 10000000 stat : 01000000 ready; 10000000 Ok >01000000 check-keys keys-tst. keys-done
keys : 01000000 stat : 11000000 ready; 00000000 Ok >01000000 check-keys keys-tst. keys-done
keys : 01000000 stat : 00000000 ready; 11000000 Ok >01000000 check-keys keys-tst. keys-done
keys : 01000000 stat : 00000000 ready; 00000000 Ok >01000000 check-keys keys-tst. keys-done
keys : 01000000 stat : 00000000 ready; 00000000 Ok >00000000 check-keys keys-tst. keys-done
keys : 00000000 stat : 01000000 ready; 00000000 Ok >00000000 check-keys keys-tst. keys-done
keys : 00000000 stat : 00000000 ready; 01000000 Ok >00000000 check-keys keys-tst. keys-done
keys : 00000000 stat : 00000000 ready; 00000000 Ok >
keys-flag содержит кнопы, "заслуживающие внимания", после обработки необходимо обнулять keys-last хранит состояние (нажата\не нажата) соответствующих кнопов. Здесь представлена только защита от дребезга, т.е. задача, представленная Олегом, не решена.
Вставлю свой грошик. Давным-давно, в далекой-далекой...отставить. В свое время для задачи защиты от дребезга выбрал следующее решение: дребезг контактов фильтруется периодическим (10~20миллисекунд) вызовом (по прерыванию от таймера) п\п ( здесь - [b]check-keys[/b]) считывания порта, к которому пристегнуты кнопочки. Код - для иллюстрации, кнопочки: нажата=1, не нажата=0, подробности - в комментариях. [code]
: BIN DECIMAL 2 BASE ! ; : .bin-byte ( c -- ) BASE @ >R BIN 0 <# # # # # # # # # #> TYPE SPACE R> BASE ! ;
MARKER keys-task
0 VALUE keys-last \ состояние кнопов прочитанное в предыдущий раз 0 VALUE keys-stat \ предыдущее изменение состояния кнопов 0 VALUE keys-flag \ кнопы готовые для обработки
: check-keys ( c -- ) \ keys-last OVER XOR \ текущее изменеение состояния кнопов keys-stat OVER XOR \ отфильтровали дребезг кнопов keys-stat AND \ отфильтровали актуальныей кнопы TO keys-flag TO keys-stat TO keys-last ;
: keys-done 0 TO keys-flag ;
: keys-tst. CR ." keys :" SPACE keys-last .bin-byte CR ." stat :" SPACE keys-stat .bin-byte CR ." ready;" SPACE keys-flag .bin-byte CR ; [/code]
Тогда это писалось на ассемблере, работало в нескольких проектах, какие-либо претензии к эксплуатации кода не запомнились, видимо работало нормально. [code] SP-FORTH - ANS FORTH 94 for Win95/98/Me/NT/2k/XP/Vista Open source project at http://spf.sf.net Russian FIG at http://www.forth.org.ru ; Started by A.Cherezov Version 4.20 Build 001 at 21.Jan.2009
>RunScript Ok >BIN Ok >00000000 check-keys keys-tst. keys-done
keys : 00000000 stat : 00000000 ready; 00000000 Ok >11000000 check-keys keys-tst. keys-done
keys : 11000000 stat : 11000000 ready; 00000000 Ok >10000000 check-keys keys-tst. keys-done
keys : 10000000 stat : 01000000 ready; 10000000 Ok >01000000 check-keys keys-tst. keys-done
keys : 01000000 stat : 11000000 ready; 00000000 Ok >01000000 check-keys keys-tst. keys-done
keys : 01000000 stat : 00000000 ready; 11000000 Ok >01000000 check-keys keys-tst. keys-done
keys : 01000000 stat : 00000000 ready; 00000000 Ok >01000000 check-keys keys-tst. keys-done
keys : 01000000 stat : 00000000 ready; 00000000 Ok >00000000 check-keys keys-tst. keys-done
keys : 00000000 stat : 01000000 ready; 00000000 Ok >00000000 check-keys keys-tst. keys-done
keys : 00000000 stat : 00000000 ready; 01000000 Ok >00000000 check-keys keys-tst. keys-done
keys : 00000000 stat : 00000000 ready; 00000000 Ok > [/code]
[b]keys-flag[/b] содержит кнопы, "заслуживающие внимания", после обработки необходимо обнулять [b]keys-last[/b] хранит состояние (нажата\не нажата) соответствующих кнопов. Здесь представлена только защита от дребезга, т.е. задача, представленная Олегом, не решена.
|
|
|
|
Добавлено: Вт янв 01, 2013 12:03 |
|
|
|
|
|
Заголовок сообщения: |
Re: *обработка клавиатуры |
|
|
Код: 1999 CONSTANT MaxLim 0 CONSTANT MinLim 2 CONSTANT Step CREATE (cnt) 8 CELLS ALLOT (cnt) 8 CELLS ERASE : cnt ( n -- a ) CELLS (cnt) + ; : Step+ ( n -- ) cnt DUP @ Step + MaxLim MIN SWAP ! ; : Step- ( n -- ) cnt DUP @ Step - MinLim MAX SWAP ! ; : cnt+ ( n cnt -- ) 1 OVER LSHIFT ROT AND 0= IF Step+ ELSE Step- THEN ; : KeyCikl ( keybrd - ) 8 0 DO DUP I cnt+ LOOP DROP ; : c? ( n -- 0-up,1-press,3-down,4-unpress ) cnt @ DUP MinLim = IF DROP 0 EXIT THEN DUP MaxLim = IF DROP 3 EXIT THEN 1 AND 0= IF 1 ELSE 4 THEN ;
настроить на железе можно меняя MaxLim и Step, но самое главное MaxLim должен быть нечетным, а Step четным. именно это гарантирует правильное определение и смену состояний up->press->down->unpress состояние клавиши можно получить с помощью слова c? номера от 0 до 7, а внутри рабочего цикла использовать KeyCikl
[code]1999 CONSTANT MaxLim 0 CONSTANT MinLim 2 CONSTANT Step CREATE (cnt) 8 CELLS ALLOT (cnt) 8 CELLS ERASE : cnt ( n -- a ) CELLS (cnt) + ; : Step+ ( n -- ) cnt DUP @ Step + MaxLim MIN SWAP ! ; : Step- ( n -- ) cnt DUP @ Step - MinLim MAX SWAP ! ; : cnt+ ( n cnt -- ) 1 OVER LSHIFT ROT AND 0= IF Step+ ELSE Step- THEN ; : KeyCikl ( keybrd - ) 8 0 DO DUP I cnt+ LOOP DROP ; : c? ( n -- 0-up,1-press,3-down,4-unpress ) cnt @ DUP MinLim = IF DROP 0 EXIT THEN DUP MaxLim = IF DROP 3 EXIT THEN 1 AND 0= IF 1 ELSE 4 THEN ; [/code]настроить на железе можно меняя MaxLim и Step, но самое главное MaxLim должен быть нечетным, а Step четным. именно это гарантирует правильное определение и смену состояний up->press->down->unpress состояние клавиши можно получить с помощью слова c? номера от 0 до 7, а внутри рабочего цикла использовать KeyCikl
|
|
|
|
Добавлено: Пн дек 24, 2012 06:34 |
|
|
|
|
|
Заголовок сообщения: |
Re: *обработка клавиатуры |
|
|
Пробую решать налету Код: HEX \ параметры "схемы" антидребезга для для настройки времен срабатывания и \ пороговых уровней тригера шмидта 13 CONSTANT MAXRG 2 CONSTANT MINRG 11 CONSTANT MAXEDGE 4 CONSTANT MINEDGE \ интеграторы схемы антидребезга VARIABLE RG1 VARIABLE RG2 VARIABLE RG3 VARIABLE RG4 VARIABLE RG5 VARIABLE RG6 VARIABLE RG7 VARIABLE RG8 VALUE RG RG1 to RG \ рабочий регистр для обработчика кнопки \ счетчик в младшем байте RG \ триггер шмидта в старших разрядах RG : KEY_WORK ( false|true --> ) \ АНТИДРЕБЕЗГОВАЯ ОБРАБОТКА БИТА КНОПКИ 0= IF \ КНОПКА НЕ НАЖАТА RG @ 0FF AND MAXRG < IF 1 RG +! \ если не достигло максимума - увеличивать RG @ 0FF AND MINEDGE < IF RG 00FF AND RG ! THEN \ нижний порог тригера шмидта THEN ELSE \ КНОПКА НАЖАТА RG @ 0FF AND MINRG > IF -1 RG +! \ если не достигло минимума - уменьшать RG @ 0FF AND MAXEDGE > IF RG FF00 OR RG ! THEN \ верхний порог тригера шмидта THEN THEN VARIABLE KEYS \ КОПИЯ ПОРТА КНОПОК VALUE KMASK \ МАСКА БИТА КНОПКИ : KEYBIT KEYS @ KMASK AND ; : WORK_ALL INKEYS \ ВВОД КНОПОК ИЗ ПОРТА KEYS ! \ сохранить 1 ТО KMASK KEYBIT RG1 TO RG KEY_WORK 2 ТО KMASK KEYBIT RG2 TO RG KEY_WORK 4 ТО KMASK KEYBIT RG3 TO RG KEY_WORK 8 ТО KMASK KEYBIT RG4 TO RG KEY_WORK 10 ТО KMASK KEYBIT RG5 TO RG KEY_WORK 20 ТО KMASK KEYBIT RG6 TO RG KEY_WORK 40 ТО KMASK KEYBIT RG7 TO RG KEY_WORK 80 ТО KMASK KEYBIT RG8 TO RG KEY_WORK
\ остается только выдать здесь результат в нужном виде
;
вызывать WORK_ALL 10000 раз в секунду и ловить нажатия/отпускания в старших байтах RG1...RG8 ВАРНИНГ! код не проверялся - не на чем
Пробую решать налету [code]HEX \ параметры "схемы" антидребезга для для настройки времен срабатывания и \ пороговых уровней тригера шмидта 13 CONSTANT MAXRG 2 CONSTANT MINRG 11 CONSTANT MAXEDGE 4 CONSTANT MINEDGE \ интеграторы схемы антидребезга VARIABLE RG1 VARIABLE RG2 VARIABLE RG3 VARIABLE RG4 VARIABLE RG5 VARIABLE RG6 VARIABLE RG7 VARIABLE RG8 VALUE RG RG1 to RG \ рабочий регистр для обработчика кнопки \ счетчик в младшем байте RG \ триггер шмидта в старших разрядах RG : KEY_WORK ( false|true --> ) \ АНТИДРЕБЕЗГОВАЯ ОБРАБОТКА БИТА КНОПКИ 0= IF \ КНОПКА НЕ НАЖАТА RG @ 0FF AND MAXRG < IF 1 RG +! \ если не достигло максимума - увеличивать RG @ 0FF AND MINEDGE < IF RG 00FF AND RG ! THEN \ нижний порог тригера шмидта THEN ELSE \ КНОПКА НАЖАТА RG @ 0FF AND MINRG > IF -1 RG +! \ если не достигло минимума - уменьшать RG @ 0FF AND MAXEDGE > IF RG FF00 OR RG ! THEN \ верхний порог тригера шмидта THEN THEN VARIABLE KEYS \ КОПИЯ ПОРТА КНОПОК VALUE KMASK \ МАСКА БИТА КНОПКИ : KEYBIT KEYS @ KMASK AND ; : WORK_ALL INKEYS \ ВВОД КНОПОК ИЗ ПОРТА KEYS ! \ сохранить 1 ТО KMASK KEYBIT RG1 TO RG KEY_WORK 2 ТО KMASK KEYBIT RG2 TO RG KEY_WORK 4 ТО KMASK KEYBIT RG3 TO RG KEY_WORK 8 ТО KMASK KEYBIT RG4 TO RG KEY_WORK 10 ТО KMASK KEYBIT RG5 TO RG KEY_WORK 20 ТО KMASK KEYBIT RG6 TO RG KEY_WORK 40 ТО KMASK KEYBIT RG7 TO RG KEY_WORK 80 ТО KMASK KEYBIT RG8 TO RG KEY_WORK
\ остается только выдать здесь результат в нужном виде
; [/code] вызывать [b]WORK_ALL[/b] 10000 раз в секунду и ловить нажатия/отпускания в старших байтах RG1...RG8 [color=#FF0000][b]ВАРНИНГ! код не проверялся - не на чем[/b][/color]
|
|
|
|
Добавлено: Сб дек 22, 2012 22:24 |
|
|
|
|
|
Заголовок сообщения: |
Re: *обработка клавиатуры |
|
|
получается, что на каждую клавишу надо 2 бита, т.к. состояния UP,DN,PRESS и UNPRESS, т.е функция должна выдавать на выходе 8х2=16 бит Я похожую вещь на 16 кнопок с антидребезгом у себя делал сразу в ПЛИСе используя вот такие фильтры viewtopic.php?f=11&t=2748 на каждую кнопку
получается, что на каждую клавишу надо 2 бита, т.к. состояния UP,DN,PRESS и UNPRESS, т.е функция должна выдавать на выходе 8х2=16 бит Я похожую вещь на 16 кнопок с антидребезгом у себя делал сразу в ПЛИСе используя вот такие фильтры http://fforum.winglion.ru/viewtopic.php?f=11&t=2748 на каждую кнопку
|
|
|
|
Добавлено: Сб дек 22, 2012 18:15 |
|
|
|
|
|
Заголовок сообщения: |
*обработка клавиатуры |
|
|
В этот раз вполне практическая задача.
Имеется очень простая клавиатура: набор из 8 кнопок, каждая из которых подключена к одному порту В/В, каждая линия притянута к питанию через резистор, и при нажатии на кнопку соответствующий контакт замыкается на землю (то есть: пока не нажали - на входе 1, при нажатии на входе 0). Заданная функция вызывается периодически ~10000 раз в секунду: на входе состояние порта В/В (один байт, т.е. те самые 8 бит каждый из которых соответствует одной клавише). Где-то в теле программы происходит проверка на состояние каждой клавиши с последующим выполнением заданных действий. Для каждой клавиши должно быть определено четыре состояния: отжата, нажата, нажимается, отжимается - действия в коде могут выполняться по любому из состояний. Реакция оператора невелика, поэтому в результате работы заданной функции состояние любой из клавиш не должно меняться чаще 10 раз в секунду (т.е. необходимо устранить дребезг), выявить моменты нажатия и отжатия клавиш, а так же удобным способом передать в программу состояния клавиш. Необходимо разработать механизм, позволяющий пользователю взаимодействовать с клавиатурой. Название и количество используемых функций на ваше усмотрение.
В этот раз вполне практическая задача.
Имеется очень простая клавиатура: набор из 8 кнопок, каждая из которых подключена к одному порту В/В, каждая линия притянута к питанию через резистор, и при нажатии на кнопку соответствующий контакт замыкается на землю (то есть: пока не нажали - на входе 1, при нажатии на входе 0). Заданная функция вызывается периодически ~10000 раз в секунду: на входе состояние порта В/В (один байт, т.е. те самые 8 бит каждый из которых соответствует одной клавише). Где-то в теле программы происходит проверка на состояние каждой клавиши с последующим выполнением заданных действий. Для каждой клавиши должно быть определено четыре состояния: отжата, нажата, нажимается, отжимается - действия в коде могут выполняться по любому из состояний. Реакция оператора невелика, поэтому в результате работы заданной функции состояние любой из клавиш не должно меняться чаще 10 раз в секунду (т.е. необходимо устранить дребезг), выявить моменты нажатия и отжатия клавиш, а так же удобным способом передать в программу состояния клавиш. Необходимо разработать механизм, позволяющий пользователю взаимодействовать с клавиатурой. Название и количество используемых функций на ваше усмотрение.
|
|
|
|
Добавлено: Сб дек 22, 2012 17:39 |
|
|
|
|