Hallo,
die Suche brachte mich leider nicht zu dem Encoder den ich benötige.
Es ist also ein "Drehschalter" der 2 Ausgänge besitzt.
Von Stellung zu Stellung wechselt er von 0 0 auf 1 1, dann wieder auf 0
0
entscheidend ist, welcher Ausgang zuerst das Signal wechselt. also 0 1
oder 1 0 (in der Zwischenstellung)
Der Encoder ist an RC0 und RC1
Mein Ansatz sieht so aus:
read_encoder
movf PORTC,0 ;Port C nach W
movwf neu ; aktuelle encoder-Stellung nach neu
movlw B'00000011'
andwf neu, 1 ;nur 1. und 2.Bit stehen lassen und speichern
MOVF alt ;alt nach w
xorwf neu,0 ;alt und neu vergleichen, Wert bleibt in W
ADDWF PCL ;PROGRAMMZEIGER ÄNDERN 0 BIS 4
Goto weiter ;W=0 (alt und neu ist gleich)
Goto links ;W=1 (1.bit gesetzt)
Goto rechts ;W=2 (2.Bit gesetzt)
Goto weiter ;W=3 (würde passieren wenn der zwischenschritt
überspungen ist)
Irgend einen fehler muss ich mit der verknüpfung gemacht haben, da der
Programmzeiger vermutlich an eine ganz andere Stelle springt sobald ich
am Encoder drehe.
Am ende will ich dann noch in "links" und "rechts" prüfen ob die
Stellung von 00 zu 11 oder umgekehrt stattgefunden hat um prellen zu
verhindern.
Vielen Dank für einen Hinweis oder gar eine bessere Programmlösung.
Ja - hallo auch,
also ich vermute mal folgendes:
Der 'computed goto' hat das Problem, dass PCLATH nicht richtig vorbelegt
wird. Das passiert immer, wenn genau ein 256-Bytes Umbruch zwischen den
nachfolgenden GOTOs existiert. Daher muss man genau drauf achten, dass
alle GOTOs immer in der 256-Bytes PAGE liegen, in der auch der ADDWF
PCL,1 liegt.
Das wäre der erste Ansatz. Nun der nächste:
Wenn es sich bei der Routine 'read_encoder' um eine Unterfunktion
handelt,
dann muss in den Routinen 'weiter', 'links' und 'rechts' ein 'return'
stehen und nicht ein GOTO xyz. Das ist auch ein häufig gemachter Fehler.
Jetzt eine andere Frage:
Wieso nutzt du nicht den onChange-Interrupt um die Auswertung
durchzuführen?
Irgendwo hier im Forum gibts auch eine 'Anleitung' zur Auswertung eines
Encoders. Ist zwar für den ATMEL (muss man also nicht unbedingt
verstehen) - aber die Logik ist für beide Controller die gleiche. Da
kann man sich ja mal was abschauen.
Gru0
TK
Hallo TK
Also an der 256-Bytes PAGE liegt es nicht, hätte ich aber auch
übersehen.
Nach Goto kommt dann allerdings wieder ein Goto, danach aber Return.
Was ich jetzt festgestellt habe, der Fehler tritt schon nach dem
einschalten auf, wenn der Encoder in einer bestimmten Stellung steht (00
oder 11 müste ich mal prüfen) sonnst erst wenn ich drehe.
Der Drehgeber sowie die serielle Schnittstelle werden in einer Schleife
abgefragt. Der Drehgeber hat nicht die Priorität und ich wollte die
Abfrage nicht mit einem interrupt unterbrechen, aber das wäre ja immer
noch möglich wenn es funktionieren würde.
Wäre denn das Programm so logisch richtig?
Bin da leider nicht so der Profi.
Gruß Mario
Jo, dann fragen wir uns jetzt mal, wie sich denn der Fehler äußert???
Der Code scheint generell zu funktionieren (soweit dies der
Codeschnipsel zulässt).
Serielle Schnittstelle?
Fragst du die im Polling-Mode ab?
Jetzt fällt mir dann noch das 'Read-Modify-Write' Problem ein. Wobei das
hier eigentlich nicht zum Tragen kommt, da RC0,1 ja immer ein INPUT ist,
oder?
Gruß
TK
Nachtrag:
VORSICHT: Die PAGE und die 256-Bytes Grenze sind NICHT das gleiche!!!
Eine PAGE kann bis zu 2k groß sein!
Hier muss man genau unterscheiden!
Gruß
TK
vielen Dank für die schnellen Antworten.
in der Programmzeile;
ADDWF PCL ;PROGRAMMZEIGER ÄNDERN 0 BIS 4
liegt der Code bei 0x54
das kann es also nicht sein.
Die anderen Programmteile laufen ohne Probleme.
An Port C ist derzeit auch nicht weiter drann oder im Programm schon was
vorgesehen.
An Port B hängt ei Display und an RA0 ein Temp.-Fühler.
In das UP welches ich oben abgebildet habe, hatte ich vorher einen
Programmcode von Sprut.de (angepasst). Vom Prinzip hat das auch
funktioniert, nur das mein Encoder halt gleich 2x gezählt hatte wenn man
langsamm dreht. Die andere Richtung ging mehr recht als schlecht.
Den Fehler sehe ich darann, das der Begrüßungstext plötlich in der 2.
Zeile auftaucht. Also muss der Fehler irgendwie mit dem Programmzeiger
zusammenhängen, denn ein Zählwert von dem Encoder sollte in der 2.Zeile
zum testen erscheinen. Das macht er auch kurz, aber der Zähler wird
nicht geändert, so das die UPs LINKS und RECHTS vermutlich gar nicht
angesprungen werden.
Wenn ich direkt auf den Programmzeiger zugreife, passiert denn dann noch
was? Der obere Schnipsel wird übrigens auch per Call angesprungen.
Die serielle Schnittstelle wollte ich per Polling abfragen, aber so weit
bin ich noch nicht.
ich bins gerade noch mal durchgegangen
die Zeile wo ich den RCL ändere steht bei 0159h
W ist vermutlich 0 und er springt dann zu 0060h
das versteh ich nicht!
Ich kann die Simulation zwar nich im ganzen Programm laufen lassen, aber
da käme genau das raus was ich im Display sehe, nämlich noch mal der
Begrüßungstext.
hmmmm
Antworte ich mir mal selber.
Also wie oben schon beschrieben, lag es doch darann das ich in das UP
per Call bin und das UP in einem anderen Block lag.
Vom Prinzip war es erst mal ok.
Nun habe ich den Code eingekürzt und das klappt auch sehr gut....aber
andere UP brauchen zu lange damit ich keine Drehung "übersehe".
UND was noch viel schlimmer ist, ich warte in "weiter" darauf das der
Encoder auf 11 oder 00 steht. Das sind zwar auch nur ms aber das ist
nicht gerade schön. ABER IRGEND EINE ENTPRELLUNG / SICHERHEITSABFRAGE
MUSS DA REIN.
Hier noch mal der neue Code:
read_encoder
movf PORTC,0 ;Port C nach W
andLw B'00000011' ;rest ausblenden
xorwf alt,0 ;vergleiche mit alt
ADDWF PCL,1 ;PROGRAMMZEIGER ÄNDERN 0 BIS 4
Return
Goto links
Goto rechts
Goto weiter
rechts
incf counter, f ; rechts: increment counter
goto weiter
links
decf counter, f ; links: decrement counter
weiter movf PORTC,0 ;Port C nach W
andlw B'00000011'
ADDWF PCL,1 ;PROGRAMMZEIGER ÄNDERN 0 BIS 4
Goto ende
Goto weiter ;Encoder steht noch in mittelstellung
Goto weiter ;Encoder steht noch in mittelstellung
Goto ende ;könnte ich weglassen, nur zur verständniss
ende movwf alt ; für nächsten Vergleich als alt speichern
return
Also jede bessere Lösung ist Willkommen!!!!!
Hallo Mario,
hatte gestern keine Zeit mehr.
Also folgendes:
Wenn der Programmzaehler bei $0159 steht und der goto auf $0060 springt,
liegt das am PCLATH-Register. Das ist nämlich noch $00 und daher geht
der
goto in die Hose. Abhilfe: VOR dem ADDWF PCL,1 muss ein - sagen wir mal
-
'movlw high(rechts)'
'movwf PCLATH'
stehen. Man muss jetzt noch gewährleisten, dass 'rechts', 'links' und
'weiter' in der GLEICHEN 256-Bytes-Page stehen. Dann geht der goto auch
nach $0160 und nocht nach $0060.
Gut, nächstes Problem:
Ich finde es überhaupt nicht lange, wenn einige ms gewartet wird, bis
der
Encoder nicht mehr prellt. Man sollte mal im Datenblatt nachsehen, wie
gross die max. Prelldauer den ist. Das geht manchmal schom bis 200ms.
Also, wenn das keine 'Hochgeschwindigkeitsanwendung' werden soll, was ja
alleine schon wegen dem Display nicht geht, dann nimm die Zeit einfach
als gegeben hin.
Gruß
TK