Forum: Projekte & Code Einzelnen Taster entprellen ASM


von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Hallo zusammen,

dachte es wäre evtl. nützlich das einmal mit einer passenden Überschrift 
in die Codesammlung einzufügen, da es sonst schlecht auffindbar ist.

Ist nicht von mir sondern von Peter Dannegger.
Die Quelle entstammt hierher :
Beitrag "Re: Tasten entprellen - Bulletproof"
1
AVR-Assembler-Code
2
;************************************************************************
3
;*                                                                      *
4
;*      Timer 0 interrupt                                               *
5
;*      Debounce a single key (3 times)                                 *
6
;*                                                                      *
7
;************************************************************************
8
.equ key_state  = 2    ;Bit Tastenstatus
9
.equ key_press  = 3    ;Bit Tastenflag
10
11
  in  savesreg, sreg
12
13
  bst  key_reg, key_state
14
  sbis  key_in, key_pin
15
  rjmp  _deb_x0
16
  brts  _deb_11
17
  rjmp  _deb_10
18
_deb_x0:
19
  brts  _deb_10
20
_deb_00:
21
_deb_11:                    ;key_state == key_pin
22
  cbr  key_reg, 0x03        ;reset debounce counter
23
_deb_10:
24
_deb_01:                    ;key_state != key_pin
25
  sbrs  key_reg, key_press
26
  inc  key_reg              ;count up
27
28
  out  sreg, savesreg
29
  reti
30
;-------------------------------------------------------------------------
31
AVR-Assembler-Code

: Gesperrt durch Moderator
von Electronics'nStuff (Gast)


Lesenswert?

Bernd Stein schrieb:
> dachte es wäre evtl. nützlich das einmal mit einer passenden Überschrift
> in die Codesammlung einzufügen, da es sonst schlecht auffindbar ist.

Hm.. du verlinkst einen Artikel mit der Aufschrift:

"Tasten entprellen - Bulletproof"

und zwar im Unterforum "Codesammlung"..

Also irgendwie eine passendere Überschrift gibt es kaum.
Ausser vllt. "Wie Entprelle ich so kompliziert und undurchschaubar, dass 
es min. 4h dauert bis ich es begriffen habe".

Gruss

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Hallo,

hiermit möchte ich versuchen, die grundsätzliche Funktion dieser 
Interrupt Service Routine ( ISR ) für das Tasterentprellen zu erklären.

In meinem Beispiel wird die Timer0 Overflow Interrupt eines ATmega8 
welcher mit seinem internen 1Mhz RC-Oszillator arbeitet unter anderem 
zur Tasterentprellung genutzt. Diese IRQ wird dazu ca. alle 2ms 
aufgerufen, dementsprechend natürlich auch die dazugehörige ISR.

Das Prinzip beruht auf dem Inkrementieren eines Arbeitsregisters
( key_reg ), dessen einzelnen Bits unterschiedliche Funktionen erfüllen.
Dieses Arbeitsregister sollte eines ab r16 sein, damit kompfortabel mit 
den Bitmanipulations,- und Auswertebefehlen cbr/sbr sowie sbrc/sbrs 
gearbeitet werden kann.

In diesem Fall dienen die Bits 1&0 als Zählerbits. Es könnten aber auch 
die Bits 5...0 dazu genutzt werden. Das darauf folgende Bit 2
( key_state ) dient der Erkennung das der Taster nicht betätigt ist. 
Dieses Bit wird nur gesetzt, wenn 3x direkt hintereinander in der ISR 
ein nicht betätigter Taster erkannt wurde ( 4x nach POR bzw. Reset ).

Das auf dieses Bit folgende Bit 3 ( key_press ) wird gesetzt, wenn auch 
hier wieder 3x direkt hintereinander in der ISR ein diesmal betätigter 
Taster dedektiert wurde. Es gilt zu beachten, das hierbei nur einmalig 
eine Aktion ausgeführt wird. Das heißt eine Dauerbetätigung löst keine 
weitere Aktion aus, da die Zählerbits immer zurückgesetzt werden.
Nach einem Power On Reset ( POR ), Watch Dog Reset, Reset oder sonstigen 
Resets, wird ein bereits davor betätigter Taster also nicht erkannt.

Dies könnte allerdings nach Ablauf der Entprellzeit durch das nicht 
gesetzte Bit 2 ( key_state ) erkannt werden, da dieses ja bei 
Nichtbetätigung des Taster gesetzt wird. Allerdings darf das nicht mit 
Taster " losgelassen " gleichgesetzt werden, denn " Taster losgelassen " 
setzt vorraus das der Taster vorher betätigt war, aber Bit 2 wird auch 
gesetzt, wenn der Taster vorher nicht betätigt wurde.



Typische Prellzeiten bei elektromechanischen Schaltern und Tastern 
liegen laut Wikipedia zwischen 100µs bis 10ms

*( Reaktionszeit Mensch 300-400ms ).*

Deshalb sollte die Zeit so eingestellt werden, das das Bit 3
( key_press ) bei  > = 10ms gesetzt wird. Hier in dem Beispiel, wo in 
der ISR welche ca. alle 2ms aufgerufen wird, unter anderem auch die 
Tasterentprellung vorgenommen wird, gilt der Taster bereits nach ca. 6ms 
( 3x 2ms ) als entprellt.

