LinkedIn YouTube Facebook
Szukaj

Newsletter

Proszę czekać.

Dziękujemy za zgłoszenie!

Wstecz
Artykuły

Mikrokontrolery AVR XMEGA w praktyce, część 15. Proste zdarzenia

W tym oraz kilku kolejnych odcinkach kursu będziemy ćwiczyć różne możliwości systemu zdarzeń w mikrokontrolerach XMEGA. Na początek sprawa bardzo prosta – zwyczajne zliczanie impulsów. Zdarzenie będzie generował pin E5, czyli ten, który jest połączony z przyciskiem FLIP na płytce X3-DIL64 z Leon Instruments. Odbiornikiem zdarzenia będzie timer C0, który będzie zwiększał swoją wartość o 1 przy każdym wciśnięciu przycisku. Schemat układu do zbudowania na płytce stykowej przedstawiono na rysunku 1. Przejdźmy od razu do pisania programu!

 

Rys. 1. Schemat układu demonstrującego podstawowe funkcje systemu zdarzeń

Rys. 1. Schemat układu demonstrującego podstawowe funkcje systemu zdarzeń

 

Zaczynamy, jak to zwykle, od skonfigurowania pinów. Zdarzenie ma generować pin E5, w związku z czym musimy go skonfigurować jako wejście oraz uaktywnić rezystor podciągający do zasilania. Czytelnicy pamiętający artykuł o przerwaniach w XMEGA zapewne zwrócą uwagę, że poniższy kod niczym nie różni się, od tego, który uaktywnia przerwania. W rzeczy samej! Parametr PORT_ISC_FALLING_gc wpisany do rejestru PINxCTRL konfiguruje, co ma wywoływać przerwania i również zdarzenia.

    // przyciski
    PORTE.DIRCLR    =    PIN5_bm;                    // pin E5 jako wejście (przycisk FLIP)
    PORTE.PIN5CTRL  =    PORT_OPC_PULLUP_gc|         // podciągnięcie do zasilania
                         PORT_ISC_FALLING_gc;        // zdarzenie mam wywoływać zbocze malejące

Pamiętajmy, że żeby uaktywnić przerwanie, trzeba było jeszcze skonfigurować kontroler przerwań PMIC oraz odblokować przerwania, które chcemy używać, a na końcu trzeba jeszcze wykonać instrukcję sei. Jednak my tego nie zrobimy. Mamy przecież zająć się systemem zdarzeń.

Wykorzystajmy kanał 0 systemu zdarzeń. W procesorze ATxmega128A3U, zamontowanego w module prototypowym X3-DIL64, dostępne jest osiem kanałów zdarzeń i moglibyśmy użyć dowolnego z nich. Musimy wskazać, jaki układ ma być nadajnikiem zdarzenia i wpisać go do rejestru EVSYS.CH0MUX. Rzućmy okiem na dokumentację, której fragment przedstawiono na rysunku 2.

 

Rys. 2. Wybór nadajnika zdarzenia

Rys. 2. Wybór nadajnika zdarzenia

 

Jak widać, wybór jest bardzo szeroki i bardzo pomocne są podpowiedzi, generowane automatycznie przez Atmel Studio podczas wpisywania tekstu. Aby zdarzenie generował pin E5, musimy do rejestru CH0MUX wpisać wartość EVSYS_CHMUX_PORTE_PIN5_gc.

