Hallo, ich möchte einen Drehencoder (mechanisch) mit einem PIC 16F628 auswerten. Der Encoder hängt am PortA, am PortB hängen 8 LEDs, von denen jeweils eine leuchtet. Erste Versuche habe ich mit einem Code von Sprut gemacht, aber der funktioniert leider nicht zuverlässig (einzelne LEDs werden übersprungen): http://www.sprut.de/electronic/pic/programm/rotary2/rotary2.html Hat jemand vielleicht schonmal den hier mehrfach erwähnten und wohl sehr zuverlässigen Code von Peter Dannegger für den PIC 16F628 umgeschrieben? Bin dankbar für jede Hilfe. Bernd
Gast
#2284335
Also ich würde mir überlegen, den Encoder vielleicht lieber an die 4 Lower Bits des PORTB zu hängen, weil du dort einen Interrupt auslösen lassen kannst, wenn sich einer der RB0:3 (natürlich als Input konfiguriert) ändert. Das könnte das "Übersehen" von Impulsen reduzieren. Aber im Allgemeinen sind Drehencoder nicht sooo nett, die überspringen gerne mal einen, daher solltest du das bei deiner Auswertung berücksichtigen; siehe dir dazu mal den Wiki-Artikel an: http://www.mikrocontroller.net/articles/Drehgeber Gruß Jens
Gast
#2284376
Ich weiß nicht, ob meine Methode irgendwie verpöhnt ist, ich hab das folgender Maßen gemacht: Diagramm: http://www.reichelt.de/index.html?;ACTION=7;LA=3;OPEN=0;INDEX=0;FILENAME=B400%252FSTEC11B.pdf;SID=323ulPNqwQASAAAEo2Sz4fedeedafe8a74e4bffc78de65e77b735 , Seite 8 oben rechts. Ich überprüfe nur einen der Beiden Eingänge auf eine steigende Flanke (z.B. Leitung A). Wenn im aktuellen Durchlauf der Eingang auf High ist und im vorherigem Durchlauf auf Low war (Variable zum speichern), dann überprüfe den 2. Eingang (Leitung B). Ist Dieser Low, wurde im UZS gedreht und wenn der Eingang High ist, wurde gegen den UZS gedreht. Nach einer Flanke muss lediglich x Millisekunden gewartet werden, um ein Prellen zu unterdrücken. Dabei könnte theoretisch fast eine halbe Periodendauer gewartet werden, was aber ansich unnötig ist. Vorteil finde ich ist, dass man nur einen Eingang pollen und entprellen muss und das die Auswertung ziemlich Simpel ist. Nachteil weiß ich eben nicht, bei mir hats bisher sehr gut funktioniert. Man braucht nur einen Drehimpulsgeber, der soviele Impulse wie Rastungen hat, z.B. STEC11B09: Impulse: 20, Rastungen: 20. Sonst müsste man beide Flanken auswerten.
Gast
#2284390
Ach und .. Jens schrieb: > Also ich würde mir überlegen, den Encoder vielleicht lieber an die 4 > Lower Bits des PORTB zu hängen... Wieso 4? Die haben doch nur 3 Anschlüsse und einer davon ist Vdd bzw. Vss, oder? Ich hab mir das immer so Vorgestellt, dass man 2 Kurzhubtaster hat, die in einer Platte eingelassen sind und dann rollt man mit einem großem Reifen oder großen Rolle einmal von links nach rechts und einmal von rechts nach links rüber. Da kann man dann die Richtung bestimmen, die Anschlüsse sind gleich und Taster prellen auch usw.
Gast
#2284459
ich schrieb: > Ich überprüfe nur einen der Beiden Eingänge auf eine steigende Flanke > (z.B. Leitung A). Wenn im aktuellen Durchlauf..... So mach ich das auch. Kontakt A frage ich im Zeittakt von 1ms ab. 10-20ms ist für normale Tasten besser. Bei Encodern bekommt man aber bei schnellem Drehen Schwierigkeiten mit der Auswertung.
Gast
#2284786
ich schrieb: > Wieso 4? Die haben doch nur 3 Anschlüsse und einer davon ist Vdd bzw. > Vss, oder? Es ging um den PORTB, der hat vier untere Bits, und die sind alle im Interrupt des PORTB-Wechsels drin, das meinte ich. Gruß Jens
Vielen Dank für Eure Antworten. Leider bin ich blutiger Anfänger in Sachen Assemblerprogrammierung für PICs. Ich habe jetzt den ganzen Vormittag verschiedenes ausprobiert, aber alles ohne Erfolg. Hier nochmal der Code von Sprut - im Prinzip funktioniert der ja, nur nicht so zuverlässig. Hat jemand einen Tip, was man da ändern könnte oder vielleicht doch nicht einen anderen zuverlässigen ASM-Code für diese Aufgabe?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | |
166 | |
167 | |
168 | |
169 | |
Gast
#2284855
Also ich bin in Assembler wirklich nicht firm, und wenn du es auch nicht bist, dann gibt es zwei Möglichkeiten: 1. Du lernst Assembler. Dazu gehört es dann unausweichlich, den geposteten Code Befehl für Befehl durchzuackern, und das wird dir niemand abnehmen ;-) 2. Du programmierst in C (so mache ich das bis jetzt) wenn es um zeitunkritische Sachen geht. Schaue mal ins Datenblatt des PIC16F628 und suche dir den Interrupt raus, der die Pins RB4:7 betrifft. Sorry, habe mich oben vertan, es sind nicht die Pins RB0:3. Der Interrupt heißt "PORTB Change Interrupt": Zum Enablen musst du INTCON<4> setzen (RBIE = 1), und das Interrupt-Flag ist dann in INTCON<0>, es heißt RBIF. Denk dran, dass du noch global Interrupts enablen musst mit GIE = 1 bzw. gleichbedeutend INTCON<7> = 1. Wenn du in Assembler programmierst, dann musst du aufs INTCON-Register zugreifen, in C kannst du direkt
1 | |
2 | |
schreiben. May the force be with you. ;-) Gruß Jens
Hi Jens, Danke für Deine Hilfestellung. Ja, Du hast recht - Assembler lernen wäre das solideste. So ganz habe ich das auch noch nicht aufgegeben... Aber ich habe die Sache jetzt auch endlich an's Laufen gebracht: Mein encoder ist nicht zwei- sondern vierschrittig. Habe jetzt einfach mal eine Division durch vier eingebaut und nun klappt es auch zufriedenstellend. Auf den Sprut-Seiten findet sich auch ein weiterer, flexiblerer Code, der auch zweischrittige Encode unterstützt. Den habe ich dann einfach um die zusätzliche Division erweitert. Bernd
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.