skip navigational linksPJRC
Shopping Cart Checkout Shipping Cost Download Website
Home MP3 Player 8051 Tools All Projects PJRC Store Site Map
You are here: Teensy Teensyduino Libraries SPI

PJRC Store
Teensy 3.1, $19.80
Teensy 2.0, $16.00
Teensy++ 2.0, $24.00
USB Cable, $4.00
Teensy
Main Page
Teensy 3.1
Getting Started
How-To Tips
Code Library
Projects
Teensyduino
Reference

SPI Library

The SPI library allows you SPI (Serial Peripheral Interface) devices.

Download: SPI is included with Arduino

Often SPI is used by other libraries (like Ethernet) which provide easy access to a specific SPI device.

A faster SPI library for Teensy 3.0 is available.

Hardware Requirements


SPI Library: DigitalPotControl Example

SPI has 4 signals: SS, SCK, MOSI, MISO. Some chips need only 3 or even 2 of these signals.

SignalFunctionTeensy
2.0
Teensy++
2.0
Teensy
3.0
SSSelect Device02010
SCKClock12113
MOSIData Output22211
MISOData Input32312

Arduino automatically defines "SS", "SCK", "MOSI", and "MISO" as the pin numbers for the selected board.

Basic Usage

SPI.begin()

Begin using SPI. The SCK, MOSI and MISO pins are initialized. You should manaully configure the SS pin.

digitalWrite(SSpin, level)

Most SPI devices define a transfer of multiple bytes. You need to write the SS pin before the transfer begins (most chips use LOW during the transfer) and write it again after the last byte, to end the transfer. See below for more SS pin details.

SPI.transfer(data)

Transmit a byte, and simultaneously receive a byte. SPI always transmits and receives at the same time, but often the received byte is ignored. When only reception is needed, 0 or 255 is transmitted to cause the reception.

Example Program

This example can be opened from the menu: File > Examples > SPI > DigitalPotControl. The code here is an abreviated version. See the example for comments describing the required hardware and other details.

#include <SPI.h>  // include the SPI library:

const int slaveSelectPin = 20;

void setup() {
  // set the slaveSelectPin as an output:
  pinMode (slaveSelectPin, OUTPUT);
  // initialize SPI:
  SPI.begin(); 
}

void loop() {
  // go through the six channels of the digital pot:
  for (int channel = 0; channel < 6; channel++) { 
    // change the resistance on this channel from min to max:
    for (int level = 0; level < 255; level++) {
      digitalPotWrite(channel, level);
      delay(10);
    }
    // wait a second at the top:
    delay(100);
    // change the resistance on this channel from max to min:
    for (int level = 0; level < 255; level++) {
      digitalPotWrite(channel, 255 - level);
      delay(10);
    }
  }
}

int digitalPotWrite(int address, int value) {
  // take the SS pin low to select the chip:
  digitalWrite(slaveSelectPin,LOW);
  //  send in the address and value via SPI:
  SPI.transfer(address);
  SPI.transfer(value);
  // take the SS pin high to de-select the chip:
  digitalWrite(slaveSelectPin,HIGH); 
}

Slave Select Signal

Any pin can be used for the SS (slave select) signal. The SPI library does not control the SS signals. You do so with digitalWrite().

However, the SS pin must either be configured as an output, or if it is an input, it must remain low during the SPI transfer. Unconfigured pins default to input, and a pin with no signal can easily "float" to random voltages due to electrical noise. Always configure the SS pin as an output, or make sure it remains low.

Most SPI devices are designed to work together with others, where SCK, MISO, and MOSI are shared. Each chip needs a separate SS signal. Only the selected chip will communicate. The others ignore SCK and MOSI, and avoid driving MISO when they are not selected.

Slave Mode (Not Supported)

The SPI library only supports SPI master mode, where it selects the chip to communicate and the master drives SCK and MISO, and receives on MISO.

SPI slave devices do the opposite. They way for a master to select them, and they receive the SCK and MOSI signals from the master and transmit on MISO. Virtually all chips controlled by SPI are slave devices.

The SPI port can work in slave mode, which may be useful if Teensy should appear as a SPI device to be controlled by another Teensy or other board. The SPI library does not support slave mode.

Is there an Arduino library which supports slave mode?

Configuration Options

The SPI library provides a few configuration functions.

Speed

Most commonly configured is the speed, with SPI.setClockDivider(divider). SPI_CLOCK_DIV2 is the fastest option.

Slower speeds are usually needed when 5 volt signals are converted to 3 volts using only resistors. Together with the capacitance associated with the wire and pins, resistors can slow the signals.

Very long wires may also require slower speeds. When using long wires (more than 25 cm or 1 foot), a 100 ohm resistor should be placed between the Teensy's pin and the long wire.

Bit Order

Most SPI chips transfer data with the MSB (most significant bit) first, which is the SPI library default setting. However, if LSB first is needed, SPI.setBitOrder(LSBFIRST) can be used.

Waveform (Clock Polarity / Phase)

SPI can operate with different clock polarity and phase options, called mode 0 to 3. Most SPI chips are designed to work with either mode 0 or mode 3. The SPI library defaults to mode 0. If a different mode is needed, SPI.setDataMode(mode) can be used.

Wikipedia's SPI Page has details on these options.

More Details

Please refer to the official SPI library documentation for more details.