SPI

Getting Started With SPI

Serial Peripheral Interface (SPI) is a synchronous serial communication bus that we commonly use to transfer data between microcontrollers and other secondary segments like sensors, shift registers, and SD cards. It follows a master-slave type of interface, i.e. just one master (microcontroller) will be present, whereas slaves (peripheral segments) can be more than one.

It offers you high-speed serial communication between the processor as well as the peripherals of the board using a select line along with separate clock and data lines. The master generates the System Clock and Slave select signals. In a system where multiple slaves are present, there will be multiple select signals. 

The serial peripheral interface is a popular interface between MCU as well as peripheral ICs including sensors, ADCs, DACs, shift registers, SRAM, and others. This article offers a complete overview of the SPI interface before delving into SPI programming using MicroPython.

Master-Slave Interface

SPI

SPI is a full-duplex, synchronous master-slave interface. Data from the master or slave is aligned with the rising or dropping clock edge. Both the master and the slave will send data at the same time. The SPI interface can be either three or four wires.

One significant advantage of it is that data can be transmitted without interruption. In a continuous stream, any number of bits may be sent or received. Data is sent in packets with I2C and UART, each of which is limited to a certain number of bits.

SPI-enabled devices are in a master-slave relationship. The master (typically microcontroller) is the controlling unit, while the slave (typically sensor, display, or memory chip) receives instructions from the master. The most basic SPI configuration is a single master, single slave structure, but one master can control multiple slaves.

How SPI Works?

The communication takes place in two ways:-

  • The first method is to use a Chip Select(CS/SS) line to select each device. Each device necessitates its own Chip Select line. This is the most common way for MCU’s to use SPI at the moment.
  • The second method is via daisy chaining, in which each device is linked to the other through its data out to the data in line with the next device.

The number of SPI devices that can be connected is not limited. However, there are practical limitations due to the number of hardware select lines accessible on the main device when using the chip select method or the difficulty of transferring data between devices when using the daisy-chaining method. Therefore, the SPI interface does not require addressing operations in point-to-point communication and is full-duplex, making it simple and effective.

Basic Master-Slave Configuration in SPI

The Serial Peripheral Interface allows bits of data to be moved out of a master device and into a slave, as well as bits to be shifted back into the master. Since SPI is not standardized, it is likely that the Most Significant Bit (MSb) or the Least Significant Bit (LSb) is transferred first. Check your device’s datasheet and configure your data-handling routines accordingly.

In fact, there are multiple signals present in an SPI. These are the following:

  • SCLK: Serial Clock (Controlled by the main device)
  • MOSI: Master Output Slave In (To transfer data output from the main device)
  • MISO: Master In Slave Out (To transfer data output from slave)
  • SS: Slave Select (For device selection, controlled by the main device)
SPI

The SPI bus is a four-wire synchronous serial communication interface that is commonly used to connect an MCU to peripheral devices. MISO (Master Input Slave Output), MOSI (Master Output Slave Input), SCK (Serial Clock), and SS are the four wires (Slave Select or Chip Select). The Data Register is the primary control unit of an SPI subsystem. One 8-bit data register is in the master and one in the slave. They form a 16-bit register when connected by MISO and MOSI pins.

Understanding SPI Clock (SCK)

SPI

The clock signal synchronizes the master’s data bit output with the slave’s bit sampling. Since each clock cycle transfers one bit of data, the speed of data transmission is calculated by the frequency of the clock signal. Since the master configures and produces the clock signal, SPI communication is always initiated by the master.

Synchronous communication refers to any communication protocol in which devices share a clock signal. It is basically a protocol for synchronous communication. There are also asynchronous approaches that do not require the use of a clock signal. In UART communication, for example, both sides are set to a pre-configured baud rate, which regulates the speed and timing of data transmission.

The clock signal in SPI can be adjusted using the

  • clock polarity and,
  • clock phase properties.

Therefore, these two properties interact to determine when the bits are output and when they are sampled. The master can set the clock polarity to allow bits to be output and sampled on either the rising or falling edge of the clock cycle. The clock phase can be configured such that output and sampling occur on the first or second edge of the clock cycle, regardless of whether it is rising or dropping.

Clock Polarity and Phase

