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.
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:
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
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:
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
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.
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.
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
Due osservazioni:
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:
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:
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:
Data di creazione di questa pagina: luglio 2015
Ultima modifica: 27 dicembre 2015
Una pagina simile: MSSP/SPI (in assembly)
PIC18 in C - Versione 0.991 - luglio 2019
Copyright 2014-2019, Vincenzo Villa (https://www.vincenzov.net)
PIC18 in C di Vincenzo Villa è distribuito con Licenza Creative Commons Attribuzione 4.0 Internazionale