Forum: Mikrocontroller und Digitale Elektronik Softwareentprellung Routine von Peter Danneger


von Luigi A. (spok)


Lesenswert?

Hallo zusammen,

ich verzweifle daran die Softwareenprellroutine von Peter Danneger zu 
verstehen.
1
timer_overflow0:               ; Timer Overflow Interrupt
2
 
3
    push    r0                 ; temporäre Register sichern
4
    in      r0, SREG
5
    push    r0
6
    push    iwr0
7
    push    iwr1
8
 
9
get8key:                       ;/old      state     iwr1      iwr0
10
    mov     iwr0, key_old      ;00110011  10101010            00110011
11
    in      key_old, key_pin   ;11110000
12
    eor     iwr0, key_old      ;                              11000011
13
    com     key_old            ;00001111
14
    mov     iwr1, key_state    ;                    10101010
15
    or      key_state, iwr0    ;          11101011
16
    and     iwr0, key_old      ;                              00000011
17
    eor     key_state, iwr0    ;          11101000
18
    and     iwr1, iwr0         ;                    00000010
19
    or      key_press, iwr1    ; gedrückte Taste merken
20
;
21
;
22
    pop     iwr1               ; Register wiederherstellen
23
    pop     iwr0
24
    pop     r0
25
    out     SREG, r0
26
    pop     r0
27
    reti

Hier meine Interpretation (komme nicht weit leider)
1
    mov     iwr0, key_old     ;alter Tastenzustand nach iwr0 sichern
2
    in      key_old, key_pin  ;Tastenzustand abfragen
3
    eor     iwr0, key_old     ;prüfen ob ein Flankenwechsel erfolgt ist 
4
    com     key_old           ;?
5
    mov     iwr1, key_state   ;? 
6
    or      key_state, iwr0   ;?
7
    and     iwr0, key_old     ;? 
8
    eor     key_state, iwr0   ;? 
9
    and     iwr1, iwr0        ;?
10
    or      key_press, iwr1   ;gedrückte Taste merken

kann mir jemand helfen? Würde es gerne verstehen.

von Uwe S. (de0508)


Lesenswert?

spiele doch selbst Debugger und schreibe die Zustandsänderungen aller 
Register / Variable untereinander auf ein Stück Karopapier.

Nach 4, bzw. 5 Durchläufen siehst Du das Ergebnis.

Die Routine gibt es hier im Forum auch als C-Code, dann ist das 
Verständnis einfacher.

von Hannes (Gast)


Lesenswert?

Luigi A. schrieb:
> Würde es gerne verstehen.

Vielleicht hilft Dir ja eine anders kommentierte Version weiter?
1
Tastenabfrage:  ;Entprell-Algorithmus geklaut bei Peter Dannegger...
2
 cbr flags,1<<entprell ;Jobflag löschen
3
 in tmp,tap         ;Tastenport einlesen (gedrückt=L)
4
 com tmp            ;invertieren (gedrückt=H)
5
 andi tmp,alltast   ;ungenutzte Bits ausblenden
6
 eor tmp,tas        ;nur Änderungen werden H
7
 and tz0,tmp        ;Prellzähler unveränderter Tasten löschen (Bit0)
8
 and tz1,tmp        ;Prellzähler unveränderter Tasten löschen (Bit1)
9
 com tz0            ;L-Bit zählen 0,2,->1, 1,3,->0
10
 eor tz1,tz0        ;H-Bit zählen 0,2,->tz1 toggeln
11
 and tmp,tz0        ;Änderungen nur dann erhalten, wenn im Prellzähler
12
 and tmp,tz1        ;beide Bits gesetzt sind (Zählerstand 3)
13
 eor tas,tmp        ;erhaltene Änderungen toggeln alten (gültigen) Tastenstatus
14
 and tmp,tas        ;nur (neu) gedrückte Tastenbits bleiben erhalten
15
 or tfl,tmp         ;und zugehörige Bits setzen (gelöscht wird nach Abarbeitung)
16
 ;in "tas" steht jetzt der gültige Tastenzustand,
17
 ;in "tfl" die Flags der neu gedrückten, noch nicht abgearbeiteten Tasten...
18
Tastendauer:
19
 mov tmp,tas        ;Tastenzustand kopieren
20
 andi tmp,wietast   ;nur Tasten mit Wiederholfunktion stehen lassen
21
 tst tmp            ;ist eine Taste betätigt?
22
 breq Tastendauer0  ;nein, Dauer auf Startwert...
23
 dec twz            ;ja, Zähler runter
24
 brne Tastenabfrage_e   ;Dauer abgelaufen? - nein...
25
 or tfl,tmp         ;ja, noch aktive Tasten übernehmen (alternativ)
26
; or twf,tmp         ;ja, noch aktive Tasten übernehmen (alternativ)
27
 ldi twz,twz1       ;und Zähler auf Wiederholwert setzen
28
Tastenabfrage_e:

Diese Version läuft als Job der Mainloop und wird vom Timer über den 
Merker "entprell" im (oberen) Register "flags" synchronisiert.

"tap" ist das Pin-Register des Tastenports
"tmp" ist ein temporäres Register, manche nennen es Scratchregister
"alltast" ist eine Bitmaske (Konstante) der benutzten Tastenbits
"tas" ist ein (unteres) Register und enthält den aktuell gültigen 
Tastenstatus der bis zu 8 Tasten
"tz0" ist ein (unteres) Register und enthält das Bit 0 der 8 separaten 
2-Bit-Prellzähler
"tz1" ist ein (unteres) Register und enthält das Bit 1 der 8 separaten 
2-Bit-Prellzähler. Zusammen mit "tz0" ergeben sich 8 separate Zähler mit 
dem Zählumfang von 0 bis 3
"tfl" ist ein (oberes) Register und enthält 8 Flags, die das Betätigen 
der entsprechenden Taste signalisieren. Die Flags werden von der 
Entprellroutine gesetzt, wenn die Taste losgelassen und erneut betätigt 
wurde. Die Mainloop kann nun an geeigneter Stelle die Flags prüfen und 
bei Abarbeitung einzeln löschen.

Für das Autorepeat der Tasten:
"wietast" ist eine Bitmaske (Konstante) der Tasten mit Wiederholfunktion
"twz" ist ein (oberes) Register, das zum Zählen der Verzögerungszeit der 
Tastenwiederholung dient
"twf" ist ein zweites Register für Tastenflags, das nur dann benötigt 
wird, wenn bei langen Tastendrücken etwas völlig Anderes gemacht werden 
soll, als bei kurzen Tastendrücken. Dazu wertet die Mainloop zuerst die 
langen Tastendrücke aus und löscht bei Treffer und Abarbeitung neben den 
Flags in "twf" auch die Flags in "tfl", so dass diese für die darauf 
folgende Auswertung bereits entwertet sind.

Die Funktion der 8 separaten 2-Bit-Zähler in den beiden 
Prellzähler-Registern verstehst Du am besten, wenn Du Dir mal anschaust, 
wie Zähler mit einfachen Logikbausteinen der TTL- oder CMOS-Serien 
realisiert werden. Da hier statt einfacher Gatter (1 Bit breit) Register 
mit einer Breite von 8 Bit verwendet werden, werden gleichzeitig 8 
separate Zähler bedient.

Es ist recht schwierig zu erklären, ich hoffe, es hilft Dir weiter.

...

von Carl D. (jcw2)


Lesenswert?


von neuer PIC Freund (Gast)


Angehängte Dateien:

Lesenswert?

Die C-Variante zum simulieren.
1
                              KEY_PIN     i           ct0         ct1         key_state   key_press
2
initial values                            00000000    00000000    00000000    00000000    00000000 
3
i = key_state ^ ~KEY_PIN      11111111    00000000    00000000    00000000    00000000    00000000 
4
ct0 = ~(ct0 & i)              11111111    00000000    11111111    00000000    00000000    00000000 
5
ct1 = ct0 ^ (ct1 & i)         11111111    00000000    11111111    11111111    00000000    00000000 
6
i &= ct0 & ct1                11111111    00000000    11111111    11111111    00000000    00000000 
7
key_state ^= i                11111111    00000000    11111111    11111111    00000000    00000000 
8
key_press |= key_state & i    11111111    00000000    11111111    11111111    00000000    00000000 
9
---intcall end -----------------
10
i = key_state ^ ~KEY_PIN      11111111    00000000    11111111    11111111    00000000    00000000 
11
ct0 = ~(ct0 & i)              11111111    00000000    11111111    11111111    00000000    00000000 
12
ct1 = ct0 ^ (ct1 & i)         11111111    00000000    11111111    11111111    00000000    00000000 
13
i &= ct0 & ct1                11111111    00000000    11111111    11111111    00000000    00000000 
14
key_state ^= i                11111111    00000000    11111111    11111111    00000000    00000000 
15
key_press |= key_state & i    11111111    00000000    11111111    11111111    00000000    00000000 
16
---intcall end -----------------
17
i = key_state ^ ~KEY_PIN      11111111    00000000    11111111    11111111    00000000    00000000 
18
ct0 = ~(ct0 & i)              11111111    00000000    11111111    11111111    00000000    00000000 
19
ct1 = ct0 ^ (ct1 & i)         11111111    00000000    11111111    11111111    00000000    00000000 
20
i &= ct0 & ct1                11111111    00000000    11111111    11111111    00000000    00000000 
21
key_state ^= i                11111111    00000000    11111111    11111111    00000000    00000000 
22
key_press |= key_state & i    11111111    00000000    11111111    11111111    00000000    00000000 
23
---intcall end -----------------
24
i = key_state ^ ~KEY_PIN      11111110    00000001    11111111    11111111    00000000    00000000 
25
ct0 = ~(ct0 & i)              11111110    00000001    11111110    11111111    00000000    00000000 
26
ct1 = ct0 ^ (ct1 & i)         11111110    00000001    11111110    11111111    00000000    00000000 
27
i &= ct0 & ct1                11111110    00000000    11111110    11111111    00000000    00000000 
28
key_state ^= i                11111110    00000000    11111110    11111111    00000000    00000000 
29
key_press |= key_state & i    11111110    00000000    11111110    11111111    00000000    00000000 
30
---intcall end -----------------
31
i = key_state ^ ~KEY_PIN      11111110    00000001    11111110    11111111    00000000    00000000 
32
ct0 = ~(ct0 & i)              11111110    00000001    11111111    11111111    00000000    00000000 
33
ct1 = ct0 ^ (ct1 & i)         11111110    00000001    11111111    11111110    00000000    00000000 
34
i &= ct0 & ct1                11111110    00000000    11111111    11111110    00000000    00000000 
35
key_state ^= i                11111110    00000000    11111111    11111110    00000000    00000000 
36
key_press |= key_state & i    11111110    00000000    11111111    11111110    00000000    00000000 
37
---intcall end -----------------
38
i = key_state ^ ~KEY_PIN      11111110    00000001    11111111    11111110    00000000    00000000 
39
ct0 = ~(ct0 & i)              11111110    00000001    11111110    11111110    00000000    00000000 
40
ct1 = ct0 ^ (ct1 & i)         11111110    00000001    11111110    11111110    00000000    00000000 
41
i &= ct0 & ct1                11111110    00000000    11111110    11111110    00000000    00000000 
42
key_state ^= i                11111110    00000000    11111110    11111110    00000000    00000000 
43
key_press |= key_state & i    11111110    00000000    11111110    11111110    00000000    00000000 
44
---intcall end -----------------
45
i = key_state ^ ~KEY_PIN      11111110    00000001    11111110    11111110    00000000    00000000 
46
ct0 = ~(ct0 & i)              11111110    00000001    11111111    11111110    00000000    00000000 
47
ct1 = ct0 ^ (ct1 & i)         11111110    00000001    11111111    11111111    00000000    00000000 
48
i &= ct0 & ct1                11111110    00000001    11111111    11111111    00000000    00000000 
49
key_state ^= i                11111110    00000001    11111111    11111111    00000001    00000000 
50
key_press |= key_state & i    11111110    00000001    11111111    11111111    00000001    00000001 
51
---intcall end -----------------
52
i = key_state ^ ~KEY_PIN      11111110    00000000    11111111    11111111    00000001    00000001 
53
ct0 = ~(ct0 & i)              11111110    00000000    11111111    11111111    00000001    00000001 
54
ct1 = ct0 ^ (ct1 & i)         11111110    00000000    11111111    11111111    00000001    00000001 
55
i &= ct0 & ct1                11111110    00000000    11111111    11111111    00000001    00000001 
56
key_state ^= i                11111110    00000000    11111111    11111111    00000001    00000001 
57
key_press |= key_state & i    11111110    00000000    11111111    11111111    00000001    00000001 
58
---intcall end -----------------
59
i = key_state ^ ~KEY_PIN      11111110    00000000    11111111    11111111    00000001    00000001 
60
ct0 = ~(ct0 & i)              11111110    00000000    11111111    11111111    00000001    00000001 
61
ct1 = ct0 ^ (ct1 & i)         11111110    00000000    11111111    11111111    00000001    00000001 
62
i &= ct0 & ct1                11111110    00000000    11111111    11111111    00000001    00000001 
63
key_state ^= i                11111110    00000000    11111111    11111111    00000001    00000001 
64
key_press |= key_state & i    11111110    00000000    11111111    11111111    00000001    00000001 
65
---intcall end -----------------
66
i = key_state ^ ~KEY_PIN      11111110    00000000    11111111    11111111    00000001    00000001 
67
ct0 = ~(ct0 & i)              11111110    00000000    11111111    11111111    00000001    00000001 
68
ct1 = ct0 ^ (ct1 & i)         11111110    00000000    11111111    11111111    00000001    00000001 
69
i &= ct0 & ct1                11111110    00000000    11111111    11111111    00000001    00000001 
70
key_state ^= i                11111110    00000000    11111111    11111111    00000001    00000001 
71
key_press |= key_state & i    11111110    00000000    11111111    11111111    00000001    00000001 
72
---intcall end -----------------
73
i = key_state ^ ~KEY_PIN      11111110    00000000    11111111    11111111    00000001    00000001 
74
ct0 = ~(ct0 & i)              11111110    00000000    11111111    11111111    00000001    00000001 
75
ct1 = ct0 ^ (ct1 & i)         11111110    00000000    11111111    11111111    00000001    00000001 
76
i &= ct0 & ct1                11111110    00000000    11111111    11111111    00000001    00000001 
77
key_state ^= i                11111110    00000000    11111111    11111111    00000001    00000001 
78
key_press |= key_state & i    11111110    00000000    11111111    11111111    00000001    00000001 
79
---intcall end -----------------
80
i = key_state ^ ~KEY_PIN      11111111    00000001    11111111    11111111    00000001    00000001 
81
ct0 = ~(ct0 & i)              11111111    00000001    11111110    11111111    00000001    00000001 
82
ct1 = ct0 ^ (ct1 & i)         11111111    00000001    11111110    11111111    00000001    00000001 
83
i &= ct0 & ct1                11111111    00000000    11111110    11111111    00000001    00000001 
84
key_state ^= i                11111111    00000000    11111110    11111111    00000001    00000001 
85
key_press |= key_state & i    11111111    00000000    11111110    11111111    00000001    00000001 
86
---intcall end -----------------
87
i = key_state ^ ~KEY_PIN      11111111    00000001    11111110    11111111    00000001    00000001 
88
ct0 = ~(ct0 & i)              11111111    00000001    11111111    11111111    00000001    00000001 
89
ct1 = ct0 ^ (ct1 & i)         11111111    00000001    11111111    11111110    00000001    00000001 
90
i &= ct0 & ct1                11111111    00000000    11111111    11111110    00000001    00000001 
91
key_state ^= i                11111111    00000000    11111111    11111110    00000001    00000001 
92
key_press |= key_state & i    11111111    00000000    11111111    11111110    00000001    00000001 
93
---intcall end -----------------
94
i = key_state ^ ~KEY_PIN      11111111    00000001    11111111    11111110    00000001    00000001 
95
ct0 = ~(ct0 & i)              11111111    00000001    11111110    11111110    00000001    00000001 
96
ct1 = ct0 ^ (ct1 & i)         11111111    00000001    11111110    11111110    00000001    00000001 
97
i &= ct0 & ct1                11111111    00000000    11111110    11111110    00000001    00000001 
98
key_state ^= i                11111111    00000000    11111110    11111110    00000001    00000001 
99
key_press |= key_state & i    11111111    00000000    11111110    11111110    00000001    00000001 
100
---intcall end -----------------
101
i = key_state ^ ~KEY_PIN      11111111    00000001    11111110    11111110    00000001    00000001 
102
ct0 = ~(ct0 & i)              11111111    00000001    11111111    11111110    00000001    00000001 
103
ct1 = ct0 ^ (ct1 & i)         11111111    00000001    11111111    11111111    00000001    00000001 
104
i &= ct0 & ct1                11111111    00000001    11111111    11111111    00000001    00000001 
105
key_state ^= i                11111111    00000001    11111111    11111111    00000000    00000001 
106
key_press |= key_state & i    11111111    00000001    11111111    11111111    00000000    00000001 
107
---intcall end -----------------
108
i = key_state ^ ~KEY_PIN      11111111    00000000    11111111    11111111    00000000    00000001 
109
ct0 = ~(ct0 & i)              11111111    00000000    11111111    11111111    00000000    00000001 
110
ct1 = ct0 ^ (ct1 & i)         11111111    00000000    11111111    11111111    00000000    00000001 
111
i &= ct0 & ct1                11111111    00000000    11111111    11111111    00000000    00000001 
112
key_state ^= i                11111111    00000000    11111111    11111111    00000000    00000001 
113
key_press |= key_state & i    11111111    00000000    11111111    11111111    00000000    00000001 
114
---intcall end -----------------
115
i = key_state ^ ~KEY_PIN      11111111    00000000    11111111    11111111    00000000    00000001 
116
ct0 = ~(ct0 & i)              11111111    00000000    11111111    11111111    00000000    00000001 
117
ct1 = ct0 ^ (ct1 & i)         11111111    00000000    11111111    11111111    00000000    00000001 
118
i &= ct0 & ct1                11111111    00000000    11111111    11111111    00000000    00000001 
119
key_state ^= i                11111111    00000000    11111111    11111111    00000000    00000001 
120
key_press |= key_state & i    11111111    00000000    11111111    11111111    00000000    00000001 
121
---intcall end -----------------
122
i = key_state ^ ~KEY_PIN      11111111    00000000    11111111    11111111    00000000    00000001 
123
ct0 = ~(ct0 & i)              11111111    00000000    11111111    11111111    00000000    00000001 
124
ct1 = ct0 ^ (ct1 & i)         11111111    00000000    11111111    11111111    00000000    00000001 
125
i &= ct0 & ct1                11111111    00000000    11111111    11111111    00000000    00000001 
126
key_state ^= i                11111111    00000000    11111111    11111111    00000000    00000001 
127
key_press |= key_state & i    11111111    00000000    11111111    11111111    00000000    00000001 
128
---intcall end -----------------
129
i = key_state ^ ~KEY_PIN      11111111    00000000    11111111    11111111    00000000    00000001 
130
ct0 = ~(ct0 & i)              11111111    00000000    11111111    11111111    00000000    00000001 
131
ct1 = ct0 ^ (ct1 & i)         11111111    00000000    11111111    11111111    00000000    00000001 
132
i &= ct0 & ct1                11111111    00000000    11111111    11111111    00000000    00000001 
133
key_state ^= i                11111111    00000000    11111111    11111111    00000000    00000001 
134
key_press |= key_state & i    11111111    00000000    11111111    11111111    00000000    00000001 
135
---intcall end -----------------

von Luigi A. (spok)


Lesenswert?

Danke euch sehr, werde mir eure Beiträge zu gemüte ziehen.
Gruss

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.