Pages Menu
Categories Menu

Posted by on Nov 10, 2013 in Atmel AVR, Microcontrollers | 59 comments

Serial Peripheral Interface – SPI Basics

Serial Peripheral Interface – SPI Basics

Hey all! It’s time to continue with our tutorials on serial communication. Till now, we have covered the following:

Apart from this, there are few other serial transfer protocols like SPI, I2C, etc. In this post, we will discuss about SPI and its bus transactions – no programming, just the concepts. Programming the SPI of (AVR) microcontrollers will be discussed in upcoming post.


Serial Peripheral Interface (SPI)

Serial Peripheral Interface, often shortened as SPI (pronounced as spy, or ess-pee-eye), is a synchronous serial data transfer protocol named by Motorola. Here two or more serial devices are connected to each other in full-duplex mode. The devices connected to each other are either Master or Slave. In a SPI link there could as many Masters and Slaves as required, but it’s very rare to find more than one Master in a SPI link.

The Master device is the one which initiates the connection and controls it. Once the connection is initiated, then the Master and one or more Slave(s) can transmit and/or receive data. As mentioned earlier, this is a full-duplex connection, which means that Master can send data to Slave(s) and the Slave(s) can also send the data to the Master at the same time.

SPI Bus Transaction

Now that we have a basic knowledge of what SPI is, let’s look into the operation of SPI Bus. The SPI operation is based upon shift registers. Every device, whether Master or Slave has an 8-bit shift register inside it. The size of the shift register could be more than 8-bit as well (like 10-bit, 12-bit, etc), but it should be the same for both Master and Slave, and the protocol should support it.

Hardware Setup

The Master and Slave are connected in such a way that the two shift registers form an inter-device circular buffer. The following diagram should explains the hardware setup. Please click on the images to enlarge it and view it in high resolution.

Hardware Setup of Master-Slave Device and Shift Registers

Hardware Setup of Master-Slave Device and Shift Registers (Click to Enlarge)

As you can see, there is an 8-bit shift register inside each of the Master and Slave devices. These shift registers operate in Serial-In/Serial-Out (SISO) fashion. The output of the Master’s shift register is connected to the input of the Slave’s shift register; and the output of the Slave’s shift register is connected to the input of Master’s shift register. This makes the connection operate like a circular/ring buffer. Don’t bother about the names MISO, MOSI and SCK now. We will discuss about them a little later in this post.

As mentioned earlier, SPI is a synchronous serial data transfer protocol, which means that there must be a clock to synchronize the data transfer. It has also been stated that the Master is responsible for initiating and controlling the connection. Thus, we use the clock source of the Master device to synchronize the data transfer. That’s why you see the clock source inside the Master, which controls the operation of both the shift registers.

Data Transfer Operation

Alright, now let’s see how SPI bus transfers data among Master and Slave. Let’s refer to the diagram shown in the above section. Let’s say that the data in the Master’s shift register is A7 through A0 (MSB through LSB) whereas the data in the Slave’s shift register is B7 through B0 (MSB through LSB). This is the initial state before any clock pulse arrives.

Now as soon as a clock pulse arrives, the shift registers come into operation and the data in the registers in shifted by one bit towards the right. This evicts bit A0 from Master and bit B0 from Slave. Since the Master and Slave are connected to form a ring/circular buffer, the evicted bit occupies the MSB position of the other device. Which means, bit A0 gets evicted from Master and occupies MSB position in Slave’s shift register; whereas bit B0 gets evicted from Slave and occupies MSB position in Master’s shift register. This can be seen in the following image. Bits are color coded for better viewing. Please click on the image to enlarge it.

Clock Pulse 1 - SPI Bus Transaction showing Master Slave Shift Registers

Clock Pulse 1 – SPI Bus Transaction showing Master Slave Shift Registers (Click to Enlarge)

