Kurs XMEGA: enkoder obrotowy (16)

|

Enkodery obrotowe, zwane również impulsatorami, służą do budowy przyjaznych interfejsów człowiek-komputer. Istnieje wiele parametrów, które łatwiej jest regulować kręcąc pokrętłem niż wpisując wartości liczbowe z klawiatury. W odbiornikach radiowych do regulacji głośności dawniej stosowano potencjometry, a współcześnie, w dobie techniki cyfrowej, stosuje się enkodery. Urządzenie, w którym znajdziemy kilka lub nawet kilkanaście enkoderów to oscyloskop. Mikrokontrolery XMEGA umożliwiają bardzo łatwe wykorzystanie enkoderów, dzięki systemowi zdarzeń i wbudowanemu dekoderowi kwadraturowemu.



Enkoder ma piny oznaczone literami A i B oraz masę. Jeśli enkoder ma możliwość wciskania, wówczas są jeszcze dwie dodatkowe nóżki. Piny A i B muszą być podciągnięte do zasilania rezystorami pull-up – na szczęście XMEGA jest wyposażona w takie i nie musimy dodawać osobnych (chyba, że mamy problem z drganiem styków, to wtedy mogą się przydać). Wewnątrz niego znajdują się dwa styki, które są zwierane do masy w zależności od pozycji pokrętła. Obracając pokrętło uzyskamy przebiegi takie, jak na rysunku poniżej – przesunięte o 90º w zależności od kierunku obrotu. Dzięki sprzętowemu dekoderowi, jaki znajduje się w mikrokontrolerach XMEGA, nie musimy wgłębiać się w szczegóły i wnikliwie badać tych przebiegów. Dekoder zrobi wszystko za nas, a pozycję pokrętła będziemy mogli łatwo i szybko odczytać, korzystając z rejestru CNT timera.



Na początku funkcji main(), musimy skonfigurować piny, które będzie wykorzystywał enkoder. Ustawiamy je jako wejścia i włączamy wewnętrzne rezystory pull-up. Ponieważ piny wykorzystywane przez enkoder znajdują się w obrębie jednego portu, do ich konfiguracji możemy wykorzystać rejestr PORTCFG.MPCMASK i zdefiniować w nim, jakie piny chcemy skonfigurować. Następnie, po wpisaniu odpowiednich wartości do rejestru PORTx.PINxCTRL, ustawienia te zostaną skopiowane do rejestru kontrolnego każdego pinu wskazanego w MPCMASK. W ten sposób możemy szybko skonfigurować piny C1 i C0, które podłączymy do enkodera.
 
    // wejścia enkodera
    PORTCFG.MPCMASK    =    0b00000011;                       // wybór pinów 0 i 1 do konfiguracji
    PORTC.PIN0CTRL     =    PORT_ISC_LEVEL_gc |               // reagowanie na poziom niski
                            PORT_OPC_PULLUP_gc;               // podciągnięcie do zasilania
 
Następnie, przechodzimy do konfiguracji systemu zdarzeń. W rejestrze EVSYS.CH0MUX wskazujemy pierwszy z dwóch pinów, wykorzystywanych przez enkoder. Pamiętaj, że enkoder musi być podłączony do pinów sąsiadujących ze sobą!

Każdy kanał systemu zdarzeń ma swój rejestr kontrolny. Zobaczmy fragment dokumentacji tego rejestru na rysunku 3. Interesuje nas bit QDEN, uruchamiający dekoder kwadraturowy. Pozostałe opcje związane z dekoderem są związane z enkoderami z indeksowaniem. Przydatną rzeczą, jaką jeszcze możemy w tym rejestrze ustawić, to filtr cyfrowy. Filtr cyfrowy sprawia, że sygnał zostanie rozpoznany jeżeli będzie utrzymywał się na wejściu dłużej niż wybrana liczba cykli zegarowych. Ustawmy więc filtr na osiem cykli.


 
    // konfiguracja systemu zdarzeń
    EVSYS.CH0MUX       =    EVSYS_CHMUX_PORTC_PIN0_gc;        // pin C0 wywołuje zdarzenie
    EVSYS.CH0CTRL      =    EVSYS_QDEN_bm|                    // włączenie dekodera w systemie zdarzeń
                            EVSYS_DIGFILT_8SAMPLES_gc;        // filtr cyfrowy    
 
