Das Entprellen ist eine FAQ. Sie sollten in der Lage sein, ... nahezu unbegrenzt viele Webseiten zum Thema zu finden. Smith kommentierte auch Jack Ganssles vielgelesenes PDF zu diesem Thema. Und mit all diesen Antworten haben Sie sowohl Hardware- als auch Softwaremethoden.
Ich werde diese "Literatur" nur ein wenig ergänzen, indem ich hauptsächlich über Ideen spreche, die noch nicht gut behandelt wurden. Aber bevor ich es tue, ein oder zwei Punkte:
- Das Entprellen in analoger Hardware kann zu Ergebnissen führen, die Sie nicht mit einem Schalter erzielen können, der nur digital in regelmäßigen Abständen durch Abfragen oder sogar durch Hardware-Pin-Change-Ereignisse "beobachtet" wird. Aber Sie können in jeder Hinsicht "gut genug" digital arbeiten. Fast niemand verwendet heutzutage externe analoge Entprellungslösungen. Aber ich habe alles verwendet, von Pulsdehnung mit One-Shots (74121) bis zu Techniken, die Jack Ganssle hier erwähnt hat .
- Für diejenigen, die nur Embedded-Programmierung betreiben und überhaupt nicht daran interessiert sind, etwas über Elektronik zu lernen, ist das Entprellen von Schaltern wahrscheinlich eine der beiden grundlegenden Fähigkeiten, die benötigt werden. Betriebs-LEDs ist wahrscheinlich die andere. Und damit meine ich nicht, nur eine Fähigkeit zu haben. Ich meine, es auf verschiedene Arten tun zu können. So dass Sie wirklich tun müssen , um voll apprehend was Jack Ganssle schreibt über, und mehr noch, in Bezug auf Schalter.
Da ich die Pulsdehnung mit einer 74121 erwähnt habe und Jack Ganssle sie noch nicht erwähnt hat und noch niemand hier, kann ich diesen zusätzlichen Link auch als zusätzlichen Lesevorschlag zur Verwendung der 74121 oder 555 als One-Shot bereitstellen Timer zum Entprellen von Schaltern.
Nun dazu durch Beobachtung mit einem Mikrocontroller.
Normalerweise benutze ich eine Zustandsmaschine, um das Entprellen zu handhaben. Dies wird fast immer von einem regulären "Herzschlag" -Timer gesteuert, den ich auf ungefähr , wo möglich. (Ich verwende im Allgemeinen aus mehreren Gründen KEINE flankengetriggerten Interrupt-Ereignisse.)8Frau
Die Zustandsmaschine sieht folgendermaßen aus:
simulieren Sie diese Schaltung - Schema erstellt mit CircuitLab
Der Wert von DEBOUNCED für den Switch kann die Werte "inaktiv", "aktiv" und "unbekannt" annehmen. Auf diese Weise können Sie sicherstellen, dass Ihre Software wartet, bis sich der Schaltwert nach der Initialisierung einstellt. Aber normalerweise kümmere ich mich nicht darum. Ich ersetze den "unbekannten" Wert durch einen Standardwert und verwende stattdessen nur ein Binärwertsystem.
Die Zustandsmaschine wird aufgerufen, indem zuerst der entprellte Wert auf den Standardwert gesetzt und dann der Zustand "ÄNDERN" der Zustandsmaschine aufgerufen wird. In jedem Zeitintervall (normalerweise wenn ich damit durchkommen kann), lese ich den aktuellen Schaltwert und führe eine Aktualisierung des aktuellen Status und möglicherweise des entprellen Wertes durch. Dann gehe ich einfach. Der High-Level-Code greift dann nur auf den entprellen Zustand zu.8Frau
Wenn es mir wichtig ist, kann ich auch einen zuvor entwerteten Zustand beibehalten. In diesen Fällen kopiere ich beim Aktualisieren des entprellten Zustands selbst diesen Zustand zuerst in einen "vorherigen entprellen Zustand". Ich kann dann das Wertepaar verwenden, um festzustellen, ob ein entprellter Übergang stattgefunden hat. Manchmal interessieren mich Übergänge nicht. Manchmal mache ich. Es kommt also darauf an. Aber in jedem Fall möchte ich nur über entprellte Übergänge wissen. Ich kümmere mich nie um kleine Übergänge. High-Level-Code verwendet also niemals den internen Status, den die Zustandsmaschine für ihre eigene Arbeit verwendet.
Eines der schönen Dinge an dieser Methode ist, dass ich einen ganzen Port von Switches gleichzeitig entprellen kann. Und ich kann es auch ohne einen einzigen Zweig im Interrupt-Code tun. Dies bedeutet einen sehr schnellen und kurzen Entprellungscode für bis zur Portbreite des Mikrocontrollers (normalerweise 8 Bit breit). Ein Beispiel aus dem Atmel AT90 zeigt, wie dies mit einem Timer0-Interrupt-Ereignis erreicht wird:
.equ SWPORTPINS = PINB
.def SwRawCurr = r4
.def SwRawPrev = r5
.def SwState = r6
.def SwDebCurr = r7
.def SwDebPrev = r8
; Debounce the input switches.
mov SwRawPrev, SwRawCurr
in SwRawCurr, SWPORTPINS
mov Timer0Tmp1, SwRawCurr
eor Timer0Tmp1, SwRawPrev
mov Timer0Tmp0, Timer0Tmp1
or Timer0Tmp1, SwState
mov SwState, Timer0Tmp0
mov Timer0Tmp0, Timer0Tmp1
com Timer0Tmp0
and Timer0Tmp1, SwDebCurr
and Timer0Tmp0, SwRawCurr
or Timer0Tmp1, Timer0Tmp0
mov SwDebPrev, SwDebCurr
mov SwDebCurr, Timer0Tmp1
Dieses Beispiel zeigt nun den vollständigen Deal, einschließlich der vorherigen und aktuellen entprellten Switch-Werte. Und es führt auch alle notwendigen Zustandsübergänge durch. Ich zeige die Initialisierung dieses Codes nicht. Aber das Obige verdeutlicht, wie einfach die Zustandsmaschine zu bedienen ist und wie wenig Code dafür erforderlich ist. Es ist recht schnell und einfach und erfordert keine Verzweigung (was manchmal zusätzliche Zyklen sowie zusätzlichen Code-Speicherplatz erfordert).
8Frau
20Frau
Bitte beachten Sie, dass die von mir erwähnte Zustandsmaschine zuerst in den Zustand SETTLED wechseln und dann eine weitere Beispielzeit dort bleiben muss, bevor der Wert für DEBOUNCED aktualisiert wird. Wenn Sie also einen Knopf drücken und ihn auch unter den besten Umständen gedrückt halten, sind folgende Übergänge erforderlich:
- Wechseln Sie von SETTLED zu CHANGING
- Wechseln Sie von ÄNDERN zu EINSTELLEN
- Bleiben Sie in SETTLED und aktualisieren Sie DEBOUNCED
Für einen neuen entprellten Zustand sind mindestens 3 Abtastzeiträume erforderlich.
Ein Druckknopf benötigt mindestens 6 Abtastzeiten, um von inaktiv zu aktiv und dann zurück zu inaktiv zu wechseln.
8Frau16ms < t ≤ 24Frau24Frau40ms < t ≤ 48Frau
20Frau100ms < t ≤ 120Frau
Wenn Sie diesen Weg gehen, sollten Sie keine unbekümmerten Probenzeiten verwenden. Wenn Sie müssen, dann müssen Sie meiner Meinung nach auch viele Tests mit Benutzern / Verbrauchern durchführen.
45Frau2Frau