Now once again, when the clock generates another pulse, the data in the registers are shifted by another bit towards right, which evicts bits A1 and B1 from Master and Slave respectively. The evicted bits A1 and B1 occupy the MSB position of Slave’s and Master’s shift registers respectively. This can be seen in the following image. Please click on the image to enlarge it.

Clock Pulse 2 - SPI Bus Transaction showing Master Slave Shift Registers

Clock Pulse 2 – SPI Bus Transaction showing Master Slave Shift Registers (Click to Enlarge)

This continues for six more clock pulses. The following images depict the data transfer operation. Please click on the images to enlarge them for better viewing.

Clock Pulse 3 - SPI Bus Transaction showing Master Slave Shift Registers

Clock Pulse 3 – SPI Bus Transaction showing Master Slave Shift Registers (Click to Enlarge)

Clock Pulse 4 - SPI Bus Transaction showing Master Slave Shift Registers

Clock Pulse 4 – SPI Bus Transaction showing Master Slave Shift Registers (Click to Enlarge)

Clock Pulse 5 - SPI Bus Transaction showing Master Slave Shift Registers

Clock Pulse 5 – SPI Bus Transaction showing Master Slave Shift Registers (Click to Enlarge)

Clock Pulse 6 - SPI Bus Transaction showing Master Slave Shift Registers

Clock Pulse 6 – SPI Bus Transaction showing Master Slave Shift Registers (Click to Enlarge)

Clock Pulse 7 - SPI Bus Transaction showing Master Slave Shift Registers

Clock Pulse 7 – SPI Bus Transaction showing Master Slave Shift Registers (Click to Enlarge)

And finally,

Clock Pulse 8 - SPI Bus Transaction showing Master Slave Shift Registers

Clock Pulse 8 – SPI Bus Transaction showing Master Slave Shift Registers (Click to Enlarge)

And here’s an animation. Thanks to Audio Sketches for creating it!


Short Summary

To sum up,

  • Both, Master and Slave place the data (byte) they wish to transfer in their respective shift registers before the communication starts.
  • Master generates 8 clock pulses. After each clock pulse, one bit of information is transfer from Master to Slave and vice-versa.
  • After 8 clock pulses, Master would have received Slave’s data, whereas Slave would have Master’s data. And that’s why this is a full-duplex communication.

SPI Bus Interface

Now that we are conceptually clear how the data transfer takes place, let’s look into the SBI bus description and the interface between Master and Slave.

The Master and Slave are connected by means of four wires. Each of these wires carries a particular signal defined by the SPI bus protocol. These four signals/wires are–

  1. MOSI – Master Out Slave In: This is the wire/signal which goes from the output of Master’s shift register to the input of the Slave’s shift register.
  2. MISO – Master In Slave Out: This is the wire/signal which goes from the output of Slave’s shift register to the input of the Master’s shift register.
  3. SCK/SCLK – Serial Clock: This is the output of the clock generator for Master and clock input for Slave.
  4. SS’ – Slave Select: This is discussed in the next section of this post.

The MOSI, SCK and SS’ signals are directed from Master to Slave whereas the MISO signal is directed from Slave to Master. The following diagram represents this interface having single Master and single Slave.

SPI Bus - Single Master Single Slave

SPI Bus – Single Master Single Slave (Click to Enlarge)

Thus, it should be noted again that during each SPI clock cycle, a full duplex transmission occurs as follows–

  • Master sends a bit to the MOSI line; Slave reads it from the same line.
  • Slave sends a bit to the MISO line; Master reads it from the same line.

Multiple Slaves – Slave Select (SS’) Signal

As mentioned earlier, SPI can be used to connect one Master to multiple Slaves as well. Having multiple Masters is also possible, but it does nothing but increase the complexity due to clock synchronization issues, and is very very rare. Having multiple Slaves is where the Slave Select (SS’) signal comes into effect.

SS’ (which means SS complemented) signal is in active low configuration i.e. to select a particular Slave, we need to provide a LOW signal level to SS’ of the Slave. The SPI bus interface is pretty simple for this one, and is shown in the diagram shown below.