Moduł prototypowy X3-DIL64

Dekoder kwadraturowy jest nadajnikiem zdarzenia, a odbiornikiem musi być timer, który będzie zliczał odebrane impulsy. Wykorzystajmy do tego celu timer C0. W rejestrze CTRLA, jak pamiętamy z odcinka o timerach w XMEGA, musimy w nim zdefiniować źródło sygnału taktującego. Jest nim oczywiście kanał 0 systemu zdarzeń. W rejestrze CTRLD musimy tak skonfigurować timer, by był w stanie poprawnie odbierać impulsy z dekodera. W szczególności jest to ważne, by timer wiedział kiedy ma zwiększyć swoją wartość, a kiedy zmniejszyć, w zależności od kierunku obrotu enkodera.
 
    // konfiguracja timera
    TCC0.CTRLA         =    TC_CLKSEL_EVCH0_gc;               // taktowanie zegarem 2MHz
    TCC0.CTRLD         =    TC_EVACT_QDEC_gc |                // włączenie dekodera kwadraturowego
                            TC_EVSEL_CH0_gc;                  // dekoder zlicza impulsy z kanału 0
 
I to wszystko! Wystarczy teraz dopisać prostą procedurę pokazującą stan licznika na wyświetlaczu LCD. Pamiętać trzeba, że pojedynczy impuls enkodera powoduje zwiększenie lub zmniejszenie wartości timera o 4 – dlatego przed wyświetleniem wartości rejestru TCC0.CNT, musimy ją podzielić najpierw podzielić przez 4.


 
#define  F_CPU    2000000UL
#include <avr/io.h>
#include <util/delay.h>
#include "hd44780.h"

int main(void) {
    
    // wejścia enkodera
    PORTCFG.MPCMASK    =    0b00000011;                       // wybór pinów 0 i 1 do konfiguracji
    PORTC.PIN0CTRL     =    PORT_ISC_LEVEL_gc |               // reagowanie na poziom niski
                            PORT_OPC_PULLUP_gc;               // podciągnięcie do zasilania
    
    // konfiguracja systemu zdarzeń
    EVSYS.CH0MUX       =    EVSYS_CHMUX_PORTC_PIN0_gc;        // pin C0 wywołuje zdarzenie
    EVSYS.CH0CTRL      =    EVSYS_QDEN_bm|                    // włączenie dekodera w systemie zdarzeń
                            EVSYS_DIGFILT_8SAMPLES_gc;        // filtr cyfrowy    
    
    // konfiguracja timera
    TCC0.CTRLA         =    TC_CLKSEL_EVCH0_gc;               // taktowanie systemem zdarzeń
    TCC0.CTRLD         =    TC_EVACT_QDEC_gc |                // włączenie dekodera kwadraturowego
                            TC_EVSEL_CH0_gc;                  // dekoder zlicza impulsy z kanału 0

    // wyświetlacz
    LcdInit();
    
    while(1) {
        // wyświetlenie aktualnej wartości licznika CNT
        // CNT = ...
        LcdClear();
        Lcd("CNT = ");  
        LcdDec(TCC0.CNT / 4);                                 // jeden przeskok to 4 impulsy
        _delay_ms(100);                                       // czekanie 100ms
    }
}
 
Kurs XMEGA:Moduły prototypowe:

13 komentarze :

Anonimowy pisze...

ile enkoderów wspiera sprzętowo xmega?

Dominik Leon Bieczyński pisze...

Można podłączyć trzy enkodery. Każdy z nich wykorzystuje jeden kanał systemu zdarzeń, odpowiednio 0, 2 i 4.

Anonimowy pisze...

Witam serdecznie, kiedy będzie upragniony c.d.n. ?
Pozdrawiam W.Szwed

Dominik Leon Bieczyński pisze...

Już za kilka dni. Nowa seria odcinków kursu już jest napisana i czeka na publikacje.

Anonimowy pisze...

Witam, czy przy użyciu na przykład takiego enkodera:
http://www.ebay.com/itm/OMRON-Rotary-Encoder-E6B2-CWZ6C-2000P-R-5-24v-12v-dc-Coupling-/251602922310?pt=LH_DefaultDomain_0&hash=item3a94b3eb46
wewnętrzne pull-upy wystarczają, czy lepiej użyć zewnętrznego podciągania?

Jaka jest teoretycznie maksymalna ilość impulsów enkodera / sek. jaką XMEGA jest w stanie odczytać?

Pozdrawiam
Niedouczony Początkujący Hobbysta

Dominik Leon Bieczyński pisze...

Teoretycznie powinny, ale lepiej dać zewnętrzne. W końcu dwa rezystory to nie jest duży koszt. Trudno powiedzieć jaka jest maksymalna szybkość, ale jest na tyle duża, że kręcąc palcami na pewno jej nie przekroczysz :)

Anonimowy pisze...

Warto jeszcze napisać, że w eXtrino XL enkoder jest wpięty do portu E a nie C. Co prawda widać to na schemacie, ale jak się robi przykład ze strony i jeszcze nie bardzo wie o co chodzi to może to być spory problem.

Dawid Balcerzak pisze...

Czy da radę wykorzystać powyższe możliwości xmegi do enkodera tego typu (?): http://botland.com.pl/enkodery/2182-zestaw-enkoderow-magnetycznych-dagu-rs030.html
Ten enkoder ma tylko jedno wyjście - generuje sygnał prostokątny o wypełnieniu 50% i częstotliwości zależnej od prędkości obrotu. Nie infornuje jednak o kierunki obrotu, ale to mi nie jest potrzebne.
Więc wobec powyższego jak to jest? Da się wykorzystać powyższe możliwości w moim przypadku?

Dominik Leon Bieczyński pisze...

XMEGA na wbudowany interfejs do dekoderów z sygnałem kwadraturowym, czyli do najbardziej standardowych. Z tego co widzę Twój enkoder po prostu generuje sygnał o częstotliwości zależnej od obrotu, więc wystarczy najzwyklejszy timer, by zmierzyć tą częstotliwość.

Dawid Balcerzak pisze...

Rozumiem. A da radę w tym przypadku wykorzystać wspomniany w artykule filtr cyfrowy, który sprawdza ile cykli procesora utrzymuje się pożądany stan? Pytam, bo to fantastyczne narzędzie w przypadku jak na sygnale prostokątnym pojawiają się jakeś szpilki od silnika.

Dominik Leon Bieczyński pisze...

Dużo prościej będzie zrobić jakiś prosty filtr RC. Jeśli to ma pracować z jakimś silnikiem to i tak trzeba będzie zastosować jakiś układ ograniczający zakłócenia.

Dawid Balcerzak pisze...

A jak z doborem elementów filtru? Przepuszczenie prostokąta przez RC da mi albo 'wygładzony' prostokąt albo - przy odpowiednio dużych stałych czasowych - napięcie średnie sygnału prostokątnego na wyjściu, czyli połowę amplitudy, a to mi nijak nie pomoże.

Dawid Balcerzak pisze...

Dodam, że mam trochę kłopot z tym filtrem RC, bo jakich wartości R i C bym nie dobierał to szpilki się przedostają. Co można jeszcze zrobić?

Prześlij komentarz

Skomentuj!

Sklep Leon Instruments