The SPI Interface (Serial Peripheral Interface) bus is a high speed, 3-wire, serial communications protocol (4 if you include SSn - see below). Its primiary purpose is to reduce on-PCB wire routing by replacing the traditional parallel bus with a serial interface. (You can just about manage an 8 bit bus routing it through a several layer PCB but when you get to 16, 32 bits and more it gets far more difficult).
The connections are:
 - denotes PIC nomenclature
Note: The last signal SS or slave select is separate from the protocol and is usually implemented as an enabling control pin from the microcontroller. It is included here for completeness.
The SPI PIC interface allows connection of peripherals using a high speed serial interface. SPI Flash Memory and SPI SRAM can easily be added to any system. Other types of device include:
Its only other real competition is the I2C bus which is why you often see these interfaces both available on processors and microcontrollers.
The SPI interface was designed in the 1970s by Motorola, who used it in their 68000 processor, and it was quickly adopted by many other manufacturers as a defacto standard.
It is intended for transmission of data from a master device to one or more slave devices over short distances and at high speeds (MHz).
It works by transferring data one bit at a time between two devices with the master device sending the clock signal (SCK). The clock controls the timing of the data transfer.
Data (MOSI [SDO] )is sent out of a shift register in the Master SPI device along with a clock signal (SCK) while at the same time another shift register receives data from the slave (MISO, [SDI]).
The Master is always in control and initiates data transfer using the clock signal. Slave devices are selected using a separate slave select signal that is software controlled i.e. those signals are separate from the SPI hardware module.
The SPI clock is not defined at all - meaning that different slave devices can assume different clock operation; One slave may require an idle clock that is high, while another may require an idle state of low. Others will react to the rising edge while others react to the falling edge!
The SPI interface protocl copes with this by letting you program these details to the SPI hardware module.
The following image shows the PIC interface for SPI (all SPI hardware modules in other microcontrollers will allow the same operation just using different registers).
It is up to you to set the correct clock for you device when it is activated by a slave select signal (or in the case of a single slave it is always selected so there will be no slave select signal).
The following diagram shows the interface to the SPI connections which also happens to be the programming connector (ICSP), on the Arduino board, that allows direct programming of the ATmega328p.
Photo Credit : kenming_wang (mod shows ICSP)
There are three ways of using the SPI interface
Here is the setup for a single SPI device connection:
With this scheme you control each slave device using
its chip select line (usually active low- red arrows show control
lines). When disabled the
Data output from the
slave goes into a high impedance state so it does not interfere with
currently selected slave and the slave's data input is ignored (check
The advantage of this scheme is that you can consider (control) each device separately when you compare it with the daisy chain method - allowing connection of SPI devices that require different clock schemes.
If you have SPI slaves that operate using different clocks (edges/idle states) you can re-programme the master SPI hardware module before enabling a specific CS so each slave has the correct signals sent to it.
If you use the Daisy chain method then you need to make sure all the chips use the same clock edge and idle clock state.
With this scheme all data sent by the master is shifted into all devices and all data sent from each device is shifted out to the next (shown by red dotted arrow). For this scheme to work you have to make sure that each slave uses the clock in the same way and you have to get the right number of bits, so there is more work to do in software.
Use several HC595 chips, daisy-chain linked, giving an easy increase in the number of outputs available without using many microcontroller pins.
The limits of operation are the speed of HC, the speed of the SPI output. Also design consideration e.g. If driving a set of LEDs that must be updated every 20ms.
The trade off between using a parallel interface and the SPI interface is speed e.g. if you read a parallel 12bit ADC at 200ksps then you could read the device at a 200kHz rate but if you want to get the same data rate using SPI then you need a serial speed of 200kHz x 12 = 2.4MHz. So the actual trade off is speed and the consequential noise introduced into the circuit.
The SPI interface defines a very popular protocol that works at high speed. The main problem is that slave devices are not bound by any particular clocking scheme so they may operate differently to each other and that can make controlling them difficult i.e. the clock idle and edge must be set correctly for each device.
Oct 16, 20 09:35 AM
How to use the MCP23017 to increase your I/O by 16 pins (or more) and use its interrupt system.
Oct 02, 20 01:12 AM
Arduino Battery Charger: A very useful project that lets you charge 'un-rechargeable' alkaline batteries!
Sep 21, 20 01:13 AM
Digispark ATtiny85: Essential information on setting up and using this tiny, but powerful, chip
Sep 06, 20 02:11 PM
How to make magnetometer tilt compensation work for a magnetometer such as a QMC5883L using an ADXl345 accelerometer.
Aug 13, 20 03:40 AM
HMC5883L - How make a digital compass, Find out the differences between the HMC5883L and the QMC5883L and whether they are compatible.
Jul 28, 20 02:10 PM
Secrets of Arduino absolute value abs() - Why it might fail, Why it may cause problems...and how to fix it.