RCK Ruđera Boškovića - mobilna / uslužna robotika

Druge sabirnice i periferija - SPI

Zadatak

Naučiti koristiti SPI sabirnicu.

Priprema

Za vježbu je potrebno:

Spajanje pločica

×
Spojite ESP32 pločice iz 2 robota prema slici.

Međusobno se spajaju pinovi:
  • 23 (MOSI),
  • 19 (MISO),
  • 18 (SCK),
  • 5 (SS).

Master

#include <SPI.h>

/** Custom test. The function will be called many times during the test, till You issue "x" menu command.
*/
void RobotLine::loop() {
	static SPIClass* vspi; 
	#define SPI_CLOCK 1000000 // 1 MHz

	static uint16_t msg = 1;

	if (setup()){
		vspi = new SPIClass(VSPI);
		vspi->begin();
		pinMode(vspi->pinSS(), OUTPUT); //VSPI SS
	}

	vspi->beginTransaction(SPISettings(SPI_CLOCK, MSBFIRST, SPI_MODE0));
	digitalWrite(vspi->pinSS(), LOW); //pull SS slow to prep other end for transfer
	vspi->transfer(msg++);
	digitalWrite(vspi->pinSS(), HIGH); //pull ss high to signify end of data transfer
	vspi->endTransaction();

	delayMs(100);
}
Jedna će pločica biti master, druga slave.

S lijeve strane je kod za master pločicu.

SPI_CLOCK će biti 1 MHz. Master određuje takt veze.

U prvom prolazu budimo SPI. Pokrećemo sabirnicu putem "begin" i postavljamo pin za izbor slave jedinice na digitalni izlaz ("pinMode").

Sad šaljemo jednu poruku.

Poruka je samo 1 bajt, broj 1.

Početak je "beginTransaction", završetak "endTransaction".

Biramo slave jedinicu tako da spustimo digitalnu liniju na nulu. Kad bi bilo više slave uređaja, izabrali bismo određeni spuštanjem samo njene linije. Koristimo "digitalWrite".

Šaljemo poruku putem "transfer".

Nakon toga podižemo digitalnu liniju.

Slave

#include <ESP32SPISlave.h>

/** Custom test. The function will be called many times during the test, till You issue "x" menu-command.
*/
void RobotMaze::loop() {
  static ESP32SPISlave slave;

  static constexpr uint32_t BUFFER_SIZE {32};
  static uint8_t txBuffer[BUFFER_SIZE];
  static uint8_t rxBuffer[BUFFER_SIZE];

  if (setup()){
    slave.setDataMode(SPI_MODE0);
    slave.begin();
  }

  // block until the transaction comes from master
    slave.wait(rxBuffer, txBuffer, BUFFER_SIZE);

    // if transaction has completed from master,
    // available() returns size of results of transaction,
    // and buffer is automatically updated
    while (slave.available()) {
        // show received data
         print("Received: %i\n\r", rxBuffer[0]);
         slave.pop();
    }
}
Slave dio čeka poruku koju šalje master.

"txBuffer" i "rxBuffer" su polja koja šalju i primaju podatke.

Trebaju 2 jer slave istovremeno šalje i prima podatke.

U ovom se primjeru koristi samo primanje.

Prilikom prvog prolaza kroz funkciju, postavljamo tip prijenosa putem "setDataMode".

Postoje 4 načina, ali nije bitno koji izaberemo, sve dok isti koriste i master i slave.

"begin" pokreće SPI slave.

Nakon toga dolazi dio koji se izvršava u svakom prolazu, počevši s "wait".

Riječ je o "polling" načinu rada, gdje program stane i čeka dolazak poruke.

Ovo je najneefikasniji način rada, ali za naš primjer je dovoljno dobar.

Nakon što stigne SPI poruka, "wait" prestane blokirati izvršavanje i program krene dalje.

Sve dok je "available", znači ima podataka, ispisujemo prvi bajt i izbacujemo ga ulaznog repa pomoću "pop".

Primjedbe