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

 
 
> нажатие кнопки, в течение определенного интервала
romez777
сообщение Aug 19 2010, 08:35
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 292
Регистрация: 9-11-04
Пользователь №: 1 077



Здравствуйте,

программно необходимо читать нажата ли кнопка и если да, то как долго удерживается нажатие (есоли 3сек., то выполнить одно, если 5 сек. то другое).

Есть библиотека gpio от производителя чипа с функциями чтения/записи пина и пр. (вообще это нужно сделать под линуксом, на данном этапе это будет демон, в дальнейшем хотелось бы перенести в ядро), но я решил запостить здесь, потому как меня интересует алгоритм.

Т.е. языком псевдокода как это будет выглядеть? Очевидно, нужно проверять состояние пина, и если кнопка нажата, то запускать таймер - но возникает проблема, как отслеживать два разных тайминга - 3сек и 5 ?


Буду очень признателен за идеи и советы !
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
sergeeff
сообщение Aug 20 2010, 09:29
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Классная программа:

Код
/************************************************************************/
/*                                                                      */
/*                      Debouncing 8 Keys                               */
/*                      Sampling 4 Times                                */
/*                      With Repeat Function                            */
/*                                                                      */
/*              Author: Peter Dannegger                                 */
/*                      danni@specs.de                                  */
/*                                                                      */
/************************************************************************/

#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#ifndef F_CPU
#define F_CPU           1000000                   // processor clock frequency
#warning kein F_CPU definiert
#endif

#define KEY_DDR         DDRB
#define KEY_PORT        PORTB
#define KEY_PIN         PINB
#define KEY0            0
#define KEY1            1
#define KEY2            2
#define ALL_KEYS        (1<<KEY0 | 1<<KEY1 | 1<<KEY2)

#define REPEAT_MASK     (1<<KEY1 | 1<<KEY2)       // repeat: key1, key2
#define REPEAT_START    50                        // after 500ms
#define REPEAT_NEXT     20                        // every 200ms

#define LED_DDR         DDRA
#define LED_PORT        PORTA
#define LED0            0
#define LED1            1
#define LED2            2

volatile uint8_t key_state;                                // debounced and inverted key state:
                                                  // bit = 1: key pressed
volatile uint8_t key_press;                                // key press detect

volatile uint8_t key_rpt;                                  // key long press and repeat


ISR( TIMER0_OVF_vect )                            // every 10ms
{
  static uint8_t ct0, ct1, rpt;
  uint8_t i;

  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms

  i = key_state ^ ~KEY_PIN;                       // key changed ?
  ct0 = ~( ct0 & i );                             // reset or count ct0
  ct1 = ct0 ^ (ct1 & i);                          // reset or count ct1
  i &= ct0 & ct1;                                 // count until roll over ?
  key_state ^= i;                                 // then toggle debounced state
  key_press |= key_state & i;                     // 0->1: key press detect

  if( (key_state & REPEAT_MASK) == 0 )            // check repeat function
     rpt = REPEAT_START;                          // start delay
  if( --rpt == 0 ){
    rpt = REPEAT_NEXT;                            // repeat delay
    key_rpt |= key_state & REPEAT_MASK;
  }
}

///////////////////////////////////////////////////////////////////
//
// check if a key has been pressed. Each pressed key is reported
// only once
//
uint8_t get_key_press( uint8_t key_mask )
{
  cli();                                          // read and clear atomic !
  key_mask &= key_press;                          // read key(s)
  key_press ^= key_mask;                          // clear key(s)
  sei();
  return key_mask;
}

///////////////////////////////////////////////////////////////////
//
// check if a key has been pressed long enough such that the
// key repeat functionality kicks in. After a small setup delay
// the key is reported beeing pressed in subsequent calls
// to this function. This simulates the user repeatedly
// pressing and releasing the key.
//
uint8_t get_key_rpt( uint8_t key_mask )
{
  cli();                                          // read and clear atomic !
  key_mask &= key_rpt;                            // read key(s)
  key_rpt ^= key_mask;                            // clear key(s)
  sei();
  return key_mask;
}

