Salta la barra di navigazione [1] - Vai alla barra di navigazione [3] - Scrivimi una mail [4]

Master SPI

PIC18 in C - Sommario - Novità - Tutorial - Progetti - Risorse - Non solo elettronica

I segnali dell'interfaccia SPI

In questa pagina viene mostrato come utilizzare SPI per collegare una periferica esterna al PIC18 sfruttando il modulo MSSP Master Synchronous Serial Port.

In questa pagina non è spiegato cosa è e come si usa il bus SPI. Se serve, qui trovate qualche informazione.

La struttura di MSSP

MSSP è il cuore delle interfacce seriali sincrone del PIC18 sia SPI che I2C, sia master che slave.

Volendo semplificare al massimo, possiamo descrivere questo modulo come un registro a scorrimento in cui il processore scrive in modo parallelo il byte da trasmettere e l'hardware provvede alla trasmissione seriale, un bit alla volta. La ricezione è analoga (e contemporanea) alla trasmissione: l'hardware riceve serialmente 8 bit e questi vengono passati in modo parallelo al processore.

Lo schema a blocchi semplificato, in modalità SPI master:

MSSP

I due blocchi principali sono:

All'esterno sono presenti tre pin. Si noti che, in modo master non è prevista la gestione automatica di alcuno Slave Select: occorre utilizzare un generico pin di una PORTx, da gestire esplicitamente.

Occorre infine tenere presente che MSSP è condiviso tra SPI e I2C e che quindi tali bus sono mutuamente esclusivi. Se dovessero servire entrambi contemporaneamente è comunque possibile usare l'opzione software oppure usare un PIC con doppio modulo MSSP

Programmare l'interfaccia SPI

Il primo codice di esempio non utilizza alcuna periferica. Per osservare i segnali è quindi necessario l'uso di un oscilloscopio, se possibile dotato di decodifica seriale.

La trasmissione è sempre full-duplex: durante la scrittura di un byte sul pin MOSI, viene letto un byte sul pin MISO. Il segnale in ingresso, in assenza di hardware reale, può essere ottenuto in tre modi:

Configurare i pin di I/O

Innanzitutto occorre configurare i pin di I/O utilizzati dal bus:

TRISCbits.RC5 = 0; // Set MOSI pin as output
TRISCbits.RC3 = 0; // Set clock pin as output
TRISBbits.RB1 = 0; // Set Slave Select pin as output
TRISCbits.RC4 = 1; // Set MISO pin as input

L'unica avvertenza è legata al fatto che, per quasi tutti i PIC18, MOSI, MISO e Clock sono associati a pin fisici non modificabili. Gli Slave Select, in genere più di uno, sono invece assegnabili a pin arbitrari in quanto non gestiti dall'MSSP

Configurare il modulo MSSP

Per configurare il modulo MSSP occorre:

SSPCON1bits.SSPEN = 1;     // Synchronous Serial Port Enable bit
SSPCON1bits.SSPM = 0b0000; // SPI Master mode, clock = FOSC/4
SSPSTATbits.CKE = 1;       // 1 = Transmit occurs on transition from active to Idle clock state
SSPCON1bits.CKP = 0;       // Idle state for clock is a low level
SSPSTATbits.SMP = 0;       // Input data sampled at middle of data output time

Per la descrizione di dettaglio dei registri è bene far riferimento ai fogli tecnici, nel capitolo che descrive il modulo MSSP (o i moduli MSSP) del processore utilizzato.

Una volta configurato, l'uso del modulo MSSP per trasmettere o ricevere un byte è oltremodo semplice:

Il codice:

SSPBUF = byte_to_send;   // Send 8 bit to slave
while (!SSPSTATbits.BF); // SSPBUF is empty?
byte_recived = SSPBUF;   // Read byte from slave

Occorre inoltre attivare e disattivare lo Slave Select prima di trasmettere il primo byte e dopo aver trasmesso l'ultimo.

Di seguito il diagramma temporale durante l'esecuzione del codice riportato: la trasmissione ha clock (verde) pari a 250 kHz e il clock del processore è impostato a 1 MHz; il dato, 0xA1, è in blu.

SPI - diagramma temporale

Il tempo necessario alla trasmissione di un byte è rigorosamente pari a 8 x 4  µs = 32 µs, ma in realtà per la trasmissione è necessario un tempo più che doppio a causa delle operazioni che devono essere svolte dal software (intervallo tra i due fronti dello Slave Select, in rosso).