Clock transitions control data shifting and sampling. It has four modes (0, 1, 2, 3), which correspond to the four clocking configurations. When the slave-select line is pushed to logic low, a transaction starts (slave select is typically an active-low signal). The exact relationship between the slave-select, data, and clock lines is basically determined by the clock polarity (CPOL) and clock phase (CPHA) configurations.

With non-inverted clock polarity (i.e., when slave pick transitions to logic low, the clock is at logic low):-

  • Mode 0: The clock phase is adjusted such that data is sampled on the rising edge of the clock pulse and moved out on the dropping edge. In the diagram above, this corresponds to the first blue clock trace. It is important to note that data must be accessible before the first rising edge of the clock.
  • Mode 1: The clock phase is adjusted such that data is sampled on the clock pulse’s dropping edge and moved out on the clock pulse’s rising edge. In the diagram above, this corresponds to the second blue clock trace.

When the clock polarity is inverted (for example, the clock is at logic high when the slave pick transitions to logic low):-

  • Mode 2: The clock phase is set such that data is sampled on the dropping edge of the clock pulse and moved out on the rising edge. In the diagram above, this corresponds to the first orange clock trace. It should be noted that data must be available prior to the first dropping edge of the clock.
  • Mode 3: The clock phase is set such that data is sampled on the rising edge of the clock pulse and moved out on the dropping edge. In the diagram above, this corresponds to the second orange clock trace.

Understanding Slave Select/Chip Select

The master can select which slave to communicate, by setting the slave’s CS/SS line to a low voltage level. The slave select line is held at a high voltage level while the device is idle and not transmitting. Multiple CS/SS pins on the master may be open, allowing multiple slaves to be wired in parallel. If only one CS/SS pin is present, several slaves can be daisy-chained to the master.

Slave Select is also interchangeably called as Chip select

How to Connect Multiple SPI Slaves

SPI can be configured to work with a single master as well as a single slave, or with multiple slaves operated by a single master. There are basically two methods for linking multiple slaves to the master. If the master has more than one slave select pin, the slaves can be wired in parallel as follows:-

If there is only one slave select pin available, the slaves can be daisy-chained as following:-

Understanding MOSI and MISO

MOSI: Master Output and Slave Input is meant to send Data out from Microcontroller to the Peripheral IC/Sensor/Expansion Board. Through the MOSI line, the master sends data to the slave bit by bit in serial fashion. At the MOSI pin, the slave receives data sent by the master. Data is usually sent from the master to the slave with the Most Significant Bit(MSB) first.

MISO: Master Input and Slave Output is meant for Salve Devices to Send Data to Microcontroller. Salves devices are the Peripheral IC/Sensors/Expansion Boards. Through the MISO line, the slave sends data in a bit by bit fashion. At MISO pin MPU receives the data and uses it for further processing. The slave’s data is usually sent back to the master with the least significant bit first.

What is the Maximum Clock Rate of SPI?

SPI

The maximum SPI clock frequency for most devices is (one half of the system clock, but it cannot exceed 12.5 MHz. Thus, as long as the system clock frequency is 25 MHz or higher, the SPI clock will run at up to 12.5 MHz, and at the system, clock speeds less than 25 MHz, the maximum SPI clock rate is SYSCLK/2. The clock rate depends on the microcontrollers and the peripheral devices like SD-card may use max clk rate while DHT sensor will need a minimum clock rate. As configured as an SPI master unit, the maximum C8051 SPI clock frequency that can be realized is determined by the system clock frequency (SYSCLK).

When the SPI is configured in slave mode (i.e., the SCK is operated by the master), the maximum data transmission rate for most systems is 1/10 of the slave system clock frequency, given that the master drives the SPI clock, NSS, and data lines synchronously. If these signals are asynchronous with respect to the slave device, the data transfer rate must be less than 1/10 of the slave device’s system clock frequency.

SPI Is A Full Duplex

SPI is a full-duplex interface, which means that both the master and slave will send data at the same time through the MOSI and MISO lines. Therefore, data is transferred between the Master and Slave units. Each Master/Slave device contains an internal 8-bit shift register that is linked to other devices to form a circular/ring buffer. During the transmission, data is both transmitted (shifted serially onto the MOSI/SDO bus) and received (data on the bus (MISO/SDI) is sampled or read in). The serial clock edge synchronizes data shifting and sampling. The SPI interface allows the user to choose whether to sample and/or transfer data on the rising or dropping edge of the clock. To calculate the amount of data bits transmitted through the SPI interface, please refer to the device datasheet.

SPI

SPI (serial peripheral interface) busses are popular among designers due to a variety of reasons. The bus can transmit data at up to 60 Mbps over short distances, such as between chips on a board. The bus is conceptually simple, with just a clock, two data lines, and also a chip select signal. Since it displays the data on one phase of the clock and read back on the opposite phase, there is a large margin for delays and speed mismatches.

What is SoftSPI and HardSPI?

Hard SPI uses mutexes and is slow as compared to Soft SPI. Therefore, hard SPI can be used on SPI pins only. While soft SPI can be used on any GPIO pin. It basically uses the bit-bagging method and is very fast as compared to hard SPI. However, if you use a large date i.e 50 bytes transfer in one write/read operation then hard SPI is faster but the same cannot be done in soft SPI. Hence soft SPI is good when you are writing a 1-byte operation in a read/write operation but a hard SPI is fast when sending 50-100 bytes in a single read and write operation.

Software SPI Bus

Software SPI (bit-banging) operates on all pins and is controlled via the machine.SoftSPI class:

from machine import Pin, SoftSPI

# construct a SoftSPI bus on the given pins
# polarity is the idle state of SCK
# phase=0 means sample on the first edge of SCK, phase=1 means the second
spi = SoftSPI(baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))

