Reklama

SPI u AVR 1. Díl – Teorie

Úvod

V tomto tutoriálu si nejprve popíšeme, jak funguje SPI modul na mikrokontrolérech AVR. A pak si jeho ovládání předvedeme na čtyřech příkladech. První tři příklady budou demonstrovat ovládání mikrokontrolérů AVR v rolích Master a Slave, při kterých byste měli získat pohled na ovládání SPI modulu. Poslední příklad bude trochu neobvyklý. Předvedeme si v něm jak ovládat digitální potenciometr. Neobvyklé na něm bude to, že se budeme zabývat více digitálním potenciometrem než mikrokontrolérem. Jednak si na něm upevníte znalosti ovládání SPI na mikrokontroléru a zadruhé tím možná získáte schopnost vybavit vaše návrhy velice užitečným obvodem.

Popis

Hardware sloužící k SPI komunikaci najdete nejspíš na všech mikrokontrolérech řady ATmega. ATtiny používají USI (Universální sériové rozhraní), ale některé mají i SPI rozhraní (ATtiny88). Skoro všichni SPI rozhraní ATmelu používáte i když o tom nemusíte vědět. ISP programátory totiž využívají SPI rozhraní čipu k nahrání programu. Což do některých aplikací zavádí jisté komplikace, ale o tom až později. SPI na AVR umožňuje plně duplexní přenos s bitovou rychlostí až do poloviny taktu procesoru. Může pracovat jako Master i jako Slave obvodu a pořadí bitů ve zprávě lze nastavovat softwarově. Kromě toho může SPI generovat přerušení, nebo také mikrokontrolér probrat ze spánku. Používání SPI v roli Mastera je velice snadné, takže si ho určitě oblíbíte. Ke komunikaci používáte dvě až čtyři linky. MISO, MOSI, SCK a v roli Slave obvodu ještě SS pin. O funkci prvních třech linek jste se jistě dočetli v předchozím návodu (SPI rozhraní). Proto jen doplním roli SS pinu. Pokud je mikrokontrolér v roli Slave obvodu, tak má SS pin přesně tu samou roli jako obecně CS (Chip select). Slouží k aktivaci Slave obvodu. Přivedením log. 0 na tento vstup je Slave obvod aktivován a nastaví svůj MISO pin jako výstup a může komunikovat. Naopak jestliže je jeho SS vstup držen v log. 1, tak udržuje Slave obvod MISO linku ve stavu vysoké impedance (Hi-Z) a neprovádí žádnou komunikaci. To celé obstarává SPI modul v mikrokontroléru sám. Velmi podobné chování má SS pin i když je mikrokontrolér v roli Mastera. Tam by se dalo očekávat, že signál CS nemá žádný význam. A také nemá, pokud je SS pin (PB4 na Atmega16) nastaven jako výstup. Jestliže je ale SS pin nastaven jako vstup, tak je potřeba zajistit aby na něm byla log.1 (třeba interním “pull-up” rezistorem). Jakmile se na něm totiž objeví log. 0, přepne se Master do role Slave! To slouží k tomu, aby spolu mohlo komunikovat více Master obvodů. O správě SS pinu se dozvíte více v prvním příkladu.

SPI a ISP zároveň