Ponieważ przycisk jest elementem mechanicznym, generującym chaotyczne wielokrotne impulsy podczas przyciskania, dobrym pomysłem będzie zastosowanie filtru cyfrowego. W przeciwnym razie, procesor mógłby pojedyncze wciśnięcie zinterpretować jako kilka, kilkanaście, lub nawet kilkadziesiąt wciśnięć. Filtr cyfrowy powoduje ignorowanie impulsów trwających krócej niż wyznaczoną liczbę cykli zegara systemowego. Maksymalna wartość, jaką możemy wybrać to 8 cykli zegarowych – prawdę mówiąc, nie jest to ilość wystarczająca do całkowitego wyeliminowania problemu, ale choć trochę go zmniejszymy. Aby uruchomić filtr cyfrowy, do rejestru CH0CTRL musimy wpisać wartość EVSYS_DIGFILT_8SAMPLES_gc.

    // konfiguracja systemu zdarzeń
    EVSYS.CH0MUX    =    EVSYS_CHMUX_PORTE_PIN5_gc;   // pinE5 wywołuje zdarzenie
    EVSYS.CH0CTRL   =    EVSYS_DIGFILT_7SAMPLES_gc;   // filtr cyfrowy

To wszystko, jeśli chodzi o nadajnik. Przejdźmy teraz do konfiguracji odbiornika zdarzenia, czyli timera C0. Timery w mikrokontrolerach XMEGA zostały dokładniej opisane w poprzednich częściach kursu.

Dotychczas w naszych ćwiczeniach, timer był zawsze taktowany sygnałem zegarowych podzielonym wstępnie przez preskaler, co konfigurowaliśmy w rejestrze CTRLA timera. Z punktu widzenia timera, system zdarzeń jest takim samym sygnałem taktującym jak sygnał zegarowy – impulsy przychodzące przez system zdarzeń mogą być traktowane przez niego jak sygnał zegarowy. Dlatego wybór kanału systemu zdarzeń dokonujemy również w rejestrze CTRLA.

    // konfiguracja timera
    TCC0.CTRLB      =    TC_WGMODE_NORMAL_gc;         // tryb normalny
    TCC0.CTRLA      =    TC_CLKSEL_EVCH0_gc;          // ustawienie źródła sygnału na kanał 0 systemu zdarzeń

…i to wszystko! Pozostaje tylko inicjalizacja wyświetlacza LCD oraz procedura pętli głównej, cyklicznie wyświetlająca aktualną wartość rejestru CNT timera C0. Zwróć uwagę, że w pętli głównej nie ma jakiejkolwiek instrukcji związanej z pinem E5!

    // wyświetlacz
    LcdInit();
    
    while(1) {
        // wyświetlenie aktualnej wartości licznika CNT
        // CNT = ...
        LcdClear();
        Lcd("CNT = ");
        LcdDec(TCC0.CNT);
        _delay_ms(100);                               // czekanie 100ms
    }

Oto cały kod programu:

#define  F_CPU    2000000UL
#include 
#include 
#include 
#include "hd44780.h"


int main(void) {
    
    // przyciski
    PORTE.DIRCLR    =    PIN5_bm;                     // pin E5 jako wejście (przycisk FLIP)
    PORTE.PIN5CTRL  =    PORT_OPC_PULLUP_gc|          // podciągnięcie do zasilania
                        PORT_ISC_FALLING_gc;          // zdarzenie mam wywoływać zbocze malejące
    
    // konfiguracja systemu zdarzeń
    EVSYS.CH0MUX    =    EVSYS_CHMUX_PORTE_PIN5_gc;   // pinE5 wywołuje zdarzenie
    EVSYS.CH0CTRL   =    EVSYS_DIGFILT_7SAMPLES_gc;   // filtr cyfrowy
    
    // konfiguracja timera
    TCC0.CTRLB      =    TC_WGMODE_NORMAL_gc;         // tryb normalny
    TCC0.CTRLA      =    TC_CLKSEL_EVCH0_gc;          // ustawienie źródła sygnały na kanał 0 systemu zdarzeń
    
    // wyświetlacz
    LcdInit();
    
    while(1) {
        // wyświetlenie aktualnej wartości licznika CNT
        // CNT = ...
        LcdClear();
        Lcd("CNT = ");
        LcdDec(TCC0.CNT);
        _delay_ms(100);                               // czekanie 100ms
    }
}

Dystrybutorem zestawu X3-DIL64 jest KAMAMI.pl.

Dominik Leon Bieczyński

www.leon-instruments.pl

Do pobrania