spi.init(baudrate=200000) # set the baudrate

spi.read(10)            # read 10 bytes on MISO
spi.read(10, 0xff)      # read 10 bytes while outputting 0xff on MOSI

buf = bytearray(50)     # create a buffer
spi.readinto(buf)       # read into the given buffer (reads 50 bytes in this case)
spi.readinto(buf, 0xff) # read into the given buffer and output 0xff on MOSI

spi.write(b'12345')     # write 5 bytes on MOSI

buf = bytearray(4)      # create a buffer
spi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the buffer
spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf

Hardware SPI Bus

Two hardware SPI channels enable faster transmission rates (up to 80Mhz). These can be used on any IO pin that supports the required direction and is otherwise unused (see Pins and GPIO), but if they are not configured to their default pins, they must move through an extra layer of GPIO multiplexing, which can have an effect on their stability at high speeds. When used on pins other than the default ones mentioned below, hardware SPI channels are limited to 40MHz.

HSPI (id=1)VSPI (id=2)
sck1418
mosi1323
miso1219

Hardware SPI is accessed through the machine.SPI class and also has the same methods as software SPI that we discussed above:

from machine import Pin, SPI

hspi = SPI(1, 10000000)
hspi = SPI(1, 10000000, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
vspi = SPI(2, baudrate=80000000, polarity=0, phase=0, bits=8, firstbit=0, sck=Pin(18), mosi=Pin(23), miso=Pin(19))

Implementation of SPI

At a physical level, the bus consists of 3 lines SCK, MOSI, MISO. So, we require a separate 4th signal and SS to select a certain segment on the bus for communication. Management of SS can take place in user code. In an SPI connection, both the slave and the master can transfer data simultaneously with the help of MOIS and MISO lines, making it a full-duplex interface. The data transmission takes place by serially shifting it out onto the MOSI/SDO bus and data received on the MOSI/SDO is sampled. This process of shifting and sampling data can be controlled by a serial clock edge. 

The SPI bus is capable of transferring data up to a speed of 60 Mbps within the components of the board (intra-board). Also, the SPI interface allows its users to choose the rising and falling edge of the clock to sample and shift the data.

The software and hardware implementation of SPI occur by the use of machine.SPI and machine.SoftSPI

  • Hardware SPI Implementation uses the basic hardware support of the system to perform the read/write functions. This implementation is generally rapid and efficient but may have some restrictions where generally the pins are used. 
  • Software SPI Implementation is done by bit-banging and can be used on any pins. The classes use the same method available but the only difference is in the way of construction.

How SPI is Different from UART Interface?

Although both UART and SPI support full-duplex communication, both use “serial” communication in some manner, and are only useful for short-distance use cases, there aren’t many other similarities. So, what are the differences between UART and SPI? The answer is that there are plenty, and we will go over a few of them here.

Protocol – SPI vs UART

SPI

SPI

The SPI protocol is identical to the I2C protocol. This bus employs a total of four lines, and its components can be configured in one of two modes. The topology is basically point-to-point where a single controller interface is used to activate a single downstream device. The number of chip-select outputs given by the driver determines the number of devices that can be triggered (standard mode). The second mode employs daisy-chaining, in which a single system device-select output activates each device in the daisy chain in turn.

In contrast to I2C, the different signaling parameters in SPI are fully configurable. Unless you have a very quick interface, you should guess the signal level over the interconnect as DC so you would be below the critical length for transmission line conduct. The driver’s low impedance output should then be terminated with a series resistor to ensure optimal power transfer. The RC discharging process, as seen above with the trace capacitance, will monitor the output current and rise/fall times from your interface.

UART

The universal asynchronous receiver transmitter (UART) is analogous to the I2C.

  • The maximum data rate for these interfaces is 5 Mbps.
  • UART devices are also simple to use and no clock is transmitted between them; it is asynchronous.

It should be noted that the internal (system) clock of each UART device must be set to a multiple of the baud rate (i.e., each bit is sampled N times). For communication between a single controller device and a single downstream device, only two wires are used.

It’s worth noting that the data format, signal levels, and baud rate of a UART device can all be configured using an external driver circuit. Unfortunately, there are few hard and fast guidelines for routing and layout of UART devices as a result of this. When looking at the change to transmission line behaviour, use the standard high-speed design guidelines to determine when termination is needed.

SPI

A series termination is a popular method for reducing overshoot. It should be noted that UART will idle at high or low levels, and pull-up resistors may be necessary to set the required idle level; review the component specifications before adding pull-up resistors.

Understanding the variations in the different technology and protocols used by embedded systems is critical if you deal with them. UART and SPI are important aspects of embedded system design and development, and learning how they vary can help you to understand how the systems that use the function. In this section, we will define UART and SPI, compare them, discuss some popular applications that use UART and SPI, and provide you with details to help you get started debugging and programming embedded systems that use UART or SPI.

Hardware vs Protocol

One of the most significant distinctions is that UART is a type of hardware, while SPI is a protocol. This is easy to forget when dealing with the complexities of bringing things to work in an embedded system. However, UART is a physical piece of hardware (a microchip), while SPI is a communication protocol or specification.

Number of Pins Used

UARTs use only two pins, while SPI devices require at least four. This suggests that if pins/traces are scarce, SPI can not be an appealing option when designing a system.

Number of Connected Devices

UARTs and SPI devices endorse a different set of devices as a corollary to the number of pins. Since UART only uses Tx and Rx for outbound communication, it is essentially restricted to one-to-one communication. SPI, on the other hand, may use its master/slave model to allow an excessive number of communications.

Speed of Communication

SPI is considerably faster than UART. An SPI solution can be three times faster than a UART solution in some situations.

Pricing

The cost of a given solution is a major factor of choice in any engineering endeavor. In general, SPI is less expensive than UART.

Size

In general, SPI devices take up less space than UART chips. This suggests that SPI could be best suited to use cases where board space is limited.

Asynchronous vs Synchronous

Another significant distinction when comparing UART vs SPI is that UART communication is asynchronous, while SPI communication is synchronous.

TechnologyTransfer TypeNumber of Wires/PinsData Rate  @DistanceCostScalabilityUse Cases
UARTAsynchronous220 kbps @ 15mModerately expensivePoor (point-to-point)Diagnostic displays
SPISynchronous4+250 Mbps @ 0.1mRelatively inexpensiveModerateHigh speed chip-to-chip links

How to Write Data on SPI?

As seen in the image, most SPI flash memories have a write status register command that writes one or two bytes of data. The SPI host first activates the slave select line for the current device before writing to the status register. The master then outputs the corresponding instruction, followed by two data bytes defining the intended status register contents. Since the exchange does not need any data to be returned, the slave device maintains a high impedance condition on the MISO line while the master masks any incoming data. To finish the transaction, slave select is de-asserted.

SPI

This transaction can be completed using the Corelis SPI Exerciser command language with the following code, where Data Byte 2 is “55” and Data Byte 1 is “AA.” We’re using the abbreviated form of commands for brevity; the command script language supports both full commands like “write, read” and abbreviated versions like “wt, rd.” For eg, the following code for a write transaction activates slave select, then executes a write operation before deactivating slave select:

sson		// Activate slave select
wt 01 55 AA	// Write instruction 01h and data bytes 55h, AAh
ssoff		// Deactivate slave select

How to Read Data on SPI?

A status register read transaction is equivalent to a write transaction, but it now makes use of data returned from the slave, as shown in the image. The slave starts transmitting data on the MISO line at a rate of one byte per eight clock cycles after receiving the read status register instruction. The bitstream is received by the host, and the transaction is completed by de-asserting SS#.

SPI

This sequence is actually a single-byte write followed by a two-byte read; it can be thought of as a three-byte combined write/read command or as a single-byte write and two-byte read. Using the Corelis SPI Exerciser debugger command sequence, we may build this transaction:

sson		// Activate slave select
   wt 05	// Write instruction 05h
   rd 2		// Read two data bytes

ssoff		// Deactivate slave select

The read command’s data values will be reflected in the transaction log. The transaction log shows the data transferred between the BusPro-S host and slave when read, write, or combined write/read commands are issued.

How Many Pins do SPI Need to Work?

Motorola developed SPI (Serial Peripheral Interface), a useful networking style.

  • It has four communication pins, as well as a power and ground pin.
  • SPI can be used in both the 6 pins and 12 pin Pmod standards.
  • In SPI, a “master” device (the host board) and a “slave” device (the Pmod) communicate with one another.

Although it’s one thing to understand how SPI works and that it’s full duplex, as well as the various SPI modes available, all of that information is rendered worthless if you don’t know how or when to mount your SPI compatible module to your host board. We’ll concentrate on determining where we need to attach our SPI module to a microcontroller, since an FPGA allows you to allocate the pin locations yourself.

There are two ways to implement SPI on a microcontroller:-

  • using a hardware implementation of SPI (which is one of the advantages of a microcontroller,
  • using hardware implementations of basic interfaces such as SPI) or “bit-bang” SPI, which involves implementing and manipulating each of the SPI lines by software.

Bit-banging allows you to choose which digital pins to use to execute the SPI pins. In order to execute the communication protocol, you must use a special set of pins for the hardware implementation. It is best to consult the reference manual for your system board to determine which pins you need to use on your host board.

How to Program and interface SPI using MicroPython? 

Micropython is a software implementation of the Python programming language that has been made to work freely and compatible with microcontrollers. It has all the major features of Python and it also supports Python’s syntax, making the interaction with the hardware easy and simple for beginners and programmers. Many different microcontroller platforms also support it.  Some of the best features of Micropython that make it unique and the best choice for microcontrollers are following:

  • Highly Interactive REPL(Read-Evaluate-Print-Loop)
  • Extensive Software Library.
  • Extensible with low-level C/C++ functions. 

Now let us see how to set up your microcontroller for hardware SPI connection using MicroPython. Though a software SPI connection is much more adaptable than a hardware SPI, there are two major reasons why we use them infrequently. It not only offers a slower connection since the SPI protocol is being implemented in code instead of special hardware but is also not supported by most of the MicroPython boards. 

Setup Hardware SPI Connection For ESP8226

The hardware SPI runs up to 80MHz but only works on specific GPIO pins: GPIO12, GPIO13, and GPIO14. These are the following steps to set up the SPI connection to the board’s serial or REPL:

SPI

1: Import the machine module

Copy the following commands to import the machine module.

import machine

2:  Create an SPI object

Construct an SPI object and then identify the device using bus-id and initialise the SPI device. Since you can easily connect multiple SPI devices, each SPI device will be identified by bus-id . Similarly, create a constructor on the given bus id. The values of the id depend on the board’s hardware as well as the specific port. 

class machine.SPI(id, ...)

Since there are no parameters, the object is just created and not initialised with any value. If you will provide extra arguments, only then it will initialise the object.

Baudrate is the rate at which signal units can be transferred in a communication channel per second and also determine the bandwidth of the channel. Each signal unit consists of a number of bits. Baudrate can be anywhere between 110 to 10MHz. So, here the baud rate taken is 50000 that means the serial portal is capable of transferring a maximum of 50000 bits per second. 

When using an SPI connection, one master device (usually a microcontroller) controls the peripheral devices. Mostly, there are the following three lines typical 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 synchronise data transmission generated by the master
class machine.SoftSPI(baudrate=500000, *, polarity=0, phase=0, bits=8, firstbit=MSB, sck=None, mosi=None, miso=None)

Construct a new software SPI object. Also, we use some additional parameters like sck, mosi, and miso to initialise the bus. We have discussed the parameters in detail in the STEP  

3: Initialisation of SPI bus (Method)

Run the following method to initialise the SPI bus.

SPI.init(baudrate=1000000, *, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=None, mosi=None, miso=None, pins=SCK, MOSI, MISO)

Use the following parameters :

  • baudrate is the SCK clock rate.
  • polarity is the level the idle clock line sits at, which can be 0 or 1
  • phase is the sample data on the first or second clock edge that can be 0 or 1.
  • bits are the bit width of each transfer but the hardware supports only 8.
  • firstbit can be SPI.MSB or SPI.LSB.
  • sck, mosi, miso are pins (machine.pin) objects for the bus signals. Pins for fixed and can’t be changed for most of the hardware It blocks, but some hardware blocks allow 2-3 alternative pin sets. SPI driver (id = -1) can only be bit-banged by Arbitrary pins.
  • In case if you are using WiPy,  pins – WiPy port only allows the sck, mosi, miso values to specify them as a tuple of pins parameter and not as a singular argument.

The clock frequency may reduce and be lower than the required baud rate in hardware SPI connection. This factor also depends on the platform ware. So, by printing the project, the actual can be determined. 

4: Turn Off The Bus

To turn off the SPI bus, use the following method:

SPI.deinit()

5: Read The Number Of Bytes

Read the number of bytes defined by the nbytes also, write the single-byte specified by write. Then, return a  bytes object along with the read data. Use the following method to carry out the process:

SPI.read(nbytes, write=0)

6: Read The Buffer

You need to read into the buffer by buf and also write continuously the single-byte specified by the write. In the end, return None.

SPI.readinto(buf, write=0)

7: Write The Bytes

Write the bytes stored in buf then, return None. Use the following method:

SPI.write(buf)

8: Write The buf Value

Write the bytes stored in buf and Returns None.

SPI.write(buf)

9: Write The write_buf Values

The bytes from write_buf are also to be written along with reading into read_buf. The length of both the buffers should be same. Both the buffers can be the same and different as well. In the end, return None.

SPI.write_readinto(write_buf, read_buf)

Using Constants:

1. SPI.MSB

This constant is used to set the first bit as the most significant bit.

2. SPI.LSB

This constant is used to set the first bit as the least significant bit.

Codes Used

1:

import machine

2:

class machine.SoftSPI(baudrate=500000, *, polarity=0, phase=0, bits=8, firstbit=MSB, sck=None, mosi=None, miso=None)

3:

SPI.init(baudrate=1000000, *, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=None, mosi=None, miso=None, pins=SCK, MOSI, MISO)

4:

SPI.deinit()

5:

SPI.read(nbytes, write=0)

6:

SPI.readinto(buf, write=0)

7:

SPI.write(buf)

8:

SPI.write(buf)

9:

SPI.write_readinto(write_buf, read_buf)

SPI Vs I2C: Comparison Table

FeaturesI2CSPI
Full FormI2C stands for Inter integrated circuitSPI stands for Serial peripheral interface
Number of wiresI2C requires 2 wires (SCL and SDA)SPI requires 4 wires (MISO, MOSI, CS and CLK)
Connection diagram
CommunicationI2C is a half-duplex communication protocol, which means that the master and slave can communicate with each other but not at the same time.SPI is a full duplex communication protocol, which ensures that the master and slave can communicate with each other at the same time.
ACKAfter each transmission, I2C receives an acknowledgement from the respective slave, indicating that I2C provides a data transmission guarantee.If SPI does not receive an acknowledgement from the slave device, it means that SPI does not guarantee data transmission.
MechanismTo communicate with a slave, I2C employs the Addressing mechanism.To communicate with a slave, SPI uses a slave select or chip select pin.
Multiple slaves or ScaleSince it has an addressing mechanism, only two wires are needed to communicate with multiple slaves.Each slave needs one chip select or slave select pin in SPI. When the number of slaves increases, so does the number of slave select or chip select pins.
SpeedI2C is slower (typically 100kbps, 400kbps and 3.4Mbps)SPI is faster (up to 10 Mbps)
PowerI2C needs more powerSPI needs less power
DistanceI2C can be used for long distanceSPI better for short distance

SPI vs I2C: Which is better?

SPI

Two protocols are widely used for communicating between chips on a printed circuit board:-

  • Serial Peripheral Interface (SPI) and
  • Inter-Integrated Circuit (IIC) (IIC or I2C).

These wired protocols are called “low-end” because they lack the speed, robustness, and range of other protocols such as USB, Ethernet, SATA, and so on.

However, SPI and I2C are much more popular than their heavyweight cousins because they are easier to implement, requiring fewer components and less code. Both use serial communication to transfer data and can accommodate multiple devices on a single bus.

Many microcontrollers, sensors, and peripherals (such as LCDs) communicate using SPI and I2C.

Which would you prefer if you were designing a product and had to choose between SPI and I2C?

Both protocols are appropriate for a wide range of applications. Most of the time, you are limited to the protocol supported by the manufacturer of a specific component. Some accelerometers, such as the Analog Devices ADXL345 accelerometer, have both I2C and SPI interfaces on the same chip. If you have to choose between the two, SPI is usually the better choice for faster transfer speeds. I2C, on the other hand, is ideal if your microcontroller or microprocessor has a limited number of pins.

SPI vs UART: Comparision Table

FeaturesUARTSPI
Full FormUniversal Asynchronous Receiver/TransmitterSerial Peripheral Interface
Connection Diagram
Pin DesignationsTxD: Transmit Data
RxD: Receive Data
SCLK: Serial Clock
MOSI: Master Output, Slave Input
MISO: Master Input, Slave Output
SS: Slave Select
Data rateSince this is asynchronous communication, the data rate between two communicating devices should be set to the same value. The maximum data rate allowed ranges from 230 Kbps to 460 Kbps.The maximum data rate limit in the SPI interface is not defined. Usually supports 10 Mbps to 20 Mbps.
DistanceLower about 50 feetHighest
Type of communicationAsynchronousSynchronous
Number of mastersNot ApplicationOne
ClockThere is no use of the Common Clock signal. Both devices can operate with their own clocks.For both master and slave devices, there is a single serial clock signal.
Hardware ComplexityLesserLess
ProtocolOne start bit and one stop bit are used for every 8 bits of data.Each company or manufacturer has its own set of protocols for communicating with peripherals. As a result, in order to establish SPI communication, it is essential to read the datasheet and understand the read/write protocol. For instance, we’d like SPI communication between the microcontroller and the EPROM. In this case, the read/write operational diagram in the EPROM data sheet must be consulted.
Software AddressingAddressing is not needed since this is a one-to-one link between two devices.Slave select lines are used to address any slave that is connected to the master. On the master device, there will be ‘n’ slave select lines for ‘n’ slaves.

SPI vs UART: Which is better?

There is no one-size-fits-all solution to the question “UART vs SPI: Which is better?” However, with the details we’ve provided here, you should be able to make an educated decision about which approach is best for a specific application you’re working on.

UART is the simplest and most popular mode of communication, and

  • It is available because UART support is present in almost all devices with a 9-pin connector.
  • It is also known as an RS232 interface.
  • They are only suitable for two-way communication.
  • It supports a set data rate that is settled upon between devices prior to communication; otherwise, data is garbled.

SPI is a simple protocol that does not necessitate processing overheads.

  • It allows for full-duplex communication.
  • Since CS lines are used separately, the same type of multiple chips may be used in the circuit design. Since it uses push-pull, higher data rates and longer ranges are possible.
  • It consumes less power than I2C.
  • When the number of slaves increases, so does the number of CS lines, resulting in increased hardware complexity due to the increased number of pins needed.
  • To add a device in SPI, one must add an extra CS line and make adjustments to the program for specific device addressing. The master/slave relationship cannot be modified, as is common in I2C interfaces. It does not support flow control.

In general, SPI is favored in applications that require higher-speed communication between chips or communications between multiple devices. UART, on the other hand, may be best suited for applications that need RS-232 support and may travel a slightly greater distance, such as diagnostic displays.

Wrapping It Up

So, this was a complete tutorial on how to program and interface SPI connection for a microcontroller using MicroPython. Almost all the processors are equipped with an SPI port for communication between SPI as well as peripheral ICs, making Serial Peripheral Interface (SPI) a very important medium of communication. Hope this article made the procedure of setting up the SPI connection easy for you. Good luck with your next IoT project!

0 0 votes
Article Rating
Previous articleThe New RP2040 Board from Arduino: Worth the $25 Price Tag?
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments