Forum: Mikrocontroller und Digitale Elektronik get_key_long() von Peter Dannegger


von Alex K. (derheld2k1)


Lesenswert?

Hallo zusammen,

ich habe schon lange zu meinem Problem hier gesucht, aber dieses Thema 
zu den Entprell Routinen von P.Dannegger wurde noch nicht angesprochen.

Ich schaffe es nicht die Funktion get_key_long() zum Funktionieren zu 
überreden.

Meine Defines:
1
#define KEY_DDR         DDRA
2
#define KEY_PORT        PORTA
3
#define KEY_PIN         PINA
4
#define DIR_INC_KEY     0
5
#define DIR_DEC_KEY     1
6
#define SETAXIS_KEY     2
7
#define GOTO_REF_KEY    3
8
#define ENCODER_KEY     4
9
#define ALL_KEYS        (1<<DIR_INC_KEY | 1<<DIR_DEC_KEY | 1<<SETAXIS_KEY | 1<<GOTO_REF_KEY | 1<<ENCODER_KEY)
10
 
11
#define REPEAT_MASK     (1<<ENCODER_KEY | 1<<DIR_INC_KEY | 1<<DIR_DEC_KEY)       // repeat: key1, key2
12
#define REPEAT_START    50                        // after 500ms
13
#define REPEAT_NEXT     20                        // every 200ms

Es soll get_key_long() mit dem ENCODER_KEY klappen.
Dazu muss ich diesen ja erstmal in die REPEAT_MASK eintragen, soweit 
richtig?

Nun meine erste Frage: Wo stelle ich die Zeit ein nach der ein 
Tastendruck als "long" gewertet wird.

In main() sieht das ganze bei mir so aus:
1
int main() 
2
{
3
  // initzeug
4
  while(1) {
5
    if( get_key_short( 1<<ENCODER_KEY )) {
6
      foo();
7
    }
8
    
9
    if( get_key_long( 1<<ENCODER_KEY )) {
10
      bar();    
11
    }
12
  }
13
}

Habe ich hier irgendwo einen Denkfehler?
Ich kann den Taster solange drücken wie ich will, bar() wird nie 
aufgerufen.

Danke schonmal,
Alex

von Peter D. (peda)


Lesenswert?

Keine Schnipsel und erst recht keinen Fantasiecode.
Sondern den getesteten compilierbaren Code als Anhang!


Peter

von Alex K. (derheld2k1)


Angehängte Dateien:

Lesenswert?

gekürzter Code mit reproduzierbarem Fehler im Anhang.

von Bernhard M. (boregard)


Lesenswert?

Muss man nicht immer get_key_long() vor get_key_short() aufrufen?
Andersherum gehts glaube ich nicht.

von Uwe (de0508)


Lesenswert?

Bernhard M. schrieb:
> Muss man nicht immer get_key_long() vor get_key_short() aufrufen?
> Andersherum gehts glaube ich nicht.

Glauben ist nicht wissen, was soll also der Beitrag.

Ich verwende die Abfragen nacheinande und ohne Probleme.
1
      // Auslesen der Encoder Zustände
2
      // alle weiteren Funktionen greifen auf diese Daten in |encoder| zu.
3
4
      ENCODER_DATA(direction)       = ENCODER_READ();
5
      ENCODER_DATA(key_short_press) = get_key_short( _BV(KEY_ENCODER_BIT) );  // beide Key-Ereignisse können nicht zusammen auftreten
6
      ENCODER_DATA(key_long_press)  = get_key_long ( _BV(KEY_ENCODER_BIT) );  // beide Key-Ereignisse können nicht zusammen auftreten

von Peter D. (peda)


Lesenswert?

1
#ifdef ACTIVE_HIGH
2
  key_rpt = ~(key_rpt | (key_state & REPEAT_MASK));
3
#else
4
    key_rpt |= key_state & REPEAT_MASK;
5
#endif

Wer hat sich denn sowas ausgedacht?

Ob Taste gegen GND oder VCC, wird nur beim Einlesen des Input-Ports 
unterschieden, nirgendwo anders!


Peter

von Alex K. (derheld2k1)


Lesenswert?

> Ob Taste gegen GND oder VCC, wird nur beim Einlesen des Input-Ports
> unterschieden, nirgendwo anders!

Also ist diese Stelle in der ISR korrekt?
1
#ifdef ACTIVE_HIGH
2
  i = key_state ^ KEY_PIN;                        // key changed ?
3
#else
4
  i = key_state ^ ~KEY_PIN;                       // key changed ?
5
#endif

Dann werde ich
1
#ifdef ACTIVE_HIGH
2
  key_rpt = ~(key_rpt | (key_state & REPEAT_MASK));
3
#else
4
    key_rpt |= key_state & REPEAT_MASK;
5
#endif

wieder durch
1
    key_rpt |= key_state & REPEAT_MASK;
ersetzen.

Obs dann klappt weiß ich erst wenn ich wieder im Keller sitze.

von Alex K. (derheld2k1)


Lesenswert?

Hat geklappt, Danke !

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.