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..