STM32F103 SPL Tutorial 5 – SPI Interface


STM32F103 SPI (Serial Peripheral Interface) is a synchronous serial communication protocol. In this interface, in addition to transmit and receive lines, there is a third line that is used for clock line. Each slave device also has a chip select (enable) pin, that is used for activating the device. So to use SPI, we need 2 wires for data lines (MOSI, MISO), 1 wire for clock line, and 1 wire per device for chip select line. MOSI (Master Out Slave In) is used for data transfer from master device to slave device. MISO (Master In Slave Out) is used for data transfer from slave device to master device.

SPI bus

SPI Protocol

SPI communication is different from other serial communication especially on data transfer. There is no concept like transmit and receive data, but there is a data trading concept. When data trading occurs, the data bits in master register is traded with the data bits in slave register on every clock from master (one data bit per clock tick). You can think SPI is like shift registers. There are 2 shift registers, one in master device and another in slave device. Each input of shift register is connected to the output of the other through MOSI and MISO lines, so that they form a ring.

Shift register

The figure above illustrates the bit trading from master to slave. Master register contain data 0xFF and slave register contain data 0x00. After one clock tick, the master is left with seven of its original bits and the first one that is come in from the slave, and vice versa. After a total of eight clock ticks, all eight bits of each byte have traded place. Sometimes not all data byte come from slave or sent to slave is meaningful. This happen because probably slave device has not received any command yet, so the data in slave register is not meaningful. Another case, if we just want to take data from slave, but don’t want to send any command to slave, we can place dummy byte on master register and then give eight clock ticks for trading with data bits in slave register.

Sparkfun SPI

The figure above is the timing diagram of SPI protocol. We know that to communicate to the slave device, the slave select pin should be activated (active low). The data is sampled every rising edge of clock. We can also sample data on falling edge of clock, this setting can be configured depending on the feature of the hardware SPI that you use. In this example, master is send data byte 0x53 to slave and then slave send data byte 0x46 to master. The order of the data is LSB first, but it can also MSB first depending on the configuration.

Example Code

In this tutorial, I will explain how to use SPI in STM32F103 as a master, and for the slave I will use Arduino. We can send data char ‘1’ from SPI master to turn on LED blinking on Arduino. To turn off LED blinking, we can send ‘0’ from SPI master. Master can also read LED blinking status (off/on) from Arduino by sending ‘?’ first, then read the LED blinking status which will return 0 or 1. This is the Arduino code for SPI slave device.

For the SPI on STM32F103, I create several functions such as for initialize SPI, SPI data transfer, and enable/disable slave device. In main function, I write codes to turn on and off the LED blinking on Arduino, then ask the current LED blinking status every 2500 ms. The LED blinking status will be displayed on LCD.

You can get the project file from here. This is the result:

Go to the part 6 of the tutorial.