andi temp, maske ; Ausmaskieren der Drehgeber Bits
31
mov merker, temp ; Sichern
32
mov merker2, temp ; Sichern
33
cp alt, merker ; Vergleiche merker mit alt
34
brne gedreht ; Wenn ungleich wurde gedreht
35
rjmp main ; Wenn gleich -> Dauerschleife
36
37
gedreht:
38
39
dec zahl
40
out PORTB, zahl
41
rjmp main
42
43
; ldi temp, maske
44
; cp merker, temp ; Beide Werte 1 ?
45
; brne ungleich_1
46
; rjmp weiter
47
48
;ungleich_1:
49
; ldi temp, 0x00
50
; cp temp, merker ; Beide Werte 0 ?
51
; brne ungleich
52
; rjmp weiter
53
;
54
;ungleich:
55
; com merker ; Invertieren
56
; andi merker, maske
57
; rjmp weiter
58
;
59
;weiter:
60
; eor merker, alt
61
; ldi temp, 0b00001000
62
; cp merker, temp
63
; brne rechts
64
; rjmp links
65
;
66
;rechts:
67
; mov alt, merker2
68
; inc zahl
69
; out PORTB, zahl
70
; rjmp main
71
;
72
;links:
73
; mov alt, merker2
74
; dec zahl
75
; out PORTB, zahl
76
; rjmp main
Ich habe ihn momentan zum Testen vereinfacht.
Es soll einfach nur wenn ich eine Taste drücke EINMAL weitergezählt
werden.
Da ab dann der Wert "alt" mit dem Akutellen übereinstimmt sollte er
eigentlich solang in der Main-Schleife im Kreis springen bis sich etwas
ändert!
Im Debugger von AVR-Studio macht er das auch alles so wie es soll...
Wenn ich es aber auf den Controller schreibe und dort Teste, zählt er
solange ich eine Taste drücke (also sich eigentlich nichts verändert?!)
- Wenn ich loslasse gehen alle LED's wieder An (also PortB - 0x00)
Ich benutze das STK500
Was muss ich noch beachten oder was ist in meinem Code falsch?!
Achso, falls jemand "einfachere" oder bessere Methoden hat einen
Drehgeber auszulesen bin gerne offen für - aber ich wollte erstmal
meinen eigenen Weg verfolgen - Learning by doing :-)
Vielen Dank für Antworten
Greez Tobi
Suche hier im Forum mal nach Drehgeber oder bei Google nach Rotary
Encoder.
Da gibt es einige Beispiele wie man einen Drehgeber auslesen kann.
Eine der besten Methoden findest du hier im Forum von Peter Danegger:
Beitrag "Drehgeber auslesen"
Gruss Stefan
Hab noch vergessen, der Code ist in C!
> Hat mir trotzdem jemand eine Antwort warum mein programm nicht will???
Ich sehe ein DEC zahl.
Inkrementiert wird gar nicht.
Was soll da funktionieren ?
Im Übergang von einem Zustand zum anderen ändert sich wegen prellen der
Kontakte das Signal mehrmals. Dann dekrementierst du mehrmals.
> Im Debugger von AVR-Studio macht er das auch alles so wie es soll...
Da prellen Kontakte auch nicht, es sei denn, du simulierst das, durch
wiederholtes Ein- und Ausschalten.
Aber warum machen eigentlich immer alle Leute dieselben Fehler ?
Ist es so schwer, vorher mal zu gucken, wie es richtig geht?
http://dse-faq.elektronik-kompendium.de/dse-faq.htm#F.29
Bei deinem Link ist es richtig erklärt, jedoch ist folgendes falsch:
0: ab (Spur A LOW, Spur B LOW)
1: Ab (Spur A HIGH, Spur B LOW)
2: aB (Spur A LOW, Spur B HIGH)
3: AB (Spur A HIGH, Spur B HIGH)
Zustand 2 und 3 der Signale sind vertauscht.
Richtig wäre die Bitfolge so:
0: ab (Spur A LOW, Spur B LOW)
1: Ab (Spur A HIGH, Spur B LOW)
2: AB (Spur A HIGH, Spur B HIGH)
3: aB (Spur A LOW, Spur B HIGH)
An sonsten ist das eine sehr gute Erklärung!
Es gibt auch Drehgeber die Zusätzlich noch eine "Null"-Markierung haben.
Da wird ein 3. Ausgang 1x pro Umdrehung gesetzt, zum Abgleich mit den
Softwarezählern. Da kann dann (fast) nichts mehr schief gehen und es ist
auch nicht so schlim wenn man mal 1 oder 2 Schritte/U nicht mitgezählt
hat, denn es wird ja nach jeder Umdrehung abgeglichen ;)
Gruss Stefan
Die Beschreibung passt schon, denn es ist zunächstmel eine Aufzählung
der möglichen Zustände, nicht die Reihenfolge beim Drehen. Derzeit ist
die Reihenfolge nach binärer Wertigkeit der Eingänge.
Die Frage wäre, ob zu dieser Definition die Beschreibnng darunter passt.
Sie passt. Also ist die Zustandsbeschreibung korrekt.
Ich kann zur Kenntnis nehmen, dass du die Auflistung der möglichzen
Zustände schon in der Reihenfolge der Zustände beim Drehen sehen willst.
Das hat was für sich, zumindest wennn man gleich daneben zeichnet, bei
welcher Drehrichtung es sich ergibt.
Naja, wenn man die Zustände schon Durchnummeriert, sollten sie (meiner
Meinung nach)auch in der richtigen Reihenfolge da stehen, sonnst gibt es
hinterher vieleicht Verständnissprobleme.
Ein "Neuling" (der nicht in sein Datenblatt geschaut hat) wird dann auch
nicht interpretieren können, wie er die Drehrichtung auswerten kann.
Gruss Stefan
Im Übergang von einem Zustand zum anderen ändert sich wegen prellen der
Kontakte das Signal mehrmals. Dann dekrementierst du mehrmals.
Ein Taster prellt aber nicht 10sec lang :-)
Warum ich nicht Inkrementiere?
Weil ich wie gesagt das Programm wegen diesem Problem verkürzt hab und
einfach nur sehen wollte wo er nicht das tut was ich will ...
Und ich sehe das er auch wenn keine Änderung zum vorigen Zustand (trotz
Prellen - welches aber niemals SOOO lange und SOOO oft ist)
weiterzählt...
Danke aber für die Links und erklärungen - will aber trotzdem schaffen
meienn Ansatz weiter zu bekommen - und ich denke das Prellen kann ich
ausschließen ... wo könnte der fehler noch liegen?!
Danke :-)
Ich hab dein Programm mal kopiert und im Simulator getestet. Da sieht es
wirklich gut aus, also theoretisch funktioniert es.
Mess doch mal die Spannungen an den beiden Eingängen. wenn kein Taster
gedrückt, sollte sich die Spannung bei ca. 4,9V befinden.
Bei gedrücktem Taster sollten 0V anliegen.
Wenn irgendwas dazwischen gemessen wird, stimmt entweder die Schaltung
nicht (Taster muss gegen GND schalten^^) oder dein Taster ist nicht in
Ordnung, also hochomig. Im Datenblatt des MC steht, ab welcher Spannung
High und unter welcher Spannung Low erkannt wird. Alles dazwischen ist
unzulässig, denn dann wäre ein unbestimmter (zufälliger) Zustand im
Register PinD. Dadurch würde sich die Zählerei erklären.
Was passiert denn, wenn du die Taster komplett abhängst und nur die
Pull-Ups einschaltest? Zählt er dann immer noch?
Gruss Stefan
Ich hab einen Drehgeber mal ausgelesen mit einem Siemens C161. Der Hatte
externe Interrups mit fallender und steigender Flanke.Den hab ich an
Ausgang A des drehgebers gelegt. B an einen anderen Pin.
Es geht auch mit 2 Interrupteingängen wenn nur auf eine Flanke
getriggert werden kann.
void resolver_trap(void) interrupt 0x1A//bei pos. und neg. Flanke von A
{
#define TIM_COUNT 0xFFFF-18430
static uint old_system_counter;
static uint old_tim_counts;
uint system_counts;
static ulong speed_counts;
if((P2&0x0400)==0){//A=0?
if((P3&0x0010)==0)res_pos--;//A=0,B=0,runterzählen
else res_pos ++;//A=0,B=1,raufz.
}
else{if((P3&0x0010)==0)res_pos++;//A=1,B=0,raufzählen
else res_pos --;//A=1,B=1,runterz.
}
system_counts=(system_counter-old_system_counter);
speed_counts=(ulong)((ulong)(T2-old_tim_counts)+(ulong)(TIM_COUNT*system
_counts));
old_system_counter=system_counter;
old_tim_counts=T2;
}
Grüße Gebhard
Danke für deinen Tipp...
Das ist es aber leider nicht.. wie gesagt nutze ich z.Z. das STK500 -
Hab die OnBoard verfügbaren Taster genommen - und die auch mal überprüft
- Funktionieren einwandfrei oO ...
Dann hab ich auch mal externe Taster genommen - da auch - sobald ich
etwas drücke Zählt er wenn ich nichts Drücke passiert auch nichts...
Auch wenn ich einfach einen Drehgeber einbaue funktioniert es nicht...
*verwirrt bin und nachher nommal ne Stunde rumprobier -.- *
Kann an dem Programm auch nichts finden, was mich stören würde. Meiner
Meinung nach müsste es funktioniereen.
Bist du sicher, dass du das richtige Programm geflasht hast?
Ansonsten lass dir doch einfach mal alt oder merker am Port ausgeben und
sieh nach, was sich da ständig ändert, wenn du eine Taste drückst.
Vieleicht hat auch der Drehgeber ne Macke? Ich hab mal EWIG (gefühlt)
nach dem Fehler in einer Verstärkerschaltung gesucht warum der eine
Kanal (obwohl identisch aufgebaut) nicht funktionieren wollte, bis ich
dann einfach mal ein anderes Stereopoti genommen habe und auf einmal
alles lief ;)
Ich hab jetzt mal den merker2 komplett raus getan weil ich gemerkt habe,
dass dieser unnötig ist - jetzt zählt er sozusagen kurz eins hoch
(taster bleibt gedrückt) und geht sofort wieder auf null...
Irgendwo wird "zahl" resettet aber wo und warum?!
Nochmal der Quellcode:
1
.include "m8515def.inc"
2
3
.set maske = 0b00001100 ; Drehgeber Bits
4
.set DrehPort = PIND ; Drehgeber Port
5
6
.def temp = r16
7
.def merker = r17
8
.def alt = r18
9
.def zahl = r19
10
11
ldi temp, LOW(ramend)
12
out SPL, temp
13
ldi temp, HIGH(ramend)
14
out SPH, temp
15
16
ldi temp, 0x00
17
out DDRD, temp ; Port D als Eingang
18
mov merker, temp ; Alt auf 0
19
20
21
ldi temp, 0xff
22
out DDRB, temp ; Port B als Ausgang
23
out PORTD, temp ; PullUP Aktivieren
24
mov zahl, temp
25
out PORTB, zahl
26
27
main:
28
in temp, DrehPort ; DrehPort einlesen
29
com temp ; Invertieren -> Bessere Anschaulichkeit
30
andi temp, maske ; Ausmaskieren der Drehgeber Bits
31
mov merker, temp ; Sichern
32
cp alt, merker ; Vergleiche merker mit alt
33
brne gedreht ; Wenn ungleich wurde gedreht
34
rjmp main ; Wenn gleich -> Dauerschleife
35
36
gedreht:
37
38
mov alt, merker
39
inc zahl
40
out PORTB, zahl
41
rjmp main
Natürlich noch gekürzt weil erstmal die Grundfunktion laufen soll danach
kommt dann irgenwann der Teil mit dem eigentlichen Drehgeber...
Tobias Binkowski schrieb:
> Ich hab jetzt mal den merker2 komplett raus getan weil ich gemerkt habe,> dass dieser unnötig ist - jetzt zählt er sozusagen kurz eins hoch> (taster bleibt gedrückt) und geht sofort wieder auf null...
Die einzige Möglichkeit, wo Zahl auf einen bestimmten Wert gesetzt wird,
ist am Anfang in der Initialisierung.
D.h. die Initialisierung wird erneut durchlaufen, was wiederrum heißt,
dass dein µC das Programm von vorne abarbeitet, was wiederrum bedeutet
das der µC resettet wurde. Das könnte zb sein, wenn du mit dem Taster
einen Kurzen gebaut hast.
Die Darstellung von Zahlen im 2-er Komplement hat eine sehr nützliche
Eigenschaft. Differenzen funktionieren immer, auch bei Überlauf.
Nehmen wir als Beispiel den Überlauf von 127 nach -128, jetzt rechnen
wir also: -128 - 127 = 0x80 - 0x7F = 1
D.h. wenn wir 2 aufeinanderfolgende Zahlen subtrahieren, stimmt das
Ergebnis immer.
Nun gibt es ne kleine Aufgabe, ein Encoder liefert keine Binärzahlen,
sondern Graycode. Das hat den Vorteil, daß es keine falschen Codes gibt.
Schauen wir uns also mal 2 Bit als Graycode und als Binärzahl an:
1
Gray Binär
2
0 0 0 0
3
0 1 0 1
4
1 1 1 0
5
1 0 1 1
Wie man leicht sieht, läßt sich Gray sehr einfach nach binär umwandeln,
einfach das 0. Bit umdrehen, wenn das 1. gesetzt ist.
Das ist das ganze Geheimnis meines sehr einfachen Codes und warum er
sicher entprellt.
Peter
Ah wie geil - Ich flipp gleich aus...
Es lag nicht an den Tastern und nicht am Code...
Bah eigentlich sollte ich solche fehler aus erfahrung immer als erstes
ausschließen aber ich hab nicht dran gedacht.. mein ATMega (der schon
laaange zeit als experimentier stein herhält) hat irgend einen Schuss
gehabt - IC getauscht - Funktioniert -.- oh man .. :-) *jetz dafür
rumjubel*
Trotzdem allen ein Danke die mir den ein oder anderen neuen Link gezeigt
haben...