Il secondo grafico è relativo allo stesso programma eseguito impostando il clock del processore a 16 MHz e mantenendo il clock SPI ancora a 250 kHz; le modifiche necessarie sono state inserite come commento. Il tempo necessario alla trasmissione di un byte è ovviamente ancora pari a 8 x 4  µs = 32 µs, ma in questo caso le operazioni svolte in software sono estremamente più veloci, permettendo un throughput maggiore.

SPI - diagramma temporale

Infine l'ultimo grafico mostra come si comporta un PIC18 impostando alla massima frequenza il clock SPI ed il clock del processore (rispettivamente per il PIC18F25K20 16 MHz e 64 MHz). Osservazione 1

SPI - diagramma temporale

Due osservazioni:

Colleghiamo una periferica reale

Un bus SPI ha senso solo collegando periferiche... Il circuito utilizzato a titolo di esempio è descritto in questa pagina ed utilizza un PIC18F25K20 e un ADC a 12 bit MAX 146. Nel circuito è presente anche un DAC a 12 bit MCP4822, oggetto del primo esercizio.

Ovviamente il codice è strettamente dipendente dalla periferica utilizzata e le informazioni necessarie alla scrittura del codice devono essere ricavate dai fogli tecnici di quest'ultima

Il codice completo relativo al MAX146 è disponibile a fondo pagina ed è basato su quanto già descritto in questa pagina.

Nell'esempio, specifico per il MAX 146, viene mostrato la lettura della tensione presente sul canale 0:

Il primo byte trasmesso (Control Byte) nell'esempio è fisso e vale 0x8F; il suo significato è specifico per il MAX 146 ed è descritto nella Table 1  dei fogli tecnici. Esso permette di:

Il diagramma temporale non presenta particolari sorprese, sapendo che la frequenza di clock è stata impostata a 250 kHz:

Qualche osservazione:

Un altro esempio: full-duplex

Spesso lo scambio di informazioni utilizzando SPI è realizzato in modalità full-duplex. In astratto, anche la comunicazione nel precedente diagramma temporale è full-duplex, ma si tratta un esempio poco significativo, essendo uno dei byte in uno dei due versi sempre nullo,

L'esempio proposto a fondo pagina utilizza lo stesso hardware appena visto; la modalità di comunicazione usata da MAX146 però non utilizza più lo Slave Select tra una conversione e l'altra, ma effettua un gruppo di campionamenti consecutivi, modalità descritta nel dettaglio dalla figura 11b dei fogli tecnici. In pratica una nuova conversione viene avviata mentre è ancora in corso il trasferimento del risultato della precedente:

  1. Il master trasmette il comando di inizio di una conversione
  2. Lo slave trasmette la risposta con il primo byte contenente i primi 7 bit del risultato della conversione. Il Master trasmette un byte nullo
  3. Lo slave trasmette il secondo byte con i rimanenti 5 bit e, contemporaneamente, il master  trasmette il comando di inizio di una nuova conversione
  4. Il processo ricomincia al punto 2, per tutte le volte per cui è necessario

Nell'esempio vengono letti consecutivamente gli 8 canali, scambiando complessivamente 17 byte: 2 byte per ciascun canale più l'ultimo per completare l'ultima lettura

Al fine di rendere realistico e tecnicamente corretto lo scenario è stata utilizzata una frequenza di funzionamento del processore di 64 MHz e di 1 MHz per il bus SPI.

Il codice è riportato a fondo pagina. In sintesi:

Il diagramma temporale:

Dall'alto:

Codice sorgente

Esercizi

  1. Scrivere il codice per la gestione del MCP4822 (o di altra periferica SPI disponibile)
  2. Scrivere la funzione int Get_mV_ADC (int channel) il cui scopo è leggere la tensione applicata al canale channel del MAX146, ritornando il risultato in mV
  3. Analizzare il seguente codice: SPI-Master-esercizio.c

Osservazioni

  1. Il diagramma temporale mostrato è stato misurato con oscilloscopio da 100 MHz (sonde 10X da 150 MHz, campionamento 1 Gsps), e quindi non particolarmente adatto a ricostruire un segnale digitale con frequenza 16 MHz. Inoltre parte dei collegamenti erano realizzati su breadboard
  2. La struttura di MSSP permette di ricevere un byte mentre si sta ricevendo un secondo byte (doppio buffer). In trasmissione questo meccanismo non è invece implementato

Una pagina simile: MSSP/SPI (in assembly)


PIC18 in C

Appendici:

Qualche utile informazione integrativa: C per sistemi embedded

Licenza Creative Commons Attribuzione 4.0 Internazionale


EN - Pagina principale - Sommario - Accessibilità - Note legali e privacy policy - Posta elettronica

XHTML 1.0 Strict - CSS 3