Rozhraní SPI patří k těm nejjednodušším se kterými se lze v světě mikrokontrolerů setkat. A právě díky své jednoduchosti nachází široké uplatnění. Mít o něm povědomí patří k základní výbavě programátora embedded aplikací.
Tento článek se bude věnovat principům SPI komunikace. Slouží jako základní kámen pro další navazující články o SPI na Atmelech a na STM32. SPI je zkratka pro Serial Peripheral Interface a rozhraní slouží pro komunikaci mikrokontrolérů mezi sebou nebo s periferiemi. Mezi ně mohou patřit paměti, AD a DA převodníky, čidla různých veličin, displeje, drivery všeho druhu, SD karty a mnoho dalších. Přenos po SPI bývá typicky duplexní (data tečou oběma směry zároveň), ale v některých aplikacích může být simplexní (data tečou pouze jedním směrem). Přenos je synchronní (používá clock), takže může dosahovat slušných datových toků (STM32F429 až 45 Mbit/s, Atmega16A až 8 Mbit/s). Princip komunikace je jednoduchý a díky tomu je na většině mikrokontrolerů snadná i jeho implementace. Sběrnice je koncipována tak aby na ní pracoval jeden master a obecně vzato neomezené množství slave. Všechna zařízení sdílejí trojici linek. Clock (SCLK), který je generován masterem. Linku MOSI (Master Out Slave In) po níž tečou data z masteru do slave a linku MISO (Master In Slave Out) po které tečou data ze slave do master. Každý slave má vlastní "Chip Select" (CS) linku (někdy také "Slave select" - SS), která slouží jako "adresovací". Master tedy musí obsluhovat tolik CS linek kolik je na sběrnici připojeno slave obvodů.
Na obrázku 1 je příklad zapojení 4 slave obvodů na SPI. Slave 4 je atypický, protože nemá vývod MOSI. Není tedy schopen data přijímat. Může pouze odesílat. Takovou konfiguraci mají třeba některé AD převodníky. Zbylé tři slave obvody mají možnost duplexní komunikace (mají MOSI i MISO). Označování linek není jednotné ale většinou bývá dobře čitelné. Clock se označuje například SCK, CLK nebo SCLK. Někdy mají obvody linky označené SDI, SI nebo DI (Device Input - vstup do zařízení) a SDO, SO nebo DO (Device Output - výstup ze zařízení). Vzhledem k tomu, že k lince MISO je připojeno více slave zařízení, musí master zařídit aby k ní v jednom okamžiku přistupovalo pouze jedno zařízení. K tomu slouží linky CS ovládané masterem. Dokud má slave vstup CS v log.1, je neaktivní, udržuje svůj MISO vývod ve stavu vysoké impedance (Hi-Z) a nijak neovlivňuje stav MISO linky. Jestliže je slave aktivován (CS v log.0), nastaví svůj vývod MISO jako výstup a začne linku ovládat. Master pomocí CS linek vybírá se kterým slave obvodem chce komunikovat.
Jak "adresovat" slave už víme. Teď nám zbývá pochopit jak dochází k přenosu dat. Jakmile master pomocí CS pinu vybere některý slave obvod, začne generovat clock. S každým tiknutím clocku (tedy s každou periodou) se přenese jeden bit po lince MOSI (z masteru do slave) a zároveň jeden bit po lince MISO (ze slave do masteru). Počet datových bitů není obecně nijak specifikován. Běžně se používá 8 nebo 16. Zřídka se setkáte s 24 nebo 32 bity. Clock definuje ve kterém okamžiku má přijímač datovou linku (MOSI nebo MISO) číst. Může to být buďto s vzestupnou hranou nebo se sestupnou hranou SCLK. Žádná specifikace to pevně neurčuje. Také není pevně dáno jakou logickou hodnotu má mít SCLK linka v neutrálním stavu. Existují proto čtyři možnosti jak přenos může vypadat.
obrázek 2 - Přenos 0b11001001 v Módu 0 (data se čtou na vzestupnou hranu CLK) | obrázek 3 - Přenos 0b11001001 v Módu 1 (data se čtou na sestupnou hranu CLK) |
obrázek 4 - Přenos 0b11001001 v Módu 2 (data se čtou na sestupnou hranu CLK) | obrázek 5 - Přenos 0b11001001 v Módu 3 (data se čtou na vzestupnou hranu CLK) |
Podívejte se například na běžný logický obvod 74HC595. Jedná se posuvný registr s pamětí (latch). Pomocí SPI do něj zapíšete data (SCK připojíte ke vstupu SHCP a MOSI k DS). A přivedením vzestupné hrany na vstup STCP se posledních osm nahrátých bitů přenese do vnitřní paměti a nastaví se podle nich osm výstupů (Q0 až Q7). Obvod funguje jako "převodník" seriových dat na paralelní. Byte který po seriové lince nahrajete do '595' se paralelně objeví na jeho výstupech. Můžete si na výstupy dát LEDky nebo sadu relé, to už je na vás. Podstatné je to, že pomocí tří vývodů na mikrokontroléru jste schopni řídit 8 logických stavů na výstupu. To už je samo o sobě dosti užitečné, ale 8 výstupů vám nemusí stačit. Naštěstí je obvod řešen tak, že je sedmý (poslední) bit v posuvném registru vyveden na výstup Q7S. Takže když do obvodu začnete nahrávat novou osmici bitů, tak z vývodu Q7S postupně odchází původní obsah posuvného registru. To ale znamená, že výstup prvního obvodu můžete připojit na vstup druhého obvodu a získáte tím 16 bitový posuvný registr. Namísto 8 bitů pak přirozeně vysíláte 16. Takhle můžete obvody řetězit v podstatě do nekonečna. Pak nemáte problém ovládat libovolné množství výstupů jen za pomoci několika vodičů. Přirozeně, čím delší je řetěz obvodů '595', tím déle do nich data nahráváte (což při rychlostech jednotek Mbit/s u většiny aplikací nečiní potíže). Anglicky se takovému řetězení říká "daisy-chain" a zapojení vidíte na obrázku 6. Všimněte si, že výstup (MISO) posledního slave obvodu je přiveden zpět k masteru. To není nutné, ale některé obvody umožňují odesílat touto cestou nějáké stavové informace. Krom toho je takhle možné zjistit zda není řetěz někde přerušený. Je potřeba si uvědomit, že ne každý obvod vybavený SPI tuto konfiguraci umožňuje. Obecně je to spíše vyjímka a umožňují ji typicky obvody, které nepotřebují vysílat data zpět do masteru (tedy obvody u nichž bychom očekávali jednosměrnou komunikaci master >> slave). Informativní ukázku takové komunikace (16bit) můžete vidět na obrázku 7.
Obvod 75HC595 (nebo jeho ekvivalenty) lze využívat pro jednoduché buzení sedmisegmentových displejů. Zvláště dvoj a vícemístných, případně "dotmatrix" displejů. Obecně to ale není nejlepší metoda, protože multiplexované řízení displeje má velké proudové nároky. Obvody '595' ale obecně nesmí dodávat větší celkový proud jak 70mA a to pro méně jasné displeje (zelené, žluté a některé červené) nemusí stačit. Tento limit se v konečném důsledku může také projevovat rozdílným jasem různých cifer. Přirozeně tyto problémy nastávají hlavně pokud po displeji vyžadujeme větší jas (pro práci za denního osvětlení a podobně). Pro tyto účely ale existují vhodnější integrované obvody (a moduly s nimi). Klasický reprezentat je MAX7219, který umí řídit až 8 místný displej se společnou katodou nebo "dotmatrix displej" v rozměru 8x8 bodů. Zvláště u nich oceníte možnost obvody řetězit za sebe. Můžete pak skládat libovolné množství těchto displejů za sebe a jako celek je řídit pomocí tří linek (CLK, DIN, CS). Dalším zástupcem do rodiny SPI řízených driverů s možností řetězení je SCT2024 (a jeho ekvivalenty). Jedná se o relativně levný 16 bitový posuvný registr jehož výstupy jsou proudové zdroje. Oproti MAX7219 se hodí k řízení displejů sestavených z jednociferných sedmisegmentovek (neprovádí totiž multiplexování jako MAX7219) nebo obecně jako budič led (třeba bargrafů). To už ale hodně odbočujeme od tématu. Řízení LED displejů se budu věnovat v samostatné kapitole.