///////////////////////////////////////////////////////////////////
//
uint8_t get_key_short( uint8_t key_mask )
{
  cli();                                          // read key state and key press atomic !
  return get_key_press( ~key_state & key_mask );
}

///////////////////////////////////////////////////////////////////
//
uint8_t get_key_long( uint8_t key_mask )
{
  return get_key_press( get_key_rpt( key_mask ));
}

int main( void )
{
  KEY_DDR &= ~ALL_KEYS;                // konfigure key port for input
  KEY_PORT |= ALL_KEYS;                // and turn on pull up resistors

  TCCR0 = (1<<CS02)|(1<<CS00);            // divide by 1024
  TIMSK |= 1<<TOIE0;                // enable timer interrupt

  LED_PORT = 0xFF;
  LED_DDR = 0xFF;                    

  sei();

  while(1){
    if( get_key_short( 1<<KEY1 ))
      LED_PORT ^= 1<<LED1;

    if( get_key_long( 1<<KEY1 ))
      LED_PORT ^= 1<<LED2;

                                                  // single press and repeat

    if( get_key_press( 1<<KEY2 ) || get_key_rpt( 1<<KEY2 )){
      uint8_t i = LED_PORT;

      i = (i & 0x07) | ((i << 1) & 0xF0);
      if( i < 0xF0 )
        i |= 0x08;
      LED_PORT = i;      
    }
  }
}
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Aug 20 2010, 10:53
Сообщение #3


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(sergeeff @ Aug 20 2010, 13:29) *
Классная программа:
На любителя...
ИМХО. Идеологически более правильно использовать буфер клавиатуры и всё свести к стандартным getc putc.
PS: и через этот же буфер можно постить и все остальные сообщения, а не только коды клавиатуры...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Aug 20 2010, 10:58
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(demiurg_spb @ Aug 20 2010, 13:53) *
На любителя...
ИМХО. Идеологически более правильно использовать буфер клавиатуры и всё свести к стандартнм getch() putch(x).
PS: и через этот же буфер можно постить и сообщения...


