Arduino - Interface périphérique série

Un bus SPI (Serial Peripheral Interface) est un système de communication série qui utilise jusqu'à quatre conducteurs, généralement trois. Un conducteur est utilisé pour la réception de données, un pour l'envoi de données, un pour la synchronisation et un autre pour sélectionner un appareil avec lequel communiquer. Il s'agit d'une connexion en duplex intégral, ce qui signifie que les données sont envoyées et reçues simultanément. La vitesse de transmission maximale est supérieure à celle du système de communication I2C.

Board SPI Pins

SPI utilise les quatre fils suivants -

  • SCK - Il s'agit de l'horloge série pilotée par le maître.

  • MOSI - Il s'agit de la sortie maître / entrée esclave pilotée par le maître.

  • MISO - Il s'agit de l'entrée maître / sortie esclave pilotée par le maître.

  • SS - C'est le fil de sélection d'esclave.

Les fonctions suivantes sont utilisées. Vous devez inclure le SPI.h.

  • SPI.begin() - Initialise le bus SPI en réglant SCK, MOSI et SS sur les sorties, en tirant SCK et MOSI bas et SS haut.

  • SPI.setClockDivider(divider)- Pour régler le diviseur d'horloge SPI par rapport à l'horloge système. Sur les cartes basées sur AVR, les diviseurs disponibles sont 2, 4, 8, 16, 32, 64 ou 128. Le réglage par défaut est SPI_CLOCK_DIV4, qui règle l'horloge SPI à un quart de la fréquence de l'horloge système (5 Mhz pour le cartes à 20 MHz).

  • Divider - Cela pourrait être (SPI_CLOCK_DIV2, SPI_CLOCK_DIV4, SPI_CLOCK_DIV8, SPI_CLOCK_DIV16, SPI_CLOCK_DIV32, SPI_CLOCK_DIV64, SPI_CLOCK_DIV128).

  • SPI.transfer(val) - Le transfert SPI est basé sur un envoi et une réception simultanés: les données reçues sont renvoyées dans receiveVal.

  • SPI.beginTransaction(SPISettings(speedMaximum, dataOrder, dataMode)) - speedMaximum est l'horloge, dataOrder (MSBFIRST ou LSBFIRST), dataMode (SPI_MODE0, SPI_MODE1, SPI_MODE2 ou SPI_MODE3).

Nous avons quatre modes de fonctionnement dans SPI comme suit -

  • Mode 0 (the default) - L'horloge est normalement basse (CPOL = 0) et les données sont échantillonnées lors de la transition de bas en haut (front montant) (CPHA = 0).

  • Mode 1 - L'horloge est normalement basse (CPOL = 0), et les données sont échantillonnées lors de la transition de haut en bas (bord arrière) (CPHA = 1).

  • Mode 2 - L'horloge est normalement haute (CPOL = 1) et les données sont échantillonnées lors de la transition de haut en bas (front montant) (CPHA = 0).

  • Mode 3 - L'horloge est normalement haute (CPOL = 1), et les données sont échantillonnées lors de la transition de bas en haut (bord arrière) (CPHA = 1).

  • SPI.attachInterrupt(handler) - Fonction à appeler lorsqu'un appareil esclave reçoit des données du maître.

Maintenant, nous allons connecter deux cartes Arduino UNO ensemble; l'un comme maître et l'autre comme esclave.

  • (SS): broche 10
  • (MOSI): broche 11
  • (MISO): broche 12
  • (SCK): broche 13

Le terrain est commun. Voici la représentation schématique de la connexion entre les deux cartes -

Voyons des exemples de SPI en tant que maître et SPI en tant qu'esclave.

SPI comme MASTER

Exemple

#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 comme ESCLAVE

Exemple

#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
   }
}