SPI Bus - Single Master Multiple Slaves

SPI Bus – Single Master Multiple Slaves (Click to Enlarge)

All the Slaves share the same MOSI, MISO and SCK signals. The SS’ signal is responsible for choosing a particular Slave. The Slave gets enabled only when its input SS’ signal goes LOW.

In the above case, each of the Slaves is independent since they are separately selected via independent SS’ signals from the Master. However, there is another way to link the Slaves together – by using Daisy chain configuration. In this configuration, all the Slaves are selected at a time, and the output of one Slave goes to the input of another Slave, and so on. However we will not be discussing this here (and in upcoming posts as well) since most of the applications don’t require this type of configuration.

Clock Polarity and Phase

Keeping synchronization in mind, Master’s role doesn’t end with simply generating clock pulses at a particular frequency (usually within the range of 10 kHz to 100 MHz). In fact, Master and Slave should agree on a particular synchronization protocol as well, or else everything will go wrong and data will get lost. This is where the concept of clock polarity (CPOL) and clock phase (CPHA) comes in.

  • CPOL – Clock Polarity: This determines the base value of the clock i.e. the value of the clock when SPI bus is idle.
    • When CPOL = 0, base value of clock is zero i.e. SCK is LOW when idle.
    • When CPOL = 1, base value of clock is one i.e. SCK is HIGH when idle.
  • CPHA – Clock Phase: This determines the clock transition at which data will be sampled/captured.
    • When CPHA = 0, data is sampled at clock’s rising/leading edge.
    • When CPHA = 1, data is sampled at clock’s falling/trailing edge.

This results in four SPI modes, shown in the table below taken from the ATmega32 datasheet page 139. We will discuss more about these modes and how to choose them in our next post where we will learn how to program the SPI of the AVR.

CPOL and CPHA Functionality

CPOL and CPHA Functionality

We can also look into the timing diagrams provided in the same page of the datasheet. By now I guess you should be able to decode the timing diagrams yourself. Don’t worry about the DORD setting at the bottom, we will discuss about it in the next post. Just focus on what effect CPOL and CPHA has in these figures.

SPI Transfer Format with CPHA = 0

SPI Transfer Format with CPHA = 0 (Click to Enlarge)

SPI Transfer Format with CPHA = 1

SPI Transfer Format with CPHA = 1 (Click to Enlarge)

AVR In-System Programming

The In-System Programming (ISP) exploits the technique of SPI to transfer the hex code from the PC to the target AVR microcontroller. We won’t go into the details of how it happens. Since we are discussing about SPI, I thought to bring up this small point as well. The following figure taken from AVR Application Note 910 page 2 shows the simplified hardware connections.

Connections between ISP and AVR MCU

Connections between ISP and AVR MCU (Click to Enlarge)

This means that if you have connected some SPI device to your AVR microcontroller, and at the same time you are trying to program your microcontroller, there could be some issues (like driver contention). We will discuss about this issue and other hardware considerations in our next post.

Interesting Reads

You might be interested in reading the following documents–


Let’s look at what we have learnt in this post.

  • SPI is a full-duplex synchronous serial data transfer protocol.
  • Data transfer takes place in between Master and Slave devices.
  • Each Master/Slave device has an internal 8 bit shift register, which is connected to other devices so as to form a circular/ring buffer.
  • At each clock pulse, data gets right shifted in the circular/ring buffer.
  • After 8 clock pulses, data is completely exchanged in between devices.
  • SPI bus consists of four wires/signals – MOSI, MISO, SCK and SS’.
  • When we connect more than one Slave devices, then we choose them using the SS’ signal.
  • CPOL and CPHA must be set so that Master and Slave devices sync properly.
  • AVR ISP uses SPI to program the microcontroller.

