arduino
Comunicazione SPI
Ricerca…
Osservazioni
Segnali di selezione del chip
La maggior parte degli slave ha un input di selezione chip basso attivo. Quindi il codice corretto per inizializzare e utilizzare un pin di selezione del chip è questo:
#define CSPIN 1 // or whatever else your CS pin is
// init:
pinMode(CSPIN, OUTPUT);
digitalWrite(CSPIN, 1); // deselect
// use:
digitalWrite(CSPIN, 0); // select
... perform data transfer ...
digitalWrite(CSPIN, 1); // deselect
Deselezionare uno slave è importante quanto selezionarlo, perché uno slave può guidare la linea MISO mentre è selezionata. Potrebbero esserci molti schiavi, ma solo uno può guidare MISO. Se uno slave non viene deselezionato correttamente, due o più slave potrebbero essere alla guida di MISO, il che potrebbe causare cortocircuiti tra le loro uscite e danneggiare i dispositivi.
Le transazioni
Le transazioni hanno due scopi:
- dillo allo SPI quando vogliamo iniziare e terminarlo usandolo in un contesto particolare
- configurare l'SPI per un chip specifico
La linea dell'orologio ha diversi stati di inattività nelle diverse modalità SPI. La modifica della modalità SPI mentre è selezionato uno slave potrebbe confondere lo slave, quindi impostare sempre la modalità SPI prima di selezionare uno slave. La modalità SPI può essere impostata con un oggetto SPISettings
passato a SPI.beginTransaction
:
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
digitalWrite(CSPIN, 0);
... perform data transfer ...
digitalWrite(CSPIN, 1);
SPI.endTransaction();
SPISettings
può anche essere memorizzato altrove:
SPISettings mySettings(1000000, MSBFIRST, SPI_MODE0);
SPI.beginTransaction(mySettings);
Se un'altra parte del codice tenta di utilizzare l'SPI tra una coppia di chiamate a beginTransaction()
e endTransaction()
, può essere generato un errore - il modo in cui ciò avviene dipende dall'implementazione.
Vedi anche Riferimento Arduino: SPISettings
Utilizzo dello SPI nelle routine di servizio di interrupt
Se l'SPI deve essere utilizzato all'interno di un ISR, non possono essere eseguite altre transazioni contemporaneamente. La libreria SPI fornisce usingInterrupt(interrupt_number)
per facilitare questo. Funziona disabilitando l'interrupt dato ogni volta che viene chiamato beginTransaction()
, quindi l'interrupt non può sparare tra quella coppia per le chiamate a beginTransaction()
e endTransaction()
.
Vedi anche Riferimento Arduino: SPI: usingInterrupt
Nozioni di base: inizializza l'SPI e un pin di selezione del chip ed esegui un trasferimento da 1 byte
#include <SPI.h>
#define CSPIN 1
void setup() {
pinMode(CSPIN, OUTPUT); // init chip select pin as an output
digitalWrite(CSPIN, 1); // most slaves interpret a high level on CS as "deasserted"
SPI.begin();
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
digitalWrite(CSPIN, 0);
unsigned char sent = 0x01;
unsigned char received = SPI.transfer(sent);
// more data could be transferred here
digitalWrite(CSPIN, 1);
SPI.endTransaction();
SPI.end();
}
void loop() {
// we don't need loop code in this example.
}
Questo esempio:
- inizializza correttamente e usa un pin di selezione chip (vedi note)
- utilizza correttamente una transazione SPI (vedi osservazioni)
- utilizza solo SPI per trasferire un singolo byte. Esiste anche un metodo per il trasferimento degli array, che non viene utilizzato qui.