Anschließen eines Tasters

Xilinx Spartan3

In diesem Artikel zeige ich euch wie ihr einen Taster an euer FPGA oder CPLD anschließen und entprellen könnt, damit eure Logikschaltung auf Tastendrücke reagieren kann.
Die Funktionsweise der Entprellschaltung ist ähnlich der Schaltung eines IC welches speziell zum Entprellen von Tastern entwickelt wurde, dem MAX6817.

-> Was ist überhaupt Prellen?:

Bedingt durch den Aufbau von Tastern kommt es vor, dass ein Taster beim Betätigen nicht direkt komplett betätigt wird, sondern im Inneren noch kurz hin- und her federt.
Für schnellen Schaltungen (wie in einem FPGA) sieht dieses Federn, was durchaus mehrere Millisekunden dauern kann, aus wie ein mehrmaliges Betätigen des Tasters.
So nimmt das FPGA dann mehrere Tastendrücke wahr, obwohl der Benutzer den Taster nur einmal betätigt hat.
Dies sieht dann z.B. so aus:

Prellen_Skizze
Ein einfacher Weg dieses Prellen weg zu bekommen ist die Verwendung eines RC-Gliedes. Das RC-Glied benötigt eine gewisse Zeit um den internen Kondensator zu laden.
Der Ladevorgang findet aber nur statt, wenn der Taster gerade geschlossen ist. Je nach Kapazität des Kondensators dauert der Ladevorgang dann unterschiedlich lange und nachdem der Kondensator geladen ist (und der Taster noch gedrückt ist) führt der Kondensator den selben Pegel wie der Taster wenn er betätigt wurde.
Die Schaltung kann z.B. so aussehen:

Prellen_RC
Bei dieser Schaltung werden zusätzliche Bauelemente benötigt, was bei kleinen Leiterkarten eventuell Problematisch ist. Aus diesem Grund wird das Entprellen in das FPGA verlagert.
Da das FPGA keinen Kondensator bereit stellen kann, muss das Entprellen auf andere Weise geschehen…

-> Entprellen im FPGA:

Um den Taster zu Entprellen wird ein Taktsignal benötigt, welches bei den meisten FPGA-Schaltungen ohnehin schon vorhanden sein sollte.
Mit Hilfe dieses Taktsignals zähle ich dann einfach wie viele Taktzyklen der I/O einen High- bzw. Lowpegel führt. Sobald eine bestimmte Anzahl an Zyklen überschritten wurde kann ich annehmen, dass der Taster sicher geschaltet hat.
Den ganzen Vorgang habe ich mal in einer Skizze deutlich gemacht…

Entprellen_Skizze
Diese Grundidee muss nun nur noch in eine Schaltung umgewandelt werden…

-> Schritt 1. Die Taktquelle:

Als erstes habe ich mir Gedanken um die Taktquelle gemacht. Mein Board ist mit einer 8MHz Taktquelle ausgestattet. Wenn man von einer typischen Prellzeit von 1-10ms ausgeht wird man schnell feststellen, dass 8MHz für diese Zeit doch immens viel sind, da der Counter dann bis 80000 zählen muss um die 10ms Prellen zu überbrücken.
Aus diesem Grund habe ich ein VHDL-Modul entworfen, welches mir einen Takt auf einen beliebigen anderen Takt runterteilt:

Das Modul besitzt einen Clock-Eingang, einen Clock-Ausgang und einen Eingang wo das Teilungsverhältnis angegeben wird.
Das Modul macht im Grunde nichts anderes als bei jeder positiven Taktflanke einen Zähler hoch zu zählen und bei erreichen des Zählerstandes, der in dem Signal Div gespeichert ist, wird der Clock-Ausgang umgeschaltet.
Durch eine entsprechende Instantiierung des Moduls und einen geeigneten Teiler für den Takt erzeuge ich mir jetzt einen 1kHz Takt, welchen ich mir an einem Pin ausgeben lassen kann:

Ein Test mit dem Oszilloskop zeigt das der Takt auch richtig erzeugt wird:

Prellen(1)
Damit wäre die Taktquelle für meine Debounce-Schaltung schon mal erzeugt.

-> Schritt 2. Die Debounce-Schaltung:

Zeit um sich der Schaltung zum Entprellen eines Tasters zu widmen. Auch diese Schaltung habe ich in ein VHDL-Modul gepackt, damit ich diese Schaltung bei mehrmaliger Benutzung nur noch instantiieren muss.
Werfen wir mal einen Blick auf das Modul…

Das Modul besitzt zwei Eingänge, einen für das nicht entprellte Taster-Signal und einen für den Takt, sowie einen Output für das entprellte Taster-Signal.
Zudem wird noch ein Integerwert in das Modul übergeben, der für die Debouncezeit steht.

Wichtig: Bei dem Wert muss man sich an den übergebenen Takt orientieren!

Gehen wir die Funktion mal mit dem Einschaltzustand durch. Zu diesem Zeitpunkt sind die Signale Debounce_Counter und Taster_Debounce mit den oben angegebenen Werten vorhanden (0 und ‚0‚).
Sobald jetzt eine steigende Flanke von dem Taktsignal anliegt schaut das FPGA nach ob der Eingangspin für den Taster den selben Zustand hat wie das Signal Taster_Debounce:

  • Eingangspin hat den selben Zustand:
    Taster wurde nicht betätigt. Debounce_Counter kann 0 bleiben, bzw. wird auf 0 gesetzt.
  • Eingangspin hat einen anderen Zustand – in diesem Fall ‚1‚, also High
    Taster wurde betätigt, Debounce_Counter wird um 1 erhöht.

Der oben beschriebene Vorgang wiederholt sich nun solange bis das Signal Debounce_Counter den selben Wert hat wie das Signal Debounce_Time.
Sobald dies eintritt ist die Zeit, wonach man annehmen kann, dass der Taster wirklich gedrückt wurde, vorüber und der Debounce_Counter wird gelöscht und das Signal Taster_Debounce, welches den aktuellen Zustand des Tasters speichert, wird auf den Zustand des Eingangs gesetzt (in diesem Fall ‚1‚).
Der Taster ist jetzt entprellt und sobald er los gelassen wird, passiert das selbe nochmal, nur dass dieses mal der Eingang des Moduls eine ‚1‚ führt statt einer ‚0‚.

Die beiden fertigen Module müssen jetzt nur noch zusammengeführt werden. Für die Zusammenführung erstelle ich mir ein neues VHDL Modul mit dem Namen Taster_Top, welches einen Clock-Eingang, einen Eingang für den Taster und einen Ausgang für das entprellte Tastersignal (z.B. für einen Zähler oder eine LED) besitzt:

Wie man erkennt, besteht dieses Modul nur aus der Instantiierung der beiden besprochenen Modulen und dem geschickten Zuweisen von Eingangs- und Ausgangssignalen. Damit habt ihr einen Taster in VHDL entprellt. Im nächsten Schritt werden wir mit diesem entprellten Tastersignal einen Zähler aufbauen…

 

Dokumentation:

 

-> Zurück zum FPGA + VHDL Tutorial

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload CAPTCHA.