Fakt, že SPI rozhraní je používáno k programování čipu, přináší drobné komplikace a je dobré se s nimi vypořádat co nejdříve. Ti, kteří se plácli přes kapsu, koupili Atmel-ICE a programují čip JTAG rozhraním, nebo ti kteří využívají bootloader a programují UARTem, tak mohou tuto kapitolu klidně přeskočit. Nejprve se na věc podíváme z pohledu programátoru. ISP programátor potřebuje možnost používat vývody RST, MISO, MOSI a SCK. Je tedy potřeba zajistit, že žádné další zařízení nebude některou z linek blokovat (třeba tak, že k některé z nich bude mít připojen svůj výstup). To lze zajistit snadno. Postačí, když je od programovaného čipu sběrnice oddělena rezistory (viz, Obr. 1). Díky oddělovacím rezistorům není jakékoli zařízení na sběrnici schopné držet MISO, MOSI nebo SCK tvrdě, protože rezistor jejich výstupy “změkčí”. Programovaný mikrokontrolér a programátor si na těchto pinech mohou vynutit hodnoty, jaké potřebují. Příliš velké rezistory mohou ale snižovat maximální přenosovou rychlost (pokud je kapacita sběrnice větší). Hodnoty je proto dobré volit ve stovkách ohmů. Já používal zlatý střed 470R. Problémy mohou nastat u menších AVR mikrokontrolérů, kde může být některý z pinů sdílen třeba s AREF. Na ten byste mohli chtít připojit kondenzátor k filtraci vnitřní reference. Kondenzátor na datové lince ale hrubě omezuje komunikační rychlost. U levných programátorů USBASP nemusí být možné snížit komunikační rychlost. Těm pak jakýkoli kondenzátor na kterékoli komunikační lince znemožňuje programování. Pak vám nezbývá než ručně nebo nějakým přepínačem přepojovat problematické piny mezi programátorem a zbytkem obvodu. To je ale jen okrajová záležitost. Trochu pozornosti byste měli věnovat také tomu co se děje s SPI, když mikrokontrolér restartujete. Pokud totiž čip držíte “v resetu” (pin RST v log. 0), tak by na SPI neměl probíhat žádný provoz. Mikrokontrolér by to mohl pochopit tak, že ho programujete :D Pokud bude mikrokontrolér jediným masterem na sběrnici, tak lze skoro vždy připojit sběrnici i programátor bez oddělovacích rezistorů. Pokud nechcete, aby Slave obvody během programování nepřijímaly “nesmysly”, musíte pohlídat, aby byly během programování deaktivovány. Žádný pin CS nesmí být ve stavu log. 0, protože pak by Slave obvod přijímal a nějak interpretoval data proudící z programátoru do mikrokontroléru. Typicky budete mít CS piny připojeny k vývodům mikrokontroléru. Ten během programování držíte “v resetu” a všechny jeho vývody budou nastaveny jako vstupy bez “pull-up” rezistorů (tak jako bezprostředně po restartu). Bude tedy obvykle nutné vybavit CS linky externím “pull-up” rezistorem (pokud už není součástí Slave obvodu), aby v takovém případě zůstaly CS linky ve stavu log.1.

 
Obr. 1: Připojení ISP programátoru a SPI

Obr. 1: Připojení ISP programátoru a SPI
SPI – registry

Řízení SPI se provádí pomocí tří registrů SPCR, SPSR a SPDR. Registr SPDR slouží k manipulaci s daty. Zápisem do něj uložíte data do posuvného registru, odkud se pak data přímo odesílají. Nesmíte tedy do něj zapisovat během přenosu. Pokud to uděláte, informuje vás o tom stavový bit WCOL v registru SPSR. Pro čtení má SPDR vyrovnávací paměť. Pokud tedy z SPDR vyčtete data, tak nevidíte obsah posuvného registru, ale poslední přijatý byte. Díky tomu můžete přijímat zprávy bez prodlev. Jeden byte vám dorazí a mezi tím než na to zareagujete a vyčtete jej, tak může probíhat příjem dalšího bytu. Protože v roli Slave obvodu nemáte žádnou možnost vysílací stranu pozdržet, abyste měli dost času si data z SPDR vyzvednout, tak je tato vlastnost nutností. Uvědomte si, že pro příjem i vysílání máte jen jeden posuvný registr. Pokud tedy do něj něco dorazí a vy jeho obsah nepřepíšete (zápisem do SPDR), tak se v příštím přenosu jeho obsah odvysílá. To se vám může hodit, může vás to rozčilovat anebo vám to může být jedno. Užitečná je tato funkce pokud využíváte řetězení Slave obvodů. Jedno vám to může být, pokud váš výstup (MOSI pokud jste Master a MISO pokud jste Slave) nikam nevede anebo data z něj nikoho nezajímají. V roli Mastera se zápisem do SPDR rovnou spustí přenos.
Registr SPCR slouží k řízení periferie SPI. SPI povolujete nebo zakazujete bitem SPE. Povolením převezme SPI kontrolu nad příslušnými vývody (podle režimu Slave nebo Master). Pomocí bitu SPIE povolujete přerušení, které je vyvoláno nastavením bitu SPIF. Bit DORD nastavuje řazení dat ve zprávě. V log. 1 se nejprve odesílá LSB, v log. 0 pak MSB. Bity CPOL a CPHA nastavujete mód (viz, obrázek na wiki). Nastavením bitu MSTR zapínáte režim Master. Tady je na místě poznamenat, že pokud je vývod SS (pin PB4) Masteru nastaven jako vstup a je na něj přivedena stav log. 0, tak se přepne do role Slave a bit MSTR se vynuluje. Tato funkce může posloužit, pokud má pracovat více Masterů obvodů na jedné sběrnici. Jeden Master tak může ostatní Mastery dočasně změnit na Slave (“Zotročit” :D) a odeslat jim zprávu. Dvojice bitů SPR1 a SPR0 slouží k nastavení přenosové rychlosti. Tu je dobré udržovat v rozumných mezích. Slave totiž ke spolehlivému přijetí zprávy potřebuje, aby frekvence procesoru byla alespoň dvakrát větší než je komunikační rychlost (frekvence na pinu SCK).

Tab. 1: SPCR (SPI Control Register)

Pozice bitu Označení
7 – (nejvyšší váha) SPIE
6 SPE
5 DORD
4 MSTR
3 CPOL
2 CPHA
1 SPR1
0 – (nejnižší váha) SPR0

 

Nastavení módu SPI je shrnuto v Tab. 2. O módech jste se mohli dočíst v předešlých článcích zde (SPI rozhraní). V Tab. 3. je seznam datových rychlostí. Kromě bitů SPR1 a SPR0 má na rychlost také vliv bit SPI2X v registru SPSR, který rychlost násobí dvěma. V roli Slave nemá přirozeně nastavení těchto bitů žádný význam.

Tab. 2: Nastavení módu SPI

Režim CPOL CPHA
0 0 0
1 0 1
2 1 0
3 1 1

 

Tab. 3: Nastavení datové rychlosti

SPI2X SPR1 SPR0 frekvence SCK
0 0 0 hodiny procesoru / 4
0 0 1 hodiny procesoru / 16
0 1 0 hodiny procesoru / 64
0 1 1 hodiny procesoru / 128
1 0 0 hodiny procesoru / 2
1 0 1 hodiny procesoru / 8
1 1 0 hodiny procesoru / 32
1 1 1 hodiny procesoru / 64

 

Registr SPSR obsahuje dvojici stavových bitů. Stavový bit WCOL o kterém jsme již mluvili a který signalizuje zápis do SPDR během přenosu a stavový bit SPIF. Ten signalizuje několik věcí. V prvé řadě dokončení přenosu. Ať v roli Master nebo Slave obvodu, jakmile je přenesen celý byte, tak se bit nastaví (a případně se volá přerušení). Pokud je mikrokontrolér v roli Masteru a je pomocí SS pinu přepnut do role Slave, tak se nastaví také bit SPIF. Smazání obou bitů se provádí čtením z registru SPSR a následným přístupem k registru SPDR (čtením nebo zápisem do něj). Tento přístup je logický. Po ukončení přenosu (o němž se dozvíte čtením SPSR) byste měli z SPDR vyčíst přijatá data a případně do něj zapsat nová. Čímž dojde ke smazání stavového bitu. Pokud máte povolené přerušení tak se o mazání bitu nemusíte starat, protože se maže sám při příchodu do rutiny přerušení.

Tab. 1: SPCR (SPI Control Register)

Pozice bitu Označení
7 – (nejvyšší váha) SPIF
6 WCOL
5 -
4 -
3 -
2 -
1 -
0 – (nejnižší váha) SPI2X

 
Zbytek teorie si již vysvětlíme na příkladech v příštích dílech.
 
 
Autor: Michal Dudka
 
 

Jiné příspěvky v kategorii:

 
SPI u AVR 2. Díl – Praktické příklady I.
SPI u AVR 3. Díl – Praktické příklady II.
 
Tajned facebook
 

Za případné chyby v textu, ve zdrojovém kódě, nebo ve schématickém zapojení se omlouváme.
AUTOŘI NEBEROU ŽÁDNOU ODPOVĚDNOST ZA PŘÍPADNÉ ÚJMY NA ZDRAVÍ ČI MAJETKU.