W tym artykule spróbujemy wykorzystać nabytą wiedzę o SPI w PIC32MM. W szczególności wykorzystamy wygenerowane przez MCC funkcje do obsługi SPI, o których wspominałem w artykule poprzednim. Naszym celem będzie wymiana danych pomiędzy dwoma MCU PIC32MM. Jeden będzie skonfigurowany jako Master a drugi jako Slave czyli klasyczny układ .
Aby zajęcia sprawnie przeprowadzić wykorzystam dwie płytki developerskie PIC32MM mojego autorstwa. Praktyczna wiedza o SPI przyda nam się w następnym zagadnieniu. Zaczynamy zatem przedstawienie :)
Na początek rzut okiem na część sprzętową czyli płytki, które wykorzystam do testu SPI :
Dla przypomnienia na płytce znajduje się PIC32MM0256GPM048 i wyświetlacz DOGM162W-A.
Zabawę zaczniemy od połączeń obu płytek. Ogólny schemat połączeń interfejsu SPI dla przypomnienia wygląda tak :
Nie będziemy korzystać z linii SSx. Nasze docelowe połączenia płytek będą wyglądać tak :
RB3 - SDO (Master) ----> RA9 - SDI (Slave)
RA9 - SDI (Master) ----> RB3 - SDO (Slave)
RB8 - SCK (Master) ----> RB8 - SCK (Slave)
Korzystamy z SPI2 , konfiguracja dla Mastera i Slave zostanie zrobiona za pomocą MCC(MPLAB Code Configurator) metodologią opisaną w artykule poprzednim, ja tego w artykule nie będę już pokazywał aby się nie powtarzać. W kodzie na GitHub-ie będzie w strukturze projektu plik z rozszerzeniem .mcc (w katalogu Important Files), jak klikniemy w ten plik otworzy nam się MCC z ustawieniami jakie zastosowałem w projekcie. Można sobie wtedy na spokojnie przeanalizować jakie piny zostały wykorzystane i jaka jest ich konfiguracja jakie ustawienia SPI , zegara etc.
Przy konfiguracji Slave musimy pamiętać o zmianie pinów w/g schematu podanego wyżej. Po stronie Mastera nie będziemy korzystać z przerwań ale po stronie Slave skorzystamy z przerwania odbiorczego. Parametry dla tego przerwania znajdziemy w datasheet w tabelce na stronie 63 pod hasłem SPI2 Reception.
Funkcja obsługi tego przerwania wygląda tak i jest to standardowa postać dla PIC32 :
void __ISR(_SPI2_RX_VECTOR)__SPI2Interrupt(void)
{
/*ciało funkcji*/
IFS1bits.SPI2RXIF = 0; /*Clear SPI2 Interrupt Flag*/
}
Cechą charakterystyczną w MCU PIC jest to , że w każdym
przerwaniu musimy zerować flagę, która jest automatycznie ustawiana przy
wywołaniu przerwania. W naszym konkretnym przypadku chodzi o flagę SPI2RXIF w rejestrze IFS1.
I tutaj bardzo ważna Uwaga !!!! dotycząca przerwań w PIC32. W przypadku kiedy chcemy skorzystać z przerwań (dotyczy to wszystkich peryferiów) nie wystarczy tylko włączyć przerwanie ale koniecznie trzeba nadać im priorytet a najlepiej priorytet i subpriorytet. Jeśli wartość priorytetu będzie na zero a tak jest domyślnie to przerwanie za chiny ludowe nam nie odpali. Sam nadziałem się na ten wątek, jest to specyfika PIC32.
Poniżej podaję przykład ustawienia priorytetu i subpriorytetu dla przerwania odbiorczego SPI2 :
IPC11bits.SPI2RXIP = 3 ; /*set Priority*/
IPC11bits.SPI2RXIS = 1 ; /*set SubPriority*/
IFS1bits.SPI2RXIF = 0; /*Clear the Interrupt Flag*/
IEC1bits.SPI2RXIE = 1; /*Enable The Interrupt*/
To jakie bity w jakim rejestrze trzeba ustawić aby skonfigurować w pełni przerwanie sprzętowe mamy podane jak na tacy w tabelce w datasheet MCU, fragment tej tabelki podałem wyżej.
Teraz postawimy sobie zadanie jakie chcemy zrealizować na zajęciach . Chcemy aby Master wysłał paczkę bajtów po SPI do Slave a Slave to co odbierze wyświetlił nam na LCD. Paczką bajtów niech będzie napis "Witaj SPI"
Wiem mało ambitne , ale naszym celem jest zabawa z SPI w PIC32MM a nie epokowe dzieło a poza tym przez zabawę dziecko poznaje świat :)
Zegar PIC32MM skonfigurowany na 24 MHz (RC).
Master skonfigurowany w trybie ENHANCED BUFFER MODE i korzystamy tutaj do wysłania paczki danych z funkcji wygenerowanej przez MCC (patrz poprzedni artykuł). Przerwania w Masterze wyłączone bo z nich nie korzystamy.
Slave skonfigurowany w trybie STANDARD BUFFER MODE (nie korzystamy z FIFO) . Przerwania w Slave są włączone, korzystamy z przerwania odbiorczego nazwa wektora : _SPI2_RX_VECTOR. Cała akcja odbiorcza dzieje się w przerwaniu a wyświetlanie w pętli głównej.
Jeśli chcemy włączyć w Slave tryb ENHANCED BUFFER MODE to uwaga ważne !!! w przypadku kiedy korzystamy z przerwania odbiorczego a w Slave tak jest, nie wystarczy tylko włączyć tryb ENHANCED BUFFER MODE w rejestrze SPI2CON bit ENHBUF ale uwaga musimy włączyć tryb reagowania na status bufora FIFO, robimy to przez ustawienie w rejestrze SPI2CON dwóch bitów SRXISEL na wartość inną niż 00 a konkretnie na 01, ustawienie to wskazuje aby przerwanie odbiorcze było generowane kiedy bufor FIFO nie jest pusty. Jeśli tego nie zrobimy przerwanie będzie się kaszaniło.
Generalnie można przyjąć , że tam gdzie mamy wymagane duże prędkości przesyłu danych po SPI i duże ilości danych, należy korzystać z dobrodziejstwa jakie nam daje tryb ENHANCED BUFFER MODE czyli sprzętowej obsługi buforów FIFO.
Co robi program ?
Master (bez wyświetlacza LCD) po 2 sekundach zwłoki od włączenia zasilania prześle jeden raz paczkę danych w postaci napisu Witaj SPI , po wysłaniu danych zapali diodę LED na pinie RB6
Slave (z wyświetlaczem LCD) wyświetla napis kontrolny TEST SPI .. , odbiera paczkę danych (Witaj SPI) od Mastera i wyświetla ją na wyświetlaczu LCD w dolnym wierszu.
Master i Slave muszą być podłączone do jednego źródła zasilania.
Na zdjęciu poniżej widać efekt końcowy jaki powinniśmy uzyskać po wgraniu wsadów do MCU :
W linkach poniżej mamy wsad dla Mastera i Slave w postaci gotowych projektów do MPLABX-IDE
Pozdrawiam
picmajster.blog@gmail.com
Linki :
Wsad dla Mastera
Wsad dla Slave
PIC32 SPI Manual
PIC32MM Datasheet
Brak komentarzy:
Prześlij komentarz