Автора интересовало различие короткое/длинное нажатие на кнопку. В приведенном примере все это и реализовано. Чего не может быть в getch() putch(x).
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- romez777   нажатие кнопки   Aug 19 2010, 08:35
- - DpInRock   А они разве разные? Сначала - событие 3 сек. А уж ...   Aug 19 2010, 08:46
- - rezident   Не нужно запускать/останавливать таймер. Таймер до...   Aug 19 2010, 15:46
|- - Demeny   Цитата(rezident @ Aug 19 2010, 19:46) А с...   Sep 8 2010, 13:21
|- - rezident   Цитата(Demeny @ Sep 8 2010, 19:21) К сожа...   Sep 8 2010, 19:19
|- - Demeny   Цитата(rezident @ Sep 8 2010, 23:19) Ну и...   Sep 9 2010, 11:49
|- - rezident   Цитата(Demeny @ Sep 9 2010, 17:49) Тогда ...   Sep 9 2010, 12:20
|- - Demeny   Цитата(rezident @ Sep 9 2010, 16:20) Не н...   Sep 10 2010, 06:35
|- - rezident   Цитата(Demeny @ Sep 10 2010, 12:35) Ваш к...   Sep 10 2010, 12:51
- - Kuzmi4   2 rezident а как же переполнения таймера ? По моем...   Aug 19 2010, 15:49
|- - rezident   Цитата(Kuzmi4 @ Aug 19 2010, 21:49) а как...   Aug 19 2010, 16:15
|- - romez777   rezident, большое спасибо. Мне сейчас подумалось,...   Aug 20 2010, 04:13
- - 777777   Цитата(romez777 @ Aug 19 2010, 12:35) про...   Aug 20 2010, 09:06
||- - rezident   Цитата(sergeeff @ Aug 20 2010, 16:58) Авт...   Aug 20 2010, 11:52
|- - 777777   Цитата(demiurg_spb @ Aug 20 2010, 14:53) ...   Aug 20 2010, 11:04
|- - demiurg_spb   Можно и не ждать: получил 0 - буфер пуст... Цитат...   Aug 20 2010, 11:15
- - sergeeff   Код в студию!   Aug 20 2010, 11:21
|- - demiurg_spb   Код не отдам! А если есть конкретные вопросы -...   Aug 20 2010, 11:45
- - -JonnS-   Прилагаю вариант реализации кот. почти повторяет а...   Aug 22 2010, 17:53
- - Ivan Kuznetzov   а если я хочу помимо всего вышеперечисленного отсл...   Aug 25 2010, 18:14
|- - demiurg_spb   Достаточно одну кнопку удерживать в момент включен...   Aug 25 2010, 18:39
||- - Ivan Kuznetzov   Цитата(demiurg_spb @ Aug 25 2010, 23:39) ...   Aug 27 2010, 14:56
||- - demiurg_spb   Ну пусть сядет. При этом надо чтобы ещё в этот мом...   Aug 30 2010, 10:02
|- - rezident   Цитата(Ivan Kuznetzov @ Aug 26 2010, 00:1...   Aug 25 2010, 18:43
||- - xemul   Цитата(rezident @ Aug 25 2010, 22:43) ......   Aug 25 2010, 20:42
||- - rezident   Цитата(xemul @ Aug 26 2010, 02:42) Лучше ...   Aug 26 2010, 08:51
||- - xemul   Цитата(rezident @ Aug 26 2010, 12:51) Луч...   Aug 26 2010, 12:27
||- - rezident   Цитата(xemul @ Aug 26 2010, 18:27) Т.е. л...   Aug 26 2010, 12:52
||- - xemul   Цитата(rezident @ Aug 26 2010, 16:52) Дык...   Aug 26 2010, 14:21
||- - MrYuran   Цитата(xemul @ Aug 26 2010, 18:21) В прер...   Sep 8 2010, 13:28
|- - 777777   Цитата(Ivan Kuznetzov @ Aug 25 2010, 22:1...   Aug 26 2010, 05:18
- - XVR   ЦитатаЗачем нужно 5с событие, которое произошло по...   Sep 9 2010, 06:45
- - MrYuran   По "отжатию" не стоит работать ещё и пот...   Sep 9 2010, 12:40
- - ILYAUL   Цитата(MrYuran @ Sep 9 2010, 16:40) По ...   Sep 9 2010, 16:27
- - AHTOXA   Цитата(ILYAUL @ Sep 9 2010, 22:27) Странн...   Sep 9 2010, 17:56
|- - ILYAUL   Цитата(AHTOXA @ Sep 9 2010, 21:56) Так эт...   Sep 9 2010, 21:29
|- - MrYuran   Цитата(ILYAUL @ Sep 10 2010, 01:29) Вы по...   Sep 10 2010, 06:59
|- - AHTOXA   Цитата(MrYuran @ Sep 10 2010, 12:59) При ...   Sep 10 2010, 08:42
|- - MrYuran   Цитата(AHTOXA @ Sep 10 2010, 12:42) Видим...   Sep 10 2010, 09:00
|- - AHTOXA   Оно там не всегда обрабатывается, а только из режи...   Sep 10 2010, 09:22
- - rezident   Цитата(ILYAUL @ Sep 9 2010, 22:27) Странн...   Sep 9 2010, 22:27
- - ILYAUL   Цитата(rezident @ Sep 10 2010, 02:27) Еру...   Sep 10 2010, 08:33
- - kolisnichenko_r   Цитата(ILYAUL @ Sep 10 2010, 11:33) Я же ...   Sep 14 2010, 08:33
- - ILYAUL   Цитата(kolisnichenko_r @ Sep 14 2010, 12...   Sep 14 2010, 16:37
- - AHTOXA   Цитата(ILYAUL @ Sep 14 2010, 22:37) Юрий ...   Sep 14 2010, 16:52
- - ILYAUL   Цитата(AHTOXA @ Sep 14 2010, 20:52) Да уж...   Sep 14 2010, 20:44
- - AHTOXA   Так там про мышь, а это совсем другое дело. А про ...   Sep 15 2010, 03:51
- - ILYAUL   Цитата(AHTOXA @ Sep 15 2010, 07:51) ... А...   Sep 15 2010, 05:24


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

 


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


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