Kurs XMEGA: proste zdarzenia (15)


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. Przejdźmy od razu do pisania programu!



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 wysoł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, zamontowanym 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ę.


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

Moduł prototypowy X3-DIL64

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
 
…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:
Pliki do pobrania:
 
#define  F_CPU    2000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#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_8SAMPLES_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
    
    // wyświetlacz
    LcdInit();
    
    while(1) {
        // wyświetlenie aktualnej wartości licznika CNT
        // CNT = ...
        LcdClear();
        Lcd("CNT = ");
        LcdDec(TCC0.CNT);
        _delay_ms(100);                               // czekanie 100ms
    }
}
 
Kurs XMEGA:Moduły prototypowe:

2 komentarze :

doman pisze...

Powaznie nie da sie wyczytac z datasheeta "evsys_chmux_porte_pin5_gc" ? Jak to zrobic? Uzywam eclipse - nie ma chyba tam takich podpowiedzi.

Dominik Leon Bieczyński pisze...

Cóż poradzić - zainstalować oryginalne i darmowe Atmel Studio i będzie działało :)

Prześlij komentarz

Skomentuj!

Sklep Leon Instruments