07.12.2011
|
Drehgeber
am Atmega 32 anschließen !
|
Ein
Drehgeber sieht in
seiner einfachsten Form in der Regel wie ein Potentiometer aus ,also
etwa
wie ein Lautstärkeregler
am Radio, nur besteht der
Drehgeber nicht wie das
Potentiometer aus
einen Widerstand sondern im einfachsten Fall aus einen oder auch
mehreren Schalter (Kontakte) die bei einer
Umdrehung
immer wieder geöffnet und
geschlossen werden .
So
entstehen
bei einer Achsen Umdrehung eine genau festgelegte Anzahl von Impulse,
der von mir verwendete Drehgeber weist aber zwei interne Schalter
auf,
deren Kontakte mit Kanal A und Kanal B bezeichnet sind die genau um
90° versetzt Öffnen und Schließen, so kann der
Prozessor durch
geschickte Auswertung erkennen
ob sich der Drehgeber links oder rechts
herum dreht und anhand der vom Hersteller festgelegte feste Anzahl von
Impulse pro Umdrehung ,ist es auch möglich eine
Streckenmessung damit
vorzunehmen.
|
|
Die
meisten Drehgeber in ihrer einfachsten Ausführung besitzen zwei
Schalter und somit drei Anschlüsse.
Kontaktmitte , Kanal A und Kanal B.Die Kontakte sind genau um 90°
versetzt.
Mein erster
Versuch den Drehgeber an einen Normalen Pin
anzuschließen hat keinen großen Erfolg weil die
Zählung sehr ungenau ist,
so das man mit den Impulse nicht viel
anfangen kann weil der Drehgeber beispielsweise eine 1 hat und beim
Schaltvorgang nur sehr kurzzeitig auf 0 und dann wieder auf 1 springt,
ist der Prozessor nicht immer in der Lage den kurzzeitigen Unterschied
zu registrieren , weil er ja erst die Loop Phase ( also die eigentliche
Programmschleife )durchlaufen muss,
und
je nach dem wann er in seiner Schleife den Pin abfragt, er einmal den
Wechsel registriert und ein anderes mal eben nicht .
|
Also versuche ich die
Möglichkeit mit
externen Interrupts die Sache zu realisieren.
Der Atmega 32 stellt zwei
Interrupt Eingänge für Externe Interrupts zu Verfügung,
und zwar an den Anschlussbeinchen 16 (Interrupt 0) und 17 (
Interrupt 1).
Bei den Interrupt Eingänge wird nicht wie bei den
Standard Eingänge der Eingang innerhalb einer Schleife
ständig abgefragt, sondern sie arbeiten völlig
unabhängig der
Programmschleife, und halten die Programmschleife
bei Aktivierung sofort an und springen in das für sie vorgesehenes
Unterprogramm arbeitet dieses ab,
und lassen dann die Programmschleife
wieder laufen.
Das hat den Vorteil das sie sehr schnell und direkt
Einfluss auf das Programm nehmen.
|
|
|
Programmzeile
|
Beschreibung |
$regfile
"m32def.dat"
|
Definiert den Atmega als
Atmega 32 |
$crystal
=
1000000 |
Gibt die Quarzfrequenz an in
Herz |
$hwstack
=
32
|
Defaultwert 32 für
den Hardware Stack |
$swstack
=
10
|
Default 10 für den
Software Stack
|
Config
Lcd = 16 * 2 |
Definiert das LCD Display
als 2 Zeilen mal 16 Zeichen
|
Config
Lcdpin = Pin ,
Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.6 , Db7 = Portc.7 , Rs =
Portc.5 , E = Portc.4 |
Konfiguration fürs
Display Pin Anschlüsse
|
Dim
Kanal_aa As Byte |
Variable für Kanal A
|
Dim
Kanal_bb As Byte |
Variable für Kanal B
|
On
Int0
Kanal_a |
Interrupt Routine für
Interrupt 1 festlegen |
On
Int1
Kanal_b
|
Interrupt Routine für
Interupt 2 festlegen |
Portd
=
&B00001100 |
Pull Down an für
Interrupt Eingänge
setzen
|
Mcucr
=
&B00001010 |
Interrupts sollen auf H/L
Flanke reagieren |
Gicr =
&B11000000 |
Interrupt 0 und 1 einschalten |
Sreg.7
=
1 |
Interrupts Global freischalten |
Do |
Anfang Hauptprogramm
|
Gosub
Anzeige |
|
............
|
Platz für weitere
Programmzeilen
|
Loop |
Ende Hauptprogramm
|
|
|
Anzeige: |
Unterprogramm Displayanzeige
|
Cls
|
Display Löschen |
Locate
1 , 1 |
Definiert Displayausgabe Zeile
1 Spalte 1
|
Lcd "A
= " ; Kanal_aa |
Displayausgabe der Variable
für Kanal A
|
Locate
1 , 10 |
|
Lcd "B
=" ; Kanal_bb |
|
Locate
2 , 1 |
|
Waitms
50 |
|
Return |
Unterprogramm Ende und
zurück zum Aufruf
|
|
|
Kanal_a:
|
Unterpogramm wird bei
Interrupt 0 angesprungen
|
Kanal_aa
=
Kanal_aa
+
1
|
|
If
Pind.2 = 0 And Pind.3 = 1 Then Kanal_aa = Kanal_aa - 1
|
|
If
Pind.2 = 0 And Pind.3 = 0 Then Kanal_aa = Kanal_aa + 1
|
|
Return
|
Unterprogramm Ende
|
|
|
Kanal_b: |
Unterprogramm wird bei
Interrupt 1 angesprungen
|
Kanal_bb
=
Kanal_bb
-
1 |
|
Return |
Unterprogramm Ende
|
Drehrichtung des
Drehgebers feststellen !
|
|
Wie erkennt man nun
ob der Regler rechts oder links herum gedreht wird ?
Wie gehen einmal von einen fiktiven Anfangswert aus, beispielsweise die
grüne senkrechte gepunktete Linie, weiter haben wir im Programm
angegeben das
die Erkennung des Schaltvorganges vor sich gehen soll wenn eine Flanke
von 1 nach 0 statt findet.
Wie gehen also davon aus das wir den Drehregler links herum drehen,
dann wird die nächste Flanke von H nach L an der Blauen
senkrechten Linie erkannt, wenn wir dann minimal weiter drehe, haben
wir am Kanal A=0 und Kanal B=0
Würden wir von der Grünen Linie aus rechts herum drehen so
würde die nächste Flanke von 1 nach 0 an der Roten Linie
erkannt und wir hätten im weiteren Verlauf am Kanal A =0 und am
Kanal B=1
Wir stellen also fest !
Liegt an Kanal A eine Null und an Kanal B eine Null , so
drehen wir links herum, haben wir am Kanal A eine Null und am Kanal B
eine Eins dann drehen wir rechts
herum
|
Aktualisiert 23.03.2014
|
Copyright by ms 2009
|