Ich habe eine Hardware-Taste, die ich mit einem Interrupt verbunden habe, aber mein Problem ist, dass sie ein wenig abprallt und das Drücken der Taste unzuverlässig macht. Ich denke, ein Großteil dieser Probleme würde durch Sampling in der Hauptschleife gelöst, aber das fühlt sich technisch einfach falsch an.
Sind Interrupts besser für die Intra-Circuit-Kommunikation geeignet oder sind Interrupts auch für Hardware-Switches geeignet? Wenn ja, welche Entprellungstechniken kann ich verwenden?
Ich habe versucht, eine Timer-Variable beizubehalten und sie mit der aktuellen Zeit, Verzögerungen und anderen Techniken zu vergleichen. Es scheint, als ob die Sprünge so schnell sind, dass es keine Rolle spielt.
interrupts
button
sampling
OneChillDude
quelle
quelle
Antworten:
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:
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:
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).
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:
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.
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.
quelle
Das Entprellen kann in der Software durch Maskieren der IRQs für die Absprungzeit oder in der Hardware durch Hinzufügen eines Haltekondensators mit einer Absprungzeit von RC = T> im Bereich von 1 bis 15 ms erfolgen, abhängig von der Größe des Schalters.
quelle
Um ein SW-De-Bounce durchzuführen, zeichnen Sie den Zeitstempel des aktuellen Ereignisses auf und prüfen Sie, ob sich das letzte gültige Ereignis verzögert hat:
UPD: Mit wenigen Änderungen können Sie Doppelklicks registrieren:
quelle
Interrupts eignen sich definitiv auch hervorragend für Hardware-Switches. Durch die Verwendung von Interrupts vermeiden Sie eine große Verschwendung von Ressourcen und möglicherweise Energie, insbesondere wenn Sie mit batteriebetriebenen Geräten arbeiten.
Wenn Ihr Code immer größer wird, werden Sie feststellen, dass es noch einfacher ist, die Interrupts für Schaltflächen zu implementieren, als sie in Ihrer Hauptschleife abzufragen.
Bei Ihrem Entprellen handelt es sich wahrscheinlich um ein Codierungsproblem. Ich benutze normalerweise einen ~ 10ms Timer zum Entprellen, während ich nach dem Loslassen der Taste suche. Stellen Sie sicher, dass Sie den Tasteninterrupt auch vorübergehend deaktivieren, während Sie ihn entprellen, damit die Interruptroutine nicht mehrmals ausgeführt wird.
Wenn Sie immer noch Probleme haben, geben Sie den Code hier ein, damit wir Ihnen helfen können.
quelle
Dies ist Tony Stewarts Antwort ziemlich ähnlich, aber ich denke, es könnte etwas erweitert werden.
Das obere Schema ist entweder für einen Interrupt bei niedriger oder bei fallender Flanke. Das untere Schema ist für einen Interrupt bei hoher oder steigender Flanke.
simulieren Sie diese Schaltung - Schema erstellt mit CircuitLab
Angesichts der Kosten eines Kondensators lohnt es sich für mich, ihn einfach zu verwenden, anstatt mir Sorgen zu machen, ob mein Software-Debounce fehlerhaft ist.
Bezogen auf Hardware-Debouncing
quelle
Menschen sind langsam, wir brauchen nicht die sofortige Aufmerksamkeit eines Mikros, das im Mikrosekundenbereich liegt.
Dies ist natürlich nicht der einzige und auch nicht der richtige Weg, dies immer zu tun, aber ich finde es im Allgemeinen sinnvoller, einen Timer einzurichten (viele Mikros haben System-Ticks), um einen Interrupt in festgelegten Intervallen auszulösen und den Zustand des Pins in einen zu verschieben Variable, die der Code später untersuchen soll. Sie erhalten eine Var, die beim Hüpfen voller Asche ist
10010110 Asche
Aber zu bestimmten Zeitpunkten erhalten Sie diese 4 Werte:
01111111 steigende Flanke gerade entprellt
11111111 Taste im eingeschwungenen Zustand nach oben
10000000 fallende Flanke gerade entprellt
00000000 Taste im eingeschwungenen Zustand nach unten
Meistens verwende ich jedoch nur einen Zähler, der beim Abprallen zurückgesetzt wird. Es ist schnell, getestet und einfach zu machen.
Wenn es fehlschlägt, versuche ich etwas Klügeres aus dem von anderen vorgeschlagenen Ganssle-Dokument!
quelle