So this was all about the basics of SPI. If you want to know about the pros and cons of SPI, I would suggest you to read this Wikipedia section. In the next post, we will learn how to implement SPI in an AVR microcontroller. So subscribe to stay updated! And don’t forget to write your views about this post below.

Cheers! And it’s about to be Thanksgiving time in two weeks, so Happy “early” Thanksgiving! :)

Next Post: SPI of AVR

Don’t forget to check out the next post where we show how you can implement SPI using AVR microcontrollers.


Written By–

Mayank Prasad (aka Max)
Arizona State University

Last updated on February 9, 2016.


  1. g88888

  2. I want to setting menu so that i can set the temperature . How is it possible?

    • I don’t know what you’re talking about. Please elaborate. Thanks.

  3. It’s really helpful, thank you!

  4. Gr8 job for beginner.. upload something else about SPI i like the way of your teching

    • Thanks Deepak! Have you checked out this tutorial? Anything else you expect?

  5. A great article indeed, especially for beginners. Max if you could help me with the timing diagrams, I would be grateful. I haven’t picked that up yet.

    • Hello Adnan,
      The thing to notice in the timing diagrams is the CPOL edge at which data is sampled. Look closely. :)

  6. Hi, i want to interface two rfid reader to my single atmega16 dev board ,i thought i could use RXD and TXD pins of USART in asynchronous mode and complete my task . but atmega16 has only one pair of TXD and RXD pins dedicated to usart protocol .
    can i use SPI protocol simultaneously for another rfid reader to communicate with the same board ???
    ( i will be only reading data from two rfid , not writing to iT).it similar to like having two masters(rfid readers) and one slave( my atmega16)……….

    • No, you can’t use SPI since RFID follows protocol similar to USART. What you can do is
      (1) Either implement the second USART in software,
      (2) Or configure the Universal Serial Interface (USI) to operate as USART. This should be easier to implement however.

      • since my second rfid has RXD & TXD pins , which is similar to the pins of serial port of PC(Which is having 4 pins(txd,rxd,vcc and ground)) Can i use ISP(in serial programmer),having mosi,miso pins(at the output side) in between them ,to communicate with the same atmega board for spi protocol . Does this work ??

        • That’s what I said earlier, you can’t. Both the protocols are different. RFID follows USART whereas you are talking about SPI. USART and SPI are completely different standards and cannot be used together.

          • sir i have a doubt regarding rfid .every tag or rfid card has a unique code and it is printed on it .when i interface a rfid reader with a microcontroller ,what kind of data do i get from the reader ? Is it the same(printed on tag) id number do i get ?or in different format . if so ,how do i convert to get the real id number ?
            i tried ,i got 12 digits of data with two decimal numbers and all remaining digits as cccccccccc.
            my output was like this c15ccccccccc

          • I think you should get the 12-byte unique ID. What is it that is printed on your RFID card? I think you’re not reading it the correct way. Try out something like this:

          • i did the same way .here is my code…..i dont know whats wrong!!

          • Please share your code via Thanks.

      • is ther any differenc btwn universal serial interface (USI)and serial pheripheral interface(SPI)? can i configure my atmega16 to operate in USI ,eventhough if im already using uart protocol?

        • You can configure USI to operate as any of the other serial protocols. This is what it is meant for.

    • Why do you have 300 ms delay inside getcard_id()?

      • Sorry i didn’t mentioned it. i just wanted to be sure that data is read byte by byte properly .for this a have put a led in my bread board(40th pin of atmega16 is defined for ,input to led).i know the id has 12 bytes and i made a for loop(inside getcard_id() ) for it .inside that i have a logic for blinking led . so that as soon as a byte is read ,led blinks . Thats it ,its for my conformation.

        • I think the delay is large and it skips some characters. Remove all the delay inside of the loop and try again. It should work.

          • Wow!! it works .i got something like this
            c15001C1F120 & c00003737CBC for my first and second rfid cards respectively. i knew that first digit of id is always ‘2’ and i also put a condition that if(card[0]==2) display remaining 12 bytes.but why iam getting the ‘c’ like character in 1st digit on lcd in both the cards ??


            a)apart from 1st digit problem ,am i gettig the right id ?
            i observed some of the characters like ‘F’ in first card and ‘CBC’ in secod card . is it correct?

          • Aren’t you supposed to know the ID of the card you’re using? Isn’t it printed on the card itself? Whatever you see should be the entire card ID, including all the alphabets and numbers that you can see.

          • Sir im totally confused please help me out.
            on my rfid card i have printing like this
            a)on rfid card:”0001842962 028,07954″
            b)on rfid key chain: “0003618763”
            in each case ,it is nowhere matching the data read on lcd like this
            a)”215001C1F120 ”
            b)”200003737CBC ”

          • Thank you sooooooooooooooo much !! for your each and every valuable information .

            and would you suggest me a good website like maxEmbedded, where i can learn 8086 microprocessors .

          • Not much idea about the 8086. Btw, the world has moved ahead.. why do you want to go back in history? Pick up some latest ARM processor and learn to program that. If you want to learn about the x86 assembly, go for the new Intel’s Galileo which has the new x86 Quark processor.

  7. Hi Max,

    I am implemting SPI on BBB. I have a question regarding the threshhold on the Master clock speed, given that there are nSlaves with max frequecies x1, x2, x3 …. xN.

    At what frequency should the Master fetch data to send it to slaves ?

    I don’t know if this a valid question or not. My guess is x1+x2+x3+…xN.

    Your comments/suggestions would be helpful.

    • Hello Amit,
      Choose a frequency which can be read by all the devices.

  8. I try to implement same code in master and slave for spi communication. Is it possible to do so? In detail, master will have code for both master_init and slave_init. The exact replica will be in slave controller. Which ever turns on first, it needs to configured as master and the other one as slave. This is my requirement. Innovative ideas, suggestions, h/w suggestions are requested on this concept

    • The solution that you proposed is flawed. You will of course need to use the same code for both Master and Slave, but the code will need to have a lot of extra stuff in it to make it behave that way. The question is, why the heck do you need one such?

  9. Hi

    I have difficulty in understanding who is the master and who can be the slave? What if I have only one microcontroller (ATMEGA 16), and the LCD. Is it that the ATMEGA 16 is the master and the LCD is the slave?

    • Master is the one that controls the clock and initiates the connection.

  10. Good Job n Thankx a lot.

  11. Thanks! This is so helpful to me (:

    • Thanks Lopex!

      Keep reading, keep sharing :D

  12. hi. i have an doubt regarding my current project.. i want to transfer data A1A2A3A4.. from internal memory of ATxmega128A1 via SPI to two seperate DAC converters such that DAC1 should have A1A3… n DAC2 with A2A4… how can i write a code

  13. What is the maximum number of slave which we can connect in SPI?

  14. Ok,For every clock pulse the master will shift out a bit and slave will shift out a bit to master,then what data slave is shifting out to master when master is shifting some address (eg to access data from ADC we write some address to it…).should we discard the slave data for first time as it seems it shifts out some grbage value.i want to know in depth of this shifting…can u help me.

  15. Hello sir

    can you explain me how to configure SPI protocol if i am interfacing Microcontroller with peripherals supporting SPI?


  1. The SPI of the AVR | maxEmbedded - […] Continuing with the series of tutorials on Serial Communication, here is another one, and much awaited, the Serial Peripheral…
  2. Inter-Integrated Circuit – I2C Basics | maxEmbedded - […] time for I2C! Currently, related to Serial Communication, maxEmbedded features RS232 and SPI communication. It’s time to move beyond! In…
  3. Making GIFs with ImageMagick’s command line “convert” | Audio Sketches - […] of .png images: [ SPI basics […]
  4. Dasar-Dasar Serial Peripheral Interface (SPI) - […]                     2., […]

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: