Hallo Janiiix3
Hi @all
Bin seit langer Zeit mal wieder auf dieser Seite. Meine Rentneruhr ist schon seit einem Jahr abgelaufen und nun geht es mir wie allen Rentnern, ich hab keine Zeit mehr...
Das ein so alter Beitrag immer noch aufgegriffen wird erstaunt mich. janiiix3, du solltest nach fast 2 Jahren doch in der Lage sein, Eingänge zu entprellen. Ich weiß jetzt nicht mehr, wo damals meine Gedanken waren, aber wenn du die Eingangsbits auf Bytes legst, so brauchst du doch nur schauen, ob sich in diesen Bytes was geändert hat. Wenn ja, setzt du die Prellzeit. Bei Ablauf übernimmst du diese Bytes in einen Inputspeicher.
In Assembler habe ich z.B. 3 Variablen
New_In: aktuelle Eingänge vom Port, gelesen in jedem Zyklus (pollen)
In_Debounce: vom letzten Durchgang gelesene Eingänge. Bei einem Unterschied zwischen New_In und In_Debounce wird die Prellzeit gesetzt.
Akt_In: Wenn Prellzeit auf 0 läuft, wird derWert aus New_In nach Akt_In kopiert. Natürlich darf die Prellzeit nicht weiterlaufen. Dafür habe ich ein Controllbit, welches den Zähler für die Prellzeit freigibt. Beim Erreichen von 0 wird dieses Controllbit gelöscht und nur in diesem Schritt die Eingänge übernommen.
in Assembler:
Lesen der Eingänge:
Read_IO:
IN r16, pinb ; Beispiel Port B lesen.
ANDI r16,0b00111111 ; unbenutzte Bits evtl. ausmaskieren
STS New_In, r16 ; ablegen,
; weitere Eingänge ebenfalls einlesen, maskieren und ablegen
RET
Entprellen:
Debounce:
LDS r16, New_In ; gelesene Eingänge aus diesem Zyklus
LDS r17, In_Debounce ; zuletzt gelesene Eingänge aus Zyklus davor
EOR r17, r16 ; Ergebnis 0, wenn beide Variablen gleich sind. (keine Änderung)
STS In_Debounce, r16 ; aktuelle Eingänge ablegen
BREQ Count_Down ; Sprung, wenn keine Änderung
LDS r16, Controll ; Controllbyte laden
ORI r16,0b00000001 ; z.B. Controllbit 0 setzen
STS controll, r16 ; und ablegen
LDI r16, 50 ; Prellzeit laden
STS deb_Time ; und ablegen
rjmp End_Debounce ; und beenden
Count_Down:
LDS r16, Controll ; prüfen, ob Prellzeit läuft
ANDI r16,0b00000001 ; z.B. mit Controllbit 0
BREQ End_Debounce ; Routine beenden, wenn keine Zeit läuft
LDS r16, Deb_Time ;Prellzeit laden
DEC r16 ; herunterzählen
STS Deb_Time, r16 ; wieder speichern
BRNE End_Debounce ; und beenden, wenn nicht 0 erreicht
LDS r16, New_In ; darf auch gern In_Debounce sein...
STS akt_In, r16 ; ab hier sind die Eingänge entprellt und sind in Akt_In verfügbar.
LDS r16, Controll ; noch das Controllbit loschen
ANDI r16, 0b11111110
STS Controll, r16
End_Debounce:
Ret
Beide Routinen werden in der Programmschleife aufgerufen
Loop:
....
RCALL red_IO
RCALL debounce
....
rjmp loop
So, ich hoffe nun, entprellen ist klar. Der Wert 50 ist mal so aus der Luft gegriffen. Man kann auch ein zeitereignis benutzen, um diese Routine aufzurufen. Z. B. in jeder msek. Dann ist eventuell schon ein Wert der Entprellzeit von 5 ausreichend.
So, ich hoffe, ich find jetzt öfter wieder zu euch.
Gruß oldmax