get_key_long get_key_short Frage

Gast #2156619
Lesenswert?

Hallo,

ich stehe vor folgendem Problem:
Ich muss einen Unterschied machen, ob eine Taste mind. 2 Sekunden 
gedrückt wurde oder weniger als 2 Sekunden.
Kann ich das mit Peter Daneggers Entprellung machen mit den Funktionen 
get_key_long und get_key_short:
1
/************************************************************************/
2
/*                                                                      */
3
/*                      Debouncing 8 Keys                               */
4
/*                      Sampling 4 Times                                */
5
/*                      With Repeat Function                            */
6
/*                                                                      */
7
/*              Author: Peter Dannegger                                 */
8
/*                      danni@specs.de                                  */
9
/*                                                                      */
10
/************************************************************************/
11
 
12
#include <stdint.h>
13
#include <avr/io.h>
14
#include <avr/interrupt.h>
15
 
16
#ifndef F_CPU
17
#define F_CPU           1000000                   // processor clock frequency
18
#warning kein F_CPU definiert
19
#endif
20
 
21
#define KEY_DDR         DDRB
22
#define KEY_PORT        PORTB
23
#define KEY_PIN         PINB
24
#define KEY0            0
25
#define KEY1            1
26
#define KEY2            2
27
#define ALL_KEYS        (1<<KEY0 | 1<<KEY1 | 1<<KEY2)
28
 
29
#define REPEAT_MASK     (1<<KEY1 | 1<<KEY2)       // repeat: key1, key2
30
#define REPEAT_START    50                        // after 500ms
31
#define REPEAT_NEXT     20                        // every 200ms
32
 
33
#define LED_DDR         DDRA
34
#define LED_PORT        PORTA
35
#define LED0            0
36
#define LED1            1
37
#define LED2            2
38
 
39
volatile uint8_t key_state;                                // debounced and inverted key state:
40
                                                  // bit = 1: key pressed
41
volatile uint8_t key_press;                                // key press detect
42
 
43
volatile uint8_t key_rpt;                                  // key long press and repeat
44
 
45
 
46
ISR( TIMER0_OVF_vect )                            // every 10ms
47
{
48
  static uint8_t ct0, ct1, rpt;
49
  uint8_t i;
50
 
51
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms
52
 
53
  i = key_state ^ ~KEY_PIN;                       // key changed ?
54
  ct0 = ~( ct0 & i );                             // reset or count ct0
55
  ct1 = ct0 ^ (ct1 & i);                          // reset or count ct1
56
  i &= ct0 & ct1;                                 // count until roll over ?
57
  key_state ^= i;                                 // then toggle debounced state
58
  key_press |= key_state & i;                     // 0->1: key press detect
59
 
60
  if( (key_state & REPEAT_MASK) == 0 )            // check repeat function
61
     rpt = REPEAT_START;                          // start delay
62
  if( --rpt == 0 ){
63
    rpt = REPEAT_NEXT;                            // repeat delay
64
    key_rpt |= key_state & REPEAT_MASK;
65
  }
66
}
67
 
68
///////////////////////////////////////////////////////////////////
69
//
70
// check if a key has been pressed. Each pressed key is reported
71
// only once
72
//
73
uint8_t get_key_press( uint8_t key_mask )
74
{
75
  cli();                                          // read and clear atomic !
76
  key_mask &= key_press;                          // read key(s)
77
  key_press ^= key_mask;                          // clear key(s)
78
  sei();
79
  return key_mask;
80
}
81
 
82
///////////////////////////////////////////////////////////////////
83
//
84
// check if a key has been pressed long enough such that the
85
// key repeat functionality kicks in. After a small setup delay
86
// the key is reported beeing pressed in subsequent calls
87
// to this function. This simulates the user repeatedly
88
// pressing and releasing the key.
89
//
90
uint8_t get_key_rpt( uint8_t key_mask )
91
{
92
  cli();                                          // read and clear atomic !
93
  key_mask &= key_rpt;                            // read key(s)
94
  key_rpt ^= key_mask;                            // clear key(s)
95
  sei();
96
  return key_mask;
97
}
98
 
99
///////////////////////////////////////////////////////////////////
100
//
101
uint8_t get_key_short( uint8_t key_mask )
102
{
103
  cli();                                          // read key state and key press atomic !
104
  return get_key_press( ~key_state & key_mask );
105
}
106
 
107
///////////////////////////////////////////////////////////////////
108
//
109
uint8_t get_key_long( uint8_t key_mask )
110
{
111
  return get_key_press( get_key_rpt( key_mask ));
112
}
113
 
114
int main( void )
115
{
116
  LED_PORT = 0xFF;
117
  LED_DDR = 0xFF;                     
118
 
119
  // Configure debouncing routines
120
  KEY_DDR &= ~ALL_KEYS;                // configure key port for input
121
  KEY_PORT |= ALL_KEYS;                // and turn on pull up resistors
122
 
123
  TCCR0 = (1<<CS02)|(1<<CS00);         // divide by 1024
124
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms
125
  TIMSK |= 1<<TOIE0;                   // enable timer interrupt
126
 
127
  sei();
128
 
129
  while(1){
130
    if( get_key_short( 1<<KEY1 ))
131
      LED_PORT ^= 1<<LED1;
132
 
133
    if( get_key_long( 1<<KEY1 ))
134
      LED_PORT ^= 1<<LED2;
135
 
136
    // single press and repeat
137
 
138
    if( get_key_press( 1<<KEY2 ) || get_key_rpt( 1<<KEY2 )){
139
      uint8_t i = LED_PORT;
140
 
141
      i = (i & 0x07) | ((i << 1) & 0xF0);
142
      if( i < 0xF0 )
143
        i |= 0x08;
144
      LED_PORT = i;      
145
    }
146
  }
147
}

Wenn ja, wie stelle ich die Zeit ein und wie rufe ich die Funktionen 
auf?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren