Huhu schon wieder...
Ich weiß, dass es dieses Thema schon zig-mal hier gab, weshalb ich auch
bereits allerhand verschiedene Methoden und Quelltext-Schnipsel
durchprobiert hab, aber irgendwie hinkt das alles noch. Hier mein
aktueller Versuch, dashier
(http://www.mikrocontroller.net/attachment/highlight/22223) in Assembler
umzusetzen.
Hardware: Pollin-Drehgeber, mit Pull-*down* (!) angeschlossen.
Software:
In TMPI2 befindet sich der Wert des PIN-Registers, an welchem der
Drehgeber angeschlossen ist (PINx3 und PINx4, siehe Bitmaske). In
(dseg_encoder+[0..1]) finden zwei Bytes für alter_status (Byte 0) und
step (Byte 1) Platz (siehe C-Quelltext).
Im RAM bei dseg_buttons liegt ein "Interruptregister", welches vom
Hauptprogramm regelmäßig gepollt wird.
Hier der Original-C-Quelltext:
1 | {
|
2 | static unsigned char alter_status = 0,step = 0;
|
3 | unsigned char neuer_status;
|
4 |
|
5 | neuer_status = Geber & (_BV(Schalter_A) | _BV(Schalter_B));
|
6 | if ((neuer_status ^ step)==(_BV(Schalter_A) | _BV(Schalter_B)))
|
7 | {
|
8 | if ((neuer_status ^ alter_status)==_BV(Schalter_A))
|
9 | richtung +=1; // Es war nach rechts
|
10 | else
|
11 | richtung -=1; // Es war nach links
|
12 | step = neuer_status;
|
13 | }
|
14 | alter_status = neuer_status;
|
15 | }
|
Und hier gemischt mit meinem ASM-Versuch:
; Bits maskieren:
> neuer_status = Geber & (_BV(Schalter_A) | _BV(Schalter_B));
andi TMPI2, 0b00011000
; step laden und ver-xodern, dann mit Bitmaske vergleichen:
> if ((neuer_status ^ step)==(_BV(Schalter_A) | _BV(Schalter_B)))
lds TMPI1, (dseg_encoder+1)
eor TMPI1, TMPI2
cpi TMPI1, 0b00011000
brne t0_ovf_vec_noenc
> {
; Interruptregister laden
lds YL, dseg_buttons
; BT_ROT-Flag setzen; BR_DIR auf 1 (eine Richtung)
sbr YL, (1<<BT_DIR)|(1<<BT_ROT)
; alter_status laden, ver-xodern und mit einem Bit vergleichen:
> if ((neuer_status ^ alter_status)==_BV(Schalter_A))
lds TMPI1, (dseg_encoder+0)
eor TMPI1, TMPI2
cpi TMPI1, 0b00001000
brne t0_ovf_vec_dir
> {
; Richtung ändern (BT_DIR auf 0, andere Richtung eben)
cbr YL, (1<<BT_DIR)
> }
t0_ovf_vec_dir:
; Interruptregister speichern
sts dseg_buttons, YL
> step = neuer_status;
sts (dseg_encoder+1), TMPI2
> }
t0_ovf_vec_noenc:
> alter_status = neuer_status;
sts (dseg_encoder+0), TMPI2
Würd mich freuen, wenn da jemand eine Idee hätte, was hier schief läuft
-.-
Danke für Antworten schonmal und viele Grüße,
Haku