SPI


Serial Peripheral Interface (SPI) is a synchronous serial data protocol used by microcontrollers for communicating with one or more peripheral devices quickly over short distances. It can also be used for communication between two microcontrollers.

With an SPI connection there is always one master device (usually a microcontroller) which controls the peripheral devices. Typically there are three lines common to all the devices:
  • MISO (Master In Slave Out) — The Slave line for sending data to the master
  • MOSI (Master Out Slave In) — The Master line for sending data to the peripherals
  • SCK (Serial Clock) — The clock pulses which synchronize data transmission generated by the master
  • CS/SS (Slave Select or Chips Select) — the pin on each device that the master can use to enable and disable specific devices.
Z-Uno 2 board have the following SPI interfaces:
  • SPI0 — UART on SCK(0), MISO(1) and MOSI(2) pins
  • SPI(SPI1) — UART on SCK(0) and MISO(1), MOSI(2) pins
  • SPI2 — UART on SCK2(3), MISO2(4) and MOSI2(7) pins
For more infomation about pins of Z-Uno follow to this page When a device's Slave Select pin is low, it communicates with the master. When it's high, it ignores the master. This allows you to have multiple SPI devices sharing the same MISO, MOSI, and CLK lines.
To write code for a new SPI device you need to note a few things:
  • What is the maximum SPI speed your device can use? This is controlled by the first parameter in SPISettings. Z-Uno supports up to 8MHz (8000000). Z-Uno will automatically use the best speed that is equal to or less than the number you use with SPISettings.
  • Is data shifted in Most Significant Bit (MSB) or Least Significant Bit (LSB) first? This is controlled by second SPISettings parameter, either MSBFIRST or LSBFIRST. Most SPI chips use MSB first data order.
  • Is the data clock idle when high or low? Are samples on the rising or falling edge of clock pulses? These modes are controlled by the third parameter in SPISettings.
The SPI standard is loose and each device implements it a little differently. This means you have to pay special attention to the device's datasheet when writing your code.
Once you have your SPI parameters, use SPI.beginTransaction() to begin using the SPI port.
SPISettings spi_settings = SPISettings(8000000, MSBFIRST, SPI_MODE0);
SPI.beginTransaction(&spi_settings);
// ...
SPI.endTransaction();
The SPI settings are applied at the beginning of the transaction and endTransaction() doesn't change SPI settings. Unless you, or some library, calls beginTransaction a second time, the setting are maintained. You should attempt to minimize the time between before you call endTransaction(), for best compatibility if your program is used together with other libraries which use SPI. With most SPI devices, after SPI.beginTransaction(), you will write the slave select pin LOW, call transfer() any number of times to transfer data, then write the SS pin HIGH, and finally call endTransaction(). Note, every SPI object uses one DMA channel. It occupies the channel from begin() call to end() call. Custom pins can be used by calling begin()
The table below shows which pin can be used on which SPI port
Pin # SPI0 SCK/MISO/MOSI SPI1 SCK/MISO/MOSI SPI2 SCK/MISO/MOSI SS
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Note that SPI and UART use the same shared peripherals USARTs. Only one can work at the same time. Shared peripherals
SPI object Cortex USART
SPI0 USART0
SPI1 USART1
SPI2 USART2
		
#include "Spi.h"

void setup(){
	SPI.begin(1, 2, 3, 4);	// join SPI bus as a slave
						// We use pins sck=1, miso=2, mosi=3, slave_select = 4
}
void loop(){
	SPI.beginTransaction();//Starts a transaction
	SPI.transfer("Hello!! you?");	// Sends a string to the slave
	SPI.transfer(0xAF);				// Sends a byte o slave
	SPI.endTransaction();// Finishes the transaction
	delay(2000);
}