Mikrokontrolery AVR XMEGA w praktyce, część 19. Dodatkowy PORTX

Dodatkowy PORTX

W tym odcinku kursu zobaczymy, jak przy pomocy interfejsu SPI oraz rejestrów przesuwnych typu 74595 oraz 74165 stworzyć dodatkowy port IO oraz jak napisać program, aby obsługa tego dodatkowego portu była podobna do zwykłych portów mikrokontrolera. W ten sposób można samodzielnie zbudować odpowiednik ekspandera portu typu PCF8575 za niższą cenę.

Schemat układu przedstawiono rysunku 1, a jego uproszczony łatwiejszy do zrozumienia, uproszczony schemat, przedstawia rysunek 2. Rejestr 74595 ma wejście szeregowe oraz 8 wyjść równoległych, które możemy wykorzystać do dowolnego celu, np. do sterowania diodami. 74165 jest przeciwieństwem tego pierwszego i wyposażono go w 8 wejść. Możemy do nich podłączyć klawiaturę, czujniki lub inne układy cyfrowe.

Zastanówmy się, co się dzieje w tym układzie podczas transmisji jednego bajtu. Sygnał CS zmienia swój stan z 1 na 0, po czym moduł SPI w XMEGA nadaje osiem bitów. Wraz z każdym taktem sygnały zegarowego SCK, rejestry „przesuwają” swoje bity. W ten sposób, bajt danych z XMEGA trafia do 74595. 8 bitów dotychczas przechowywanych z 74595 przesyłane jest do 74165 i de facto są to dane, które nas nie interesują. Natomiast 8 bitów z 74165, odpowiadające sygnałom wejściowym tego rejestru, przesyła się do modułu SPI w XMEGA. Na zakończenie, zmiana CS z 0 na 1 powoduje odświeżenie wartości tych rejestrów. W ten elegancki sposób, transmitując 8 bitów, ustaliliśmy stan wyjść oraz odczytaliśmy stan wejść.

 

Rys. 1. Schemat dodatkowego portu sterowanego przez SPI

 

Rys. 2. Schemat uproszczony

 

Doskonałym pomysłem jest tutaj zastosowanie przerwań. Po każdej transmisji, układ SPI może generować przerwanie i wysyłać kolejny bajt danych, aby wejścia i wyjścia samoczynnie się odświerzały. Jedyne co musimy zrobić, to skonfigurować SPI i wywołać pierwszą transmisję, wpisując cokolwiek do rejestru SPIC.DATA.

Możemy posunąć się o krok dalej i stworzyć „pseudoport”, by kod programu jak najbardziej przypominał obsługę zwykłego portu. W tym celu zdefiniujemy sobie strukturę PORTX, w której znajdować się będą rejestry IN i OUT, analogicznie do zwykłych portów XMEGA. Ważne by nie zapomnieć i modyfikatorze volatile, gdyż zmienne te będą aktualizowane w przerwaniach, a bez tego kompilator mógłby nieprawidłowo je zoptymalizować.

Na płytce eXtrino XL znajduje się 8 przycisków, a przy każdym z nich jest dioda LED. Napiszmy program, w którym świeci się jedna z tych diod tak długo, aż użytkownik naciśnie przycisk przy tej diodzie. Wtedy zapali się sąsiednia dioda i program będzie czekał na naciśnięcie sąsiedniego przycisku, itd.

Kod programu przedstawia listing 1. Zwróć uwagę, że w pętli głównej nigdzie nie ma żadnych funkcjo obsługujących SPI. PORTX działa zupełnie jak normalny port!

Wyjaśnić należy procedurę przerwania, gdyż zaczyna się ona od deaktywowania układów SPI (CS=1), następnie czekamy kilka cykli i znów aktywujemy SPI (CS=0). Jest to podyktowane faktem, że ostatnim poleceniem przerwania powinno być wpisanie danych do rejestru SPIC.DATA. Wtedy moduł SPI transmituje dane, a w tym czasie procesor może wykonywać inne zadania. Kiedy moduł SPI zakończy transmisję, wówczas jest zgłaszane przerwanie. Wtedy, jako pierwsze następuje ustawienie CS w stan wysoki, co oznacza zakończenie transmisji rozpoczętej w poprzednim wywołaniu przerwania. Może to początkowo wydawać się trochę zagmatwane, jednak proszę przeanalizować kod wraz z komentarzami, a wszystko stanie się bardzo proste.

Działanie układu przedstawiono na fotografii 3. Po wciśnięciu przycisku, dioda LED „przeskakuje” na sąsiednią pozycję po lewej stronie.

Listing 1. Kod programu demonstrującego działanie SPI w XMEGA

 

Fot. 3. Przykład działania układu demonstrującego PORTX SPI

 

Dystrybutorem zestawu X3-DIL64 jest KAMAMI.pl.

 

Dominik Leon Bieczyński

www.leon-instruments.pl

O autorze