Hallo,
Eigentlich reicht dafür ein Interrupt aus. Eines der Signale schließt du an einen Interrupt-Eingang (am besten mit Flanken-Erkennung), das andere an einen ganz gewöhnlichen Eingang. Bei Eintreten des Interrupts schaust du in der Interrupt-Routine nach, ob der andere schon High, bzw. Low ist. Daraus kannst du die Drehrichtung bestimmen.
Diese Methode ist schön einfach und funktioniert einwandfrei.
Aber man erhält damit nur ein Viertel der möglichen Auflösung des Drehgebers.
Eine "volle" Auswertung der Drehgebersignale erfordert etwas mehr Aufwand.
Das lässt sich mir einem AVR am einfachsten und mit der geringsten Rechenzeit
mit einer kleinen State-Machine realisieren.
Gruß Jan
Code:
;für Atmel AtMega8
;Codebeispiel für vollständige Drehgehberauswertung.
;Die Signale A und B des Drehgebers
;sind an PortD Bit0 und Bit1 angeschlossen.
;in dgpos (R17) steht die aktuelle Drehgeberposition (8-Bit weit) .
.NOLIST
.INCLUDE "m8def.inc"
.LIST
.DEF temp = r16
.DEF dgpos = r17 ;Drehgeberposition
.DEF ast = r18 ;alter Zustand Drehgeber
dgstart:
ldi temp,0b00000011
out ddrd,temp ;Portd 0 und 1 auf Ouput setzen, Rest Input
in ast,portd ;einmal den aktuellen PortZustand holen
andi ast,0b00000011 ;Drehgeber-Bits maskieren
clr dgpos ;Drehgeber-Position auf 0 setzen
dgloop: in temp,portd ;aktuellen PortZustand holen
andi temp, 0b00000011 ;Drehgeber-Bits maskieren
lsl ast ;*2
lsl ast ;*2
add ast,temp ;alter Zustand mal 4 plus neuer Zustand
ldi ZL,low(dgtab<<1) ;Zeiger Z auf Tabellenanfang setzen
ldi ZH,high(dgtab<<1)
add ZL,ast ;zum Zeiger addieren
clr ast
adc ZH,ast
lpm ;Tabelleneintrag holen
add dgpos,r0 ;auf Position draufaddieren
mov ast,temp ;neuer Zustand wird alter Zustand
rjmp dgloop ;fertig
;Diese Tabelle enthält die Positionsänderungen
;des Drehgebers entsprechend der Zustandsänderungen
;der Drehgebersignale.
dgtab: .db 0,1,-1,0
.db -1,0,0,1
.db 1,0,0,-1
.db 0,-1,1,0
;Ende
Lesezeichen