![[Rozmiar: 10329 bajtów]](naglowek.gif)
![[Rozmiar: 5166 bajtów]](enkoder.jpg)
Jeśli ktoś chce użyć enkodera obrotowego to wie do czego służy i nie będę się nad tym rozwodził.
Omówienia warte są tylko sprawdzone sposoby ich obsługi. Tańsze enkodery bowiem potrzebują najczęściej specjalnego traktowania :) Pierwsze rozwiązanie to małe rozwinięcie metody zaprezentowanej na stronie Mirley - obsługa impulsatora. Sprowadzenie pinów wejściowych impulsatora do stanów dwóch najmłodszych bitów pozwoliło na pozbycie się instrukcji And (kompilator generuje krótszy kod nawet jeśli zamiast niej użyje się dwóch If`ów - nie w tym przypadku). Działa bardzo przyzwoicie. Pomiędzy wyjścia Impulsatora a masę podłączone mam kondensatory 22nF.
$regfile = "m328pdef.dat" 'register file for ATmega328p
$crystal = 8000000 '8MHz crystal
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.0 , Rs = Portc.0
Config Lcd = 20x4
Cursor Off Noblink 'nowy sposób zapisu
Cls
Portd = 255
Dim Tryb As Byte , Rezultat As Integer
Dim Zmienna As Word
Dim Enc As Byte
Lcd "Licznik:"
Do
Gosub Impulsator
If Rezultat <> 0 Then
Zmienna = Zmienna + Rezultat
Locate 1 , 10 : Lcd Zmienna ; " "
Rezultat = 0
End If
Waitms 1
Loop
End
'--- sub enkodera 1 ---
Impulsator:
Enc.0 = PIND.2
Enc.1 = PIND.3
Rezultat = 0
Select Case Tryb
Case 0:
If Enc = 3 Then Incr Tryb 'jeżeli dwa rozwarte
Case 1:
If Enc = 2 Then Tryb = 2
If Enc = 1 Then Tryb = 3
Case 2:
If Enc = 1 Then
Rezultat = 1
Tryb = 0
End If
Case 3:
If Enc = 2 Then
Rezultat = -1
Tryb = 0
End If
End Select
Return
Drugi sposób oparty jest o sprawdzanie stanu drugiego pinu enkodera jeśli pierwszy wywoła przerwanie zewnętrzne. Wymaga więc podłączenia do pinu który potrafi zgłaszac przerwanie np. INT0 lub INT1. Jeśli z przyczyn rozkładu pinów w Twoim projekcie nie masz już dostępu do pinów przerwania KONIECZNIE zobacz mój wpis na temat PCINT - przerwań wywołanych zmianą stanu na pinie.
$regfile = "m328pdef.dat" 'register file for ATmega328p
$crystal = 8000000 '8MHz crystal
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.0 , Rs = Portc.0
Config Lcd = 20x4
Cursor Off Noblink 'nowy sposób zapisu
Cls
' config for encoder
Config Portd.2 = Input : Portd.2 = 1 : Encoder_a Alias Pind.2
Config Portd.3 = Input : Portd.3 = 1 : Encoder_b Alias Pind.3 'to też pin INT1
Config Int1 = Rising 'przerwanie generować będzie rosnące zbocze
Enable Int1 : On Int1 Encoder_isr Nosave
Dim Encoder_turn_left As Byte , Encoder_turn_right As Byte
'-------------------------------------------
Dim Zmienna As Word
Enable Interrupts
Lcd "Licznik:"
Do
'encoder turns left
If 0 < Encoder_turn_left Then
Decr Encoder_turn_left
'tutaj Twój kod -
Decr Zmienna
Locate 1 , 10 : Lcd Zmienna ; " "
Eifr.intf1 = 1
'Gifr.intf1 = 1 'dla Mega8, M32 itp
Enable Int1
End If
If 0 < Encoder_turn_right Then
Decr Encoder_turn_right
'tutaj Twój kod +
Incr Zmienna
Locate 1 , 10 : Lcd Zmienna ; " "
Eifr.intf1 = 1
'Gifr.intf1 = 1 'dla Mega8, M32 itp
Enable Int1
End If
Loop
End
'tutaj obsługa przerwania zewnetrznego z enkodera
Encoder_isr:
$asm
PUSH R23
PUSH R24
PUSH R26
PUSH R27
!in R24, sreg
PUSH R24
$end asm
Disable Int1
If Encoder_a = 1 Then
Incr Encoder_turn_right
Else
Incr Encoder_turn_left
End If
' Tuned with NoSave Tool
$asm
POP R24
!out sreg, r24
POP R27
POP R26
POP R24
POP R23
$end asm
Return
Ciekawy artykuł na temat Enkodera i to na magistrali I2C można przeczytać na stronie Kaktusa :)
c.d.n..