Arduino - szeregowy interfejs peryferyjny
Magistrala Serial Peripheral Interface (SPI) to system komunikacji szeregowej, który wykorzystuje do czterech przewodów, zwykle trzech. Jeden przewodnik służy do odbierania danych, jeden do wysyłania danych, jeden do synchronizacji, a drugi do wyboru urządzenia do komunikacji. Jest to połączenie typu full duplex, co oznacza, że dane są wysyłane i odbierane jednocześnie. Maksymalna prędkość transmisji jest wyższa niż w systemie komunikacji I2C.
Piny tablicy SPI
SPI wykorzystuje następujące cztery przewody -
SCK - To jest zegar szeregowy sterowany przez mastera.
MOSI - To jest wyjście master / wejście slave sterowane przez master.
MISO - To jest wejście master / wyjście slave sterowane przez master.
SS - To jest przewód wyboru urządzenia podrzędnego.
Używane są następujące funkcje. Musisz dołączyć SPI.h.
SPI.begin() - Inicjuje magistralę SPI, ustawiając SCK, MOSI i SS na wyjściach, wyciągając SCK i MOSI w stan niski i wysoki SS.
SPI.setClockDivider(divider)- Aby ustawić dzielnik zegara SPI względem zegara systemowego. Na płytach opartych na AVR dostępne są dzielniki 2, 4, 8, 16, 32, 64 lub 128. Domyślne ustawienie to SPI_CLOCK_DIV4, które ustawia zegar SPI na jedną czwartą częstotliwości zegara systemowego (5 MHz dla płyty przy 20 MHz).
Divider - Może to być (SPI_CLOCK_DIV2, SPI_CLOCK_DIV4, SPI_CLOCK_DIV8, SPI_CLOCK_DIV16, SPI_CLOCK_DIV32, SPI_CLOCK_DIV64, SPI_CLOCK_DIV128).
SPI.transfer(val) - Transfer SPI opiera się na jednoczesnym wysyłaniu i odbieraniu: odebrane dane są zwracane w formacie receivedVal.
SPI.beginTransaction(SPISettings(speedMaximum, dataOrder, dataMode)) - speedMaximum to zegar, dataOrder (MSBFIRST lub LSBFIRST), dataMode (SPI_MODE0, SPI_MODE1, SPI_MODE2 lub SPI_MODE3).
Mamy cztery tryby pracy w SPI w następujący sposób -
Mode 0 (the default) - Zegar jest zwykle niski (CPOL = 0), a dane są próbkowane przy przejściu od niskiego do wysokiego (zbocze narastające) (CPHA = 0).
Mode 1 - Zegar jest normalnie niski (CPOL = 0), a dane są próbkowane przy przejściu od wysokiego do niskiego (zbocze opadające) (CPHA = 1).
Mode 2 - Zegar jest zwykle wysoki (CPOL = 1), a dane są próbkowane przy przejściu od wysokiego do niskiego (zbocze narastające) (CPHA = 0).
Mode 3 - Zegar jest zwykle wysoki (CPOL = 1), a dane są próbkowane przy przejściu od niskiego do wysokiego (zbocze opadające) (CPHA = 1).
SPI.attachInterrupt(handler) - Funkcja wywoływana, gdy urządzenie slave otrzymuje dane od mastera.
Teraz połączymy ze sobą dwie płyty Arduino UNO; jeden jako pan, a drugi jako niewolnik.
- (SS): pin 10
- (MOSI): pin 11
- (MISO): pin 12
- (SCK): pin 13
Ziemia jest wspólna. Poniżej znajduje się schematyczne przedstawienie połączenia między obiema płytami -
Zobaczmy przykłady SPI jako Master i SPI jako Slave.
SPI jako MASTER
Przykład
#include <SPI.h>
void setup (void) {
Serial.begin(115200); //set baud rate to 115200 for usart
digitalWrite(SS, HIGH); // disable Slave Select
SPI.begin ();
SPI.setClockDivider(SPI_CLOCK_DIV8);//divide the clock by 8
}
void loop (void) {
char c;
digitalWrite(SS, LOW); // enable Slave Select
// send test string
for (const char * p = "Hello, world!\r" ; c = *p; p++) {
SPI.transfer (c);
Serial.print(c);
}
digitalWrite(SS, HIGH); // disable Slave Select
delay(2000);
}
SPI jako SLAVE
Przykład
#include <SPI.h>
char buff [50];
volatile byte indx;
volatile boolean process;
void setup (void) {
Serial.begin (115200);
pinMode(MISO, OUTPUT); // have to send on master in so it set as output
SPCR |= _BV(SPE); // turn on SPI in slave mode
indx = 0; // buffer empty
process = false;
SPI.attachInterrupt(); // turn on interrupt
}
ISR (SPI_STC_vect) // SPI interrupt routine {
byte c = SPDR; // read byte from SPI Data Register
if (indx < sizeof buff) {
buff [indx++] = c; // save data in the next index in the array buff
if (c == '\r') //check for the end of the word
process = true;
}
}
void loop (void) {
if (process) {
process = false; //reset the process
Serial.println (buff); //print the array on serial monitor
indx= 0; //reset button to zero
}
}