In sehr vielen Schaltungen/Projekten werden Taster eingesetzt um bei deren Betätigung bestimmte Vorgänge auszulösen. Man nutzt sie um bei Tastendruck, z.B. ein Licht einzuschalten und es beim nächsten Tastendruck wieder auszuschalten. Leider haben Taster den unangenehmen Nebeneffekt, dass sie bei Betätigung mehrfach schließen oder öffnen können. Dieses Verhalten kann auch als Kontakt-"Federn" beschrieben werden. Nicht immer führt der Effekt zu Störungen. Möchte man aber in einem Programm beispielsweise die Taster Betätigungen zählen, führt das mehrfache Toggeln der Zustände zu einer starken Ergebnisverfälschung.



Abb.: Einschwingvorgang der Taster; Quelle: BBS2 Wolfsburg

Das Bild zeigt den Einschwingvorgang eines Tasters (hier mit internem Pull-Up-Widerstand -> Öffner Logik). Es ist gut zu erkennen, dass während des Einschwingvorganges der logische Zustand mehrfach zwischen High und Low toggelt.


Beispiel: In diesem Beispiel wird ein Taster als Impulsquelle für einen Zähler genutzt. Da er nicht entprellt ist, kann es beim Betätigen zu Mehrfachzählungen kommen, wie im folgenden Video zu sehen ist.



Es muss also eine Lösung gefunden werden, das Toggeln zu blockieren. Die Lösung lautet Tasterentprellung, die per Hardware oder per Software erfolgen kann. Beide Lösungen sind als gleichwertig anzusehen.


Taster entprellen per Hardware

Zum Entprellen per Hardware gibt es mehrere Ansätze, zwei davon werden im Folgenden gezeigt:

1. Nutzung eines Widerstandes, zu dem ein Kondensator parallel geschaltet wird:


Theorie

Abb.: Parallelschaltung aus R und C; Quelle: BBS2 Wolfsburg

Zeitlicher Entprellverlauf (Simulation):

Zeitverlauf

Abb.: Simulation des Entprellverlaufs; Quelle: BBS2 Wolfsburg

Legende: rote Linie = prellender Taster

               grüne Linie = Eingang des µC (entprellt)

               gelbe Linie = High-Pegel (2,6 V)

               grüne Line = Low-Pegel (2,1 V)


Funktion:

Anders als bei Variante 2, kann die Spannung hier springen. Ist der Taster unbetätigt, liegen über dem Kondensator 5V an (High-Pegel). Wird der Taster betätigt, entlädt sich der Kondensator über den Widerstand bis er entladen ist (Low-Pegel). Während des Prellens, wird der Kondensator wechselhaft, sprunghaft aufgeladen und langsam entladen. Dadurch kommt beim Prellen ein High-Pegel zustande (die grüne Linie liegt über der der gelben).

In der Simulation wurde für den Widerstand 10 kOhm und für den Kondensator 1000 nF gewählt.



2. Verwendung eines Kondensators und zwei Widerständen:

Theorie 2

Abb.: Verwendung von 2 Widerständen; Quelle: BBS2 Wolfsburg

Zeitlicher Entprellverlauf (Simulation):

Zeitverlauf

Abb.: Simulation des Entprellverlaufs mit 2 Widerständen; Quelle: BBS2 Wolfsburg

Legende: grüne Linie = prellender Taster

               gelbe Linie = Eingang des µC (entprellt)

               rote Linie = High-Pegel (2,6 V)

               blaue Line = Low-Pegel (2,1 V)


Funktion:

Entprell-Variante 2 bildet einen RC-Tiefpass. Der Kondensator lädt oder entlädt sich je nach Schalterstellung. Der Tiefpass verhindert, dass die Spannung über dem Kondensator nicht von Pegel zu Pegel springen kann. Ist der Taster (hier ein Öffner) unbetätigt, lädt sich der Kondensator allmälig über die beiden Widerstände auf 5 V auf. Der Pegel liegt über der roten Linie, daher liegt am Eingang des µC High an. Wird der Taster betätigt entlädt sich der Kondensator langsam und vollständig über die Widerstände. Während des Tasterprellens alterniert der Kondensator zwischen kurzseitigem, langsamen Laden und Entladen. Dabei kann die Spannung am Kondensator nicht springen sondern folgt der typischen Lade-/Entladekurve (gelbe Linie). Liegt die gelbe Linie über der Roten, liegt am Mikrocontroller ein High-Pegel an. Liegt sie unter der Blauen, liegt ein Low-Pegel am µC an. Am zeitlichen Ablauf lässt sich erkennen, dass pro Betätigung des Tasters nur noch ein Pegelwechsel zustande kommt. Somit liegt der Eingang des µC nicht am alternierenden Taster-Signal.

In der Simulation, wurde für die Widerstände im horizontalen Zweig 1 kOhm, für den im senkrechtem Zweig 6 kOhm und für den Kondensator 2000 nF gewählt.


Beispiel zur Variante 1.:

Verwendet wird wie auch im vorherig gezeigtem Video eine 7-Segmentanzeige, um den Zählerstand darzustellen. Die 7-Segmentanzeige wurde mit 330 Ohm-Vorwiderständen ausgestattet. Am Taster wird zum Entprellen ein 330 Ohm-Widerstand verwendet, zu dem ein Kondensator mit 100 µF parallel geschaltet ist.


Abb.: Schaltung zum Zählen der Tasterdrücke; Quelle: BBS2 Wolfsburg

Quellcode:

Zum Auswerten eines Tastendruckes wird ein externer Interrupt verwendet. Dessen Aufbau wird im Kapitel Interrupt näher beschrieben.


#include <avr/io.h>
#define F_CPU 16000000UL
#include <avr/interrupt.h>
volatile int zaehler;                                                                               // fluechtige Variable zum Zählen in der ISR

ISR(INT1_vect)                                                                                     // Interrupt Service Routine - positive Flanke an Pin 3
{
    zaehler++;
}

int main(void)
{
    DDRD &= ~(1<<3);                                                                               // Pin 3 als Eingang definiert
    DDRD |= (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0);            // Pin 0,1,2,4,5,6,7 als Ausgaenge definiert                                        
    
   
    
    EICRA |= (1<<ISC11) | (1<<ISC10);                                                              // Interrupt wird bei steigender Flanke an Pin 3 (Taster) geworfen                                         
    EIMSK |= (1<<INT1);                                                                            // Externer Interrupt an Pin 3 (INT1) wird zugelassen
    sei();                                                                                         // Erlaubt Interrupts
    
    while (1)
    {
            switch(zaehler)                                                                        // Ansteuerung der 7 Segmentanzeige
            {
                case 0:
                PORTD = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 7);
                break;
                case 1:
                PORTD = (1 << 1) | (1 << 2);
                break;
                case 2:
                PORTD = (1 << 0) | (1 << 1)  | (1 << 4) | (1 << 5) | (1 << 6);
                break;
                case 3:
                PORTD = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)  | (1 << 6);
                break;
                case 4:
                PORTD = (1 << 1) | (1 << 2)   | (1 << 7) | ( 1 << 6);
                break;
                case 5:
                PORTD = (1 << 0)  | (1 << 2) | (1 << 4) | (1 << 7) | ( 1 << 6);
                break;
                case 6:
                PORTD = (1 << 0)  | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 7) | ( 1 << 6);
                break;
                case 7:
                PORTD = (1 << 0) | (1 << 1) | (1 << 2);
                break;
                case 8:
                PORTD = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 7) | ( 1 << 6);
                break;
                case 9:
                PORTD = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 4)  | (1 << 7) | ( 1 << 6);
                break;
                default:
                zaehler = 0;
                break;
            }
    }
}


Das Ergebnis sieht wie folgt aus:

Zuletzt geändert: Montag, 28. Februar 2022, 14:27