Falls es also widererwarten doch hin und wieder zu Tasterprellen kommt, 
steht der Erweiterung des Zählers auf 3-Bit oder noch mehr nichts im 
Wege. Ein 3-Bit Zäher ( Bit 2...0 ) würde also bis das Bit 4
( key_press ) gestzt wird, ein sieben maliges aufrufen der ISR 
benötigen. Dadurch wird eine Prellzeit von ca. 14ms überdeckt, was immer 
noch weit entfernt von der Reaktionszseit des Menschen ist.

Zur Verdeutlichung sollte unbedingt ein eigener PAP
( Programmablaufplan ) erstellt werden, oder evtl. ein Logikplan, wenn 
man damit besser zurecht kommt.


Bernd_Stein

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Jetzt mal eine andere Version, die laut MaWin, ich nehme an der Echte 
und Wahre ;-) , so oder so ähnlich als Standard gilt ( Für Details lese 
den Thread im Link komplett ).

Leider wird dort nicht weiter auf sein Code eingegangen und er ist nicht 
für einen einzelnen Taster gedacht.

Beitrag "Re: Wie lange prellt ein Taster in der Regel?"

Beitrag "Wie lange prellt ein Taster in der Regel?"
1
  IN  a,KEY_PORT
2
  MOV key_new,a
3
  EOR a,key_old   ; changed
4
  AND a,key_new   ; pressed
5
  :
6
  :  a enthält gesetztes bit für jede gerade runtergedrückte Taste
7
  :
8
  MOV key_old,key_new

Ach, falls sich die Profis doch mal mit so etwas befasst haben, können 
sie gerne ihren Senf dazu beitragen, um auch in dieser Sprache 
vernünftige Programme hervorzubringen ;-) :

Beitrag "Tasterverarbeitung mit ARDUINO-C"


Bernd_Stein

: Bearbeitet durch User
von Carsten-Peter C. (carsten-p)


Lesenswert?

Moin, ich bin bestimmt kein Profi, aber vielleicht hilft Dir mein 
Ansatz. Eine Möglichkeit ist, einen Interrupt durch z.B. INT0 oder PCINT 
auszulösen. Dann startest Du in der ISR den Timer. Läuft der Timer über 
bzw. erreicht einen Compare Match, je nach dem, kannst Du in der ISR des 
Timers die Eingänge lesen und den Timer stoppen.
Eine andere Möglichkeit ist, in der Hauptschleife die Eingänge 
abzufragen und im SRAM zu speichern. Sind die Werte nach mehreren 
Durchläufen gleich, hast Du die Entprellung.
Beide Möglichkeiten haben Vor- und Nachteile. Laufen bei mir gut.
Gruß
Carsten

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Carsten-Peter C. schrieb:
> ...
> Eine Möglichkeit ist, einen Interrupt durch z.B. INT0 oder PCINT
> auszulösen.
> ...
>
" Der nicht entprellte Schalter muss mit einem programmierten I/O-Pin 
verbunden sein, niemals mit einem Interrupt. "

Ich verlass mich da mal lieber auf Profis.
Orginal ist in englisch und was der Typ da über die faulen Secret 
Service
Mitarbeiter schreibt ist schon interessant.
Überhaupt ist der Link äußerst interessant, aber für's detailierte 
Verständnis wäre mir so etwas in meiner Muttersprache lieber.

Hier unter  " Debounce Policy " zu finden :

https://www-ganssle-com.translate.goog/debouncing-pt2.htm?_x_tr_sl=en&_x_tr_tl=de&_x_tr_hl=de&_x_tr_pto=sc&_x_tr_sch=http

Vorgeschichte hier :

https://www-ganssle-com.translate.goog/debouncing.htm?_x_tr_sch=http&_x_tr_sl=en&_x_tr_tl=de&_x_tr_hl=de&_x_tr_pto=sc

Großen dank an " Mr. Debounce (Gast) ", dessen Beitrag leider zu
wenig Aufmerksamkeit geschent wurde :

Beitrag "Re: Wie lange prellt ein Taster in der Regel?"

Auch auf den vermeintlichen Vorschlag von MaWin in meinem Posting hier, 
wurde noch nicht eingegangen !

Ich bin an einer Diskusion von MaWin's Vorschlag interessiert !


Bernd_Stein

von Thomas F. (igel)


Lesenswert?

Bernd S. schrieb:
> Ach, falls sich die Profis doch mal mit so etwas befasst haben, können
> sie gerne ihren Senf dazu beitragen

Das Thema wurde doch bereits zur Genüge abgearbeitet. Es gibt sogar 
einen Suprer Artikel darüber den du nach so vielen Jahren im Forum 
kennen solltest:
https://www.mikrocontroller.net/articles/Entprellung

Und dort ist die Funktion der Routinen auch ausführlich beschrieben:

https://www.mikrocontroller.net/articles/Entprellung#Timer-Verfahren_(nach_Peter_Dannegger)

Kein Grund uralte Threads wieder raus zu kramen.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.