WebElektronika

Egy egyszerű SPI kommunikáció megvalósítása a PIC32MX családban

person access_time 2016.03.25.
Megnézzük ebben a cikkben, hogy hogyan lehet egy egyszerű SPI kommunikációt megvalósítani a PIC32MX795F512L mikrovezérlővel. Ha nem szoftveresen valósítjuk meg az SPI protokollt, akkor ebben a mikrovezérlőben négy belső perifériát használhatunk fel ennek a soros kommunikációnak a megvalósítására.


Megnézzük most az SPI kommunikáció megvalósításának egyik lehetséges megoldását a PIC32MX családnál. Felhasználhatnánk az MCC32-es fordító könyvtárát is, de most mi valósítjuk meg a szükséges függvény(eke)t.

Az első ábrán az SPIxCON regisztert látjuk, amelynek a segítségével tudjuk beállítani az SPI kommunikáció különböző tulajdonságait.
Több SPI is használható a PIC32MX795F512L-es mikrovezérlőnél, mi a SPI1-et fogjuk felhasználni, ezért az SPI1CON regisztert fogjuk programozni.

kep
1. ábra   SPIxCON regiszter
 

A programunk elején létrehozzuk a különböző makrókat, amelyeknek a segítségével beállítjuk majd az SPI1 perifériához tartozó lábaknak (SDI1, SDO1, SS1, SCK1) az irányait. A Slave Select (SS1) jelhez készítünk két makrót is, amelyeknek a segítségével kényelmesen tudjuk logikai 1-be, illetve logikai 0-ba állítani ezt a lábat.

A main() függvény előtt deklaráljuk a writeSPI() függvényt is, amellyel adatot tudunk kiküldeni az SPI buszra. Tekintettel arra, hogy ez a függvény int típusú, ezért az esetleges slave által küldött adat kényelmesen kiolvasható is ezzel.

A main() függvényben beállítjuk az SPI kommunikációhoz szükséges lábak irányát a makrókkal. Ezután az SPI1 perifériát az SPI1CON regiszter írásával állítjuk be (0x8120 = 0B1000 0001 0010 0000). Ezzel az értékadással bekapcsoltuk az SPI1 perifériát (SPI1CON<15>=1), a MODE32 és a MODE16 bitek logikai 0-ban vannak, tehát 8 bites az adatátvitelünk. Fontos, hogy a MSTEN bit logikai 1-ben van, ezzel állítottuk be azt, hogy a PIC32MX795F512L-es mikrovezérlőnk SPI1 perifériája master módban működjön.

Ezt követően az SS1 lábat logikai 1-be tesszük, tehát a slave eszközt (a méréseknél nem szerepelt) tiltjuk.

A while(1) ciklusban állandóan kitesszük az SPI buszra a writeSPI() függvény paraméterlistájában átadott értéket.

#include <p32xxxx.h>

#define    TSDO1    TRISDbits.TRISD0
#define    TSDI1    TRISCbits.TRISC4
#define    TSS1    TRISDbits.TRISD9
#define    TSCK1    TRISDbits.TRISD10
#define    SS1        LATDbits.LATD9
#define    SS1On()    {SS1 = 1;}
#define    SS1Off(){SS1 = 0;}

int writeSPI(int adat)
{
    SPI1BUF = adat;
    while(!SPI1STATbits.SPIRBF);
    return SPI1BUF;
}

main()
{
    TSS1 = 0;
    TSDO1 = 0;
    TSDI1 = 1;
    TSCK1 = 0;
    SPI1CON = 0x8120;
    SPI1BRG = 10;
    SS1On();
    
    while(1)
    {
        SS1Off();
        writeSPI(123);
        SS1On();
    }
}

 

Az SPI1CON értékadást feketével emeltük ki, mert ezt az értéket fogjuk majd többször megváltoztatni. Az első esetben (SPI1CON=0x8120;) 8 bites módban használjuk az SPI1-es modult. Az SDO kimeneten a decimális 123-as értéket küdjük ki. Ezt láthatjuk a 2. ábrán.

kep
2. ábra   A decimális 123-as érték az SPI buszon
 

Módosítsuk most az SPI1CON=0x8120 értékadást a 0x8520-ra (MODE16=1). Ekkor a 8 bites mód helyett a 16 bites üzemmódot alkalmazzuk az SPI buszon (3. ábra).

kep
3. ábra   16 biten küldjük ki sorosan a 123-as értéket
 

Módosítsuk most megint az SPI1CON regiszter értékét (0x8920), hogy 32 bites módban tudjuk alkalmazni az SPI protokollt (4. ábra). A kiküldött adat nem változott (123).

kep
4. ábra   32 bites üzemmód alkalmazása
 

Maradjunk a 32 bites üzemmódnál, de a kiküldött adat ne két byte-os legyen, hanem 4 byte. A writeSPI() függvény paraméterét módosítsuk a meghívásakor, 123456789-et küldjük ki az SPI buszra (5. ábra).

kep
5. ábra   32 bites módban küldjük ki az 123456789-es értéket