SPI to jeden z tych interfejsów, które na schemacie wyglądają skromnie, a w praktyce decydują o tym, czy mikrokontroler dogada się z czujnikiem, pamięcią albo wyświetlaczem bez opóźnień i błędów. W tym tekście pokazuję, jak działa synchroniczna komunikacja szeregowa, co oznaczają linie MOSI, MISO, SCK i CS, jak dobrać tryb pracy oraz jak uniknąć typowych pułapek przy uruchamianiu połączenia. Z perspektywy elektroniki liczy się tu nie teoria dla samej teorii, tylko to, co realnie ułatwia projekt i diagnozę.
Najważniejsze rzeczy, które trzeba wiedzieć o SPI
- SPI jest synchronicznym, pełnodupleksowym interfejsem między kontrolerem a jednym lub wieloma układami peryferyjnymi.
- Najczęściej pracuje na czterech liniach: SCLK, MOSI, MISO i CS, a CS zwykle ma stan aktywny niski.
- O poprawności komunikacji decydują CPOL i CPHA, więc zły tryb jest jedną z najczęstszych przyczyn braku odpowiedzi układu.
- Ten interfejs wybiera się tam, gdzie ważne są szybkość, prosty protokół i krótka, przewodowa komunikacja między układami.
- W wielu urządzeniach ramka nie jest uniwersalna: jej długość, kolejność bitów i znaczenie bajtów ustala dokumentacja konkretnego układu.
Czym jest interfejs SPI i po co się go używa
SPI to synchroniczny interfejs szeregowy, w którym jeden kontroler prowadzi komunikację z jednym albo kilkoma peryferiami. Jak opisuje Texas Instruments, jest to protokół pełnodupleksowy, czyli taki, który pozwala wysyłać i odbierać dane w tym samym cyklu zegara. To właśnie wspólny zegar porządkuje całą wymianę bitów i sprawia, że SPI dobrze nadaje się do krótkich połączeń między układami na jednej płytce.
Najważniejsza cecha, którą doceniam w projektach praktycznych, jest prosta: SPI nie narzuca jednego sztywnego formatu komunikatu. Sam interfejs mówi, kiedy wysłać bit i na którym zboczu go odczytać, ale to konkretny układ określa, czy ramka ma 8, 12, 16 czy 24 bity, gdzie zaczyna się adres, a gdzie dane. Dzięki temu SPI jest elastyczne, ale właśnie przez tę elastyczność łatwo o nieporozumienie, jeśli ktoś zakłada, że każdy układ zachowuje się tak samo.
W praktyce interfejs ten wybiera się tam, gdzie liczy się prostota układu logicznego, niewielkie opóźnienie i sensowna przepustowość. Typowe zastosowania to pamięci Flash, przetworniki ADC i DAC, czujniki, sterowniki wyświetlaczy oraz układy rozszerzające liczbę wejść i wyjść. To dobry wybór zwłaszcza wtedy, gdy magistrala ma obsługiwać urządzenia na jednej płytce, a nie długie odcinki przewodów.
Żeby w pełni wykorzystać SPI, trzeba jednak rozumieć sam przebieg transmisji, bo tam kryją się najczęstsze błędy konfiguracyjne.
Jak wygląda transmisja krok po kroku
W SPI wszystko zaczyna się od wybrania układu podrzędnego sygnałem CS, czyli chip select albo slave select. Dopiero wtedy kontroler podaje zegar SCLK, a dane przesuwają się równolegle w obie strony: master wysyła bajty linią MOSI, a układ podrzędny odpowiada linią MISO. W dokumentacji Microchip ten mechanizm jest opisywany jako przełączanie danych na przeciwnych zboczach zegara, tak aby sygnał miał czas się ustabilizować przed odczytem.
- Kontroler ustawia CS w stanie aktywnym, najczęściej niskim.
- Układ podrzędny zaczyna traktować linię jako aktywną i czeka na zegar.
- Kontroler generuje impulsy SCLK.
- Na jednym zboczu dane są wystawiane, a na drugim próbkowane.
- Po zakończeniu ramki CS wraca do stanu nieaktywnego i transfer się zamyka.
Warto pamiętać o jednej rzeczy, którą początkujący często pomijają: przerwa między aktywacją CS a pierwszym zboczem zegara bywa istotna. Niektóre układy potrzebują bardzo małego, ale jednak realnego czasu na przygotowanie odpowiedzi albo na rozpoczęcie wewnętrznej operacji. Jeśli ten margines jest za krótki, połączenie wygląda elektrycznie poprawnie, a mimo to nie działa.
Z punktu widzenia diagnozy warto też myśleć o SPI jak o przesuwaniu bitów przez rejestry przesuwnikowe. To pomaga zrozumieć, dlaczego przy jednym takcie zegara jednocześnie wychodzi nowy bit i wchodzi następny, nawet jeśli w danym momencie interesuje Cię tylko odczyt albo tylko zapis. Następny krok to już praktyka okablowania, bo sama logika nie wystarczy, jeśli pomylisz linie albo topologię.
Piny i topologie, które spotkasz najczęściej
W najprostszym wariancie SPI potrzebuje czterech sygnałów. To właśnie one tworzą podstawową, czytelną strukturę połączenia i w większości projektów wystarczają do uruchomienia komunikacji bez kombinowania.
| Linia | Rola | Na co zwrócić uwagę |
|---|---|---|
| SCLK | Zegar generowany przez kontroler | To on wyznacza moment zmiany i odczytu bitu. |
| MOSI | Dane z kontrolera do układu podrzędnego | W części dokumentacji ta linia może występować jako PICO albo SDO po stronie kontrolera. |
| MISO | Dane z układu podrzędnego do kontrolera | Niewybrany układ powinien odłączyć wyjście, zwykle w trybie wysokiej impedancji. |
| CS / SS | Wybór konkretnego układu | Zazwyczaj aktywne niskim stanem, ale wyjątki istnieją i trzeba je sprawdzić w nocie katalogowej. |
W dokumentacji TI spotkasz też nazwy PICO i POCI, czyli odpowiedniki kierunku danych z perspektywy kontrolera i peryferium. To nie jest zbędna kosmetyka nazewnicza, tylko przypomnienie, że ta sama fizyczna linia ma różne znaczenie zależnie od strony układu. Dla projektanta najważniejsze jest jedno: nie mylić kierunków podczas prowadzenia ścieżek i testów na płytce.
Jeśli do magistrali podłączasz kilka układów, najczęściej każdy z nich dostaje osobną linię CS. To rozwiązanie jest proste w sterowaniu i łatwe do debugowania, bo kontroler wybiera tylko jeden układ na raz. Istnieją też inne warianty, na przykład 3-wire SPI, w którym linie danych są połączone w jeden kanał dwukierunkowy, albo połączenie typu daisy chain, gdzie układy są spięte szeregowo. Te odmiany mają sens tylko wtedy, gdy konkretne układy je wspierają; nie są uniwersalnym zamiennikiem klasycznego SPI.
W praktyce bardzo często problemem nie są same piny, lecz to, że projektant wybiera niewłaściwy tryb pracy. I właśnie dlatego kolejna sekcja jest zwykle najważniejsza przy uruchamianiu pierwszej komunikacji.
Cztery tryby pracy i jak dobrać CPOL oraz CPHA
SPI ma cztery podstawowe tryby pracy, które wynikają z dwóch parametrów: CPOL i CPHA. W dokumentacji Microchip różnice te opisuje się jako cztery kombinacje ustawień zegara i momentu próbkowania. W praktyce chodzi o odpowiedź na dwa pytania: jaki poziom ma zegar w spoczynku oraz na którym zboczu dane są odczytywane.
| Tryb | CPOL | CPHA | Stan spoczynkowy zegara | Próbkowanie danych |
|---|---|---|---|---|
| Mode 0 | 0 | 0 | Niski | Na zboczu narastającym |
| Mode 1 | 0 | 1 | Niski | Na zboczu opadającym |
| Mode 2 | 1 | 0 | Wysoki | Na zboczu opadającym |
| Mode 3 | 1 | 1 | Wysoki | Na zboczu narastającym |
Jeśli układ milczy mimo poprawnego okablowania, tryb pracy jest pierwszą rzeczą, którą sprawdzam. Zbyt często ktoś ustawia domyślny Mode 0, bo „tak bywa najczęściej”, a potem dziwi się, że czujnik albo pamięć nie odpowiada. Zawsze zaczynam od dokumentacji układu podrzędnego, bo to on narzuca warunki komunikacji, a nie kontroler.
Warto też rozdzielić kilka pojęć, które bywają wrzucane do jednego worka. Tryb pracy to nie to samo co kolejność bitów, długość słowa czy format ramki. Układ może działać w poprawnym CPOL i CPHA, a mimo to nadal nie odpowiadać, jeśli oczekuje na przykład transferu 16-bitowego, a Ty wysyłasz tylko 8-bitowe słowo albo zaczynasz od niewłaściwego bitu. To właśnie dlatego przy SPI nie ma miejsca na zgadywanie.
Gdy tryb jest już ustawiony, można porównać SPI z innymi popularnymi interfejsami i ocenić, czy to rzeczywiście najlepszy wybór dla danego projektu.
Kiedy SPI wygrywa z I2C i UART
SPI nie jest „lepsze” od wszystkiego, ale bywa po prostu wygodniejsze tam, gdzie liczą się szybkość i przewidywalność sygnału. Texas Instruments ujmuje to dość jasno: SPI jest synchroniczne, pełnodupleksowe i ma wysoką przepustowość, podczas gdy I2C oraz UART rozwiązują inne problemy i robią to w innym stylu.
| Cecha | SPI | I2C | UART |
|---|---|---|---|
| Typ komunikacji | Synchroniczna | Synchroniczna | Asynchroniczna |
| Tryb transmisji | Pełnodupleksowy | Często półdupleksowy | Zwykle pełnodupleksowy |
| Zegar | Tak, wspólny SCLK | Tak, wspólny SCL | Nie |
| Adresowanie urządzeń | Linia CS dla wybranego układu | Adres w protokole | Brak adresowania magistrali |
| Liczba przewodów | Najczęściej 4 na jeden układ | Najczęściej 2 | Zwykle 2 |
| Najmocniejsza strona | Szybka i prosta wymiana danych między układami | Oszczędność pinów i prosty bus dla wielu urządzeń | Prosta łączność punkt-punkt i debug |
Wybieram SPI wtedy, gdy potrzebuję krótkiej, szybkiej i deterministycznej komunikacji na jednej płytce. I2C wygrywa, kiedy ważniejsze są oszczędność linii i wygodne adresowanie wielu układów. UART z kolei sprawdza się świetnie tam, gdzie potrzebujesz prostego kanału diagnostycznego albo połączenia punkt-punkt, ale nie chcesz zaprzątać sobie głowy zegarem magistrali.
Najważniejszy wniosek jest prosty: SPI daje większą kontrolę kosztem większej liczby przewodów. To uczciwy kompromis, który w elektronice bardzo często się opłaca, ale tylko wtedy, gdy dobrze ustawisz elektrykę i protokół.
Skoro wiemy już, kiedy ten interfejs ma sens, przejdźmy do błędów, które najczęściej psują pierwsze uruchomienie i potrafią zmylić nawet osobę z doświadczeniem.
Najczęstsze błędy, które blokują komunikację
- Zły tryb CPOL lub CPHA - układ dostaje zegar, ale próbkowanie odbywa się na niewłaściwym zboczu i odpowiedź wygląda jak losowy szum.
- Pomylone MOSI i MISO - to klasyk, który szczególnie łatwo przeoczyć przy zmianie płytki albo przejściówki.
- Brak wspólnej masy - bez tego sygnały nie mają wspólnego punktu odniesienia i pomiar staje się niepewny.
- Niezgodne poziomy napięć - 5 V i 3,3 V nie powinny być łączone „na próbę”, bo skończy się to błędami albo uszkodzeniem układu.
- Zbyt wysoka częstotliwość zegara - przy dłuższych ścieżkach i słabych zboczach dane przestają być poprawnie odczytywane.
- Niepoprawny CS - zła polaryzacja, zbyt krótki impuls albo przełączanie CS w środku ramki potrafią zabić transmisję.
- Konflikt na MISO w systemie wieloukładowym - jeśli niewybrany peryferyjny nie oddaje linii w stan wysokiej impedancji, magistrala zaczyna się „gryźć”.
- Założenie, że każdy układ używa 8-bitowych słów - część elementów wymaga innych długości ramki i innych bajtów kontrolnych.
W takich przypadkach nie zgaduję. Biorę analizator stanów lub oscyloskop i patrzę na cztery kanały: SCLK, MOSI, MISO i CS. Już sama obserwacja tych przebiegów zwykle pokazuje, czy problemem jest timing, poziom napięcia, czy zwykła pomyłka w konfiguracji. To szybsze niż wielokrotne przepisywanie kodu sterownika.
Jest jeszcze jedna rzecz, która oszczędza czas przy każdym nowym układzie: zanim uznasz połączenie za gotowe, sprawdź kilka konkretnych parametrów w dokumentacji. I właśnie tym kończę ten tekst, bo to najpraktyczniejszy fragment całej układanki.
Co jeszcze sprawdzam, zanim uznam SPI za gotowe
Gdy uruchamiam SPI po raz pierwszy, idę zawsze tą samą krótką ścieżką. Najpierw potwierdzam poziomy napięć, potem tryb CPOL i CPHA, dalej długość słowa, kolejność bitów oraz maksymalną częstotliwość zegara. Dopiero na końcu zwiększam szybkość transmisji, bo zbyt ambitny start często maskuje drobne błędy, które przy wolniejszym zegarze wyszłyby od razu.
- Sprawdź, czy układy pracują w tym samym standardzie napięciowym albo mają konwerter poziomów.
- Potwierdź w nocie katalogowej, czy CS jest aktywne niskim, czy wysokim stanem.
- Ustal, ile bitów ma pojedyncze słowo i czy dane są wysyłane od MSB, czy od LSB.
- Zweryfikuj, czy peryferium nie wymaga dodatkowego opóźnienia między CS a pierwszym impulsem SCLK.
- Jeśli magistrala obsługuje kilka urządzeń, upewnij się, że niewybrane układy nie blokują linii MISO.
W dobrze działającym projekcie SPI nie powinno być magii. Jest tylko porządek w sygnale, zgodność z dokumentacją i cierpliwe sprawdzenie kilku parametrów, zanim podkręcisz zegar. Jeśli podejdziesz do tego właśnie w ten sposób, ten interfejs odwdzięczy się prostą, szybką i bardzo przewidywalną komunikacją między układami.