Hallo Hanno,
Ich habe den Code für den Atmega8 angepasst,
Das Codefragment war als Beispiel gedacht um es zu analysieren,
die Methode zu verstehen, und dann selbst zu verwenden.
Und nicht, um es 1:1 zu übernehmen. Aber egal.
Leider funktioniert das ganze nicht
Das Beispiel hat den Anschluss des Drehgebers an den Bits 0 und 1 des Ports vorgesehen.
Du hast sie jedoch an den Bits 2 und 3 angeschlossen.
Da müssen die Bits im Register noch um zwei Bits nach rechts verschoben werden, damit es funktioniert.
Das mit der Tabelle verstehe ich auch nicht so ganz
Also diese Methode funktioniert folgendermassen:
Die Signale A und B des Drehgebers können genau vier verschiedene
Zustände annehmen: 00, 01, 10, 11.
Das entspricht den Binärwerten 0 bis 3.
Das Gleiche gilt natürlich auch für die "alten" Drehgeberwerte.
Zur Auswertung müssen die "neuen" und die "alten" DG-Werte miteinander verglichen werden.
Jeder der beiden Werte kann wie gesagt einen von vier verschiedenen Zuständen haben.
Der Vergleich kann also genau 4 mal 4 also 16 Kombinationen ergeben.
Für jede dieser 16 Kombinationen gilt es zu entscheiden,
ob der Zähler stehen bleibt (+0), oder ob er vorwärts (+1), oder rückwärts (-1) zählen muss.
Diese Entscheidungsmatrix ist die Tabelle dgtab.
Sie besteht aus 4 Zeilen a' 4 Spalten, enthält also 16 Werte.
Jede Zeile steht für einen "alten" DG-Zustand.
Jede Spalte steht für einen "neuen".
Der Tabelleneintrag (0 oder 1 oder -1) im Schnittpunkt
von "alter Wert" und "neuer" Wert ist der Zählerschritt,
der einfach auf den Zähler aufaddiert wird.
Wie findet das Progrämmchen den richtigen Tabelleneintrag ?
1. Es wird ein Zeiger (ZH,ZL) auf den Anfang der Tabelle gesetzt.
2. Es wird der "alte" DG-Zustand mal 4 genommen und auf den Zeiger addiert.
Der Zeiger zeigt jetzt auf den Anfang der richtigen Zeile.
3. Es wird der "neue" DG-Wert auch auf den Zeiger addiert.
Jetzt zeigt der Zeiger auch auf die richtige Spalte innerhalb der Zeile.
Der Tabellenwert (0 oder 1 oder -1), auf den der Zeiger jetzt zeigt,
wird ausgelesen (lpm) und zum Zähler addiert.
Jetzt muss nur noch der "neue"DG-Wert zum "alten DG-Wert werden,
und fertig.
Das war jetzt wirklich ausführlich, meine ich.
Diese Methode realisiert eine vollständige Auswertung des DG-Signales.
D.h. Bei einem Drehgeber mit nominal 100 Imp/Umdrehung wird eine
Umdrehung auf 400 Positionen aufgelöst.
Ich nehme an, du bist noch Einsteiger in der Assembler-Programierung.
Dann solltest dir das Beispiel ansehen, und versuchen zu verstehen,
wie es funktioniert, dann kannst du es beliebig selbst anwenden.
Nur Abtippen bringt dich nicht viel weiter.
Ich habe deinen Code etwas angepasst so das er funktionieren müßte.
Was ist das eigentlich für ein Drehgeber, den du da verwendest, und was
willst du eigentlich damit machen ?
Warum soll die LED gerade bei Zählerstand 4 leuchten ? Und nur da ?
Gruß Jan
Code:
;für Atmel AtMega8
;Signale A und B sind an PortD Bit2 und Bit3 angeschlossen
;Es wird 8 Bit weit gezählt mit dem Zähler cnt
.NOLIST
.INCLUDE "m8def.inc"
.LIST
.DEF temp = r16
.DEF cnt = r17 ;der Zähler
.DEF ast = r18 ;alter Zustand Drehgeber
.DEF temp2 = r19
dgstart:
ldi temp,0b11000000
out ddrd,temp ;Portd 6/7 auf Ouput setzen, Rest Input
in ast,portd ;einmal den aktuellen PortZustand holen
andi ast,0b00001100 ;Drehgeber-Bits maskieren
lsr ast ;DG-Bits in POsition 0 und 1 schieben
lsr ast
dgloop: in temp,portd ;aktuellen PortZustand holen
andi temp, 0b00001100 ;Drehgeber-Bits maskieren
lsr temp ;DB-Bits in Pos. 0 und 1 schieben
lsr temp
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 cnt,r0 ;auf Zähler draufaddieren
mov ast,temp ;neuer Zustand wird alter Zustand
cpi cnt,4 ;Counter==4 ?
brne dgloop ;nee
ldi temp,0b10000000 ;LED schalten
out portc,temp
rjmp dgloop ;fertig
dgtab: .db 0,1,-1,0
.db -1,0,0,1
.db 1,0,0,-1
.db 0,-1,1,0
;Ende
Lesezeichen