Forum: Mikrocontroller und Digitale Elektronik Tasterentprellung 8-fach


von Achim (Gast)


Lesenswert?

Hallo Gemeinde
Den Code von Peter zur Entprellung nutze ich in verschiedenen 
Programmen. Bisher max mit 4 Tasten. Jetzt brauche ich ein Stück für 6 
Tasten. In dem Programm von Peter steht:
1
#define KEY_PIN    PINB
2
#define KEY0    0
3
#define KEY1    1
4
#define KEY2    2
mir ist leider nicht klar, wie ich die anderen Tasten nehme?
Einfach
1
#define KEY_PIN    PINB
2
#define KEY0    0
3
#define KEY1    1
4
#define KEY2    2
5
#define KEY3    3
6
#define KEY4    4
7
#define KEY5    5
achim

von Karl H. (kbuchegg)


Lesenswert?

Achim schrieb:

> mir ist leider nicht klar, wie ich die anderen Tasten nehme?
> Einfach

Yep.

Die Keys noch in das ALL_KEYS Makro mit aufnehmen (damit die 
Portinitialisierung klappt) und überlegen ob und auf welchen Tasten du 
einen Autorepeat haben willst und das wars dann auch schon.

Und: gib deinen KEYS schöne Namen. Zb KEY_RECHTS oder KEY_LINKS oder 
KEY_ENTER oder was auch immer die Keys in deinem Programm für eine 
Bedeutung haben. Das liest sich dann viel besser, wenn da steht
1
   if( get_key_press( 1 << KEY_SELECT ) )
2
     ....

als wie wenn da von einem 'abstrakten' KEY0 die Rede ist.

von Uwe (Gast)


Lesenswert?

Hallo Achim,

nun das lesen des Codes würde Dir Auskunft geben.

Das Define bzw. Label KEY0 benennt nur die Bit-Nummer, also bei Dir PB0, 
wenn man 8 Taster nutzen möchte, müssen diese natürlich an einem PORT, 
hier PortB, liegen.

Wenn Du die Taste später auswerten möchtest, benötigst Du die Bit-Maske, 
also #define KEY0_MASK (1<<(KEY0)) .

von Achim (Gast)


Lesenswert?

- Die Taster werden wie oben bezeichnet,
- Alle Taster müssen am gleichen Port liegen
- noch ändern:
1
#define REPEAT_MASK  (1<<KEY1^1<<KEY2)  // repeat: key1, key2

in
1
#define REPEAT_MASK  (1<<KEY1^1<<KEY2^1<<KEY3^1<<KEY4^1<<KEY5^1<<KEY6)  // repeat: key1 bis key6
wenn das richtig ist, ist es sau einfach.
Da hab ich was gutes von dir gelernt.
achim

von Karl H. (kbuchegg)


Lesenswert?

Achim schrieb:

> wenn das richtig ist, ist es sau einfach.

Es ist 'sau-einfach'.

Das her
1
#define KEY_DDR         DDRB
2
#define KEY_PORT        PORTB
3
#define KEY_PIN         PINB
4
#define KEY0            0
5
#define KEY1            1
6
#define KEY2            2
7
#define ALL_KEYS        (1<<KEY0 | 1<<KEY1 | 1<<KEY2)
8
 
9
#define REPEAT_MASK     (1<<KEY1 | 1<<KEY2)       // repeat: key1, key2
sind die #define, die du nach Schema änderst.
Die Namen der KEYs, also KEY0, KEY1 etc. kannst du nach Gutdünken 
ändern. Ob da
1
#define KEY1         1
oder
1
#define KEY_LEFT     1
steht, spielt für den Entprellcode keine Rolle. Du musst dann eben auch 
hier
1
#define ALL_KEYS   (1<<KEY_RIGHT | 1<<KEY_LEFT) | ...
bzw. wenn du es brauchst hier
1
#define REPEAT_MASK (1<<KEY_LEFT)
den entsprechenden Namen benutzen.

Auch das hier
1
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms
in der ISR ist nicht kritisch. Hast du in deinem Programm sowieso einen 
Timer für andere Zwecke laufen, der eine ISR in Zeitabständen von 5ms 
bis ca 50ms aufruft, dann passt das. Die 10ms sind nicht fakultativ, 
dann fliegt dieses Nachladen des Timer Registers halt einfach raus. Bei 
ISR Zeiten im genannten Bereich funktioniert die Entprellung immer noch 
wunderbar. Allenfalls muss man die REPEAT Zeiten dann ein wenig 
anpassen, aber das ist ja kein Beinbruch.

Und ja. Das wars. Um die PeDa Entprellung zu übernehmen, kopiert man 
einfach den Code aus der ISR in seine eigene ISR wenn man schon eine 
hat. Hat man noch keinen Timer im Einsatz, dann kopiert man auch den 
Teil mit. Die restlichen Funktionen, sowie die Variablen
1
volatile uint8_t key_state;                                // debounced and inverted key state:
2
                                                  // bit = 1: key pressed
3
volatile uint8_t key_press;                                // key press detect
4
 
5
volatile uint8_t key_rpt;                                  // key long press and repeat
werden übernommen. Die #define Sektion wird übernommen und an die 
vorhandene Hardware angepasst. In main() kommt am Anfang noch die 
Port-Einstellung
1
int main()
2
{
3
  // Configure debouncing routines
4
  KEY_DDR &= ~ALL_KEYS;                // configure key port for input
5
  KEY_PORT |= ALL_KEYS;                // and turn on pull up resistors
6
7
...
rein und gegebenenfalls noch die Timer Initialisierung, so man nicht 
sowieso einen Timer im System hat.

Und das wars. Alles in allem dauert das keine 10 Minuten und du hast 
eine erstklassige Tastenerkennung und Entprellung am laufen.
Die regelmässigen Forumsteilnehmer preisen diese Funktion ja nicht 
umsonst an, wie geschnittenes Brot.


> Da hab ich was gutes von dir gelernt.
> achim

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.