Library 05- SPI for STM32F4

Let’s say something about SPI. SPI (or Serial Peripheral Interface) is a protocol named by Motorola. With him you can control sensors, SD card and much more.

SPI protocol works in a ways where there is one master and multiple slaves, In other words, master is our STM32F429 Discovery board and let’s say, SD card is slave.

SPI uses 3 main wires. Because more slaves can be connected to one master on same SPI peripheral, there is 4th pin called SS. SPI pin names are:

  • SCLK: Serial clock, clock for synchronization slave with master
  • MOSI: Master Out Slave In. data sent from master to slave
  • MISO: Master In Slave Out, data send from slave to master
  • SS: Slave Select, with this pin low, you enable slave. This is useful, when you have more devices on same SPI. If you have more devices as slaves, you have to manually set pins for every slave separately. When you want to send data to some slave, you put SS pin for that slave low, send data and put it back high. If SS pin is HIGH, slave does not detect your incoming data.
Connect master with slave


Our STM32F429 Discovery supports 6 SPIs. Except SPI6, all SPIs have at least 2 configurable pins, which you want to use. I searched for pins used for peripheral and show to you in bottom table.

Pins pack 1 Pins pack 2 Pins pack 3
SPI1 PA7 PA6 PA5 PB5 PB4 PB3 2
SPI2 PC3 PC2 PB10 PB15 PB14 PB13 PI3 PI2 PI0 1
SPI3 PB5 PB4 PB3 PC12 PC11 PC10 1
SPI4 PE6 PE5 PE2 PE14 PE13 PE12 2
SPI5 PF9 PF8 PF7 PF11 PH7 PH6 2
SPI6 PG14 PG12 PG13 2

On the 8th column is APB. APB means Advanced Peripheral Bus. Inside our mcu are APB1 and APB2. This two are used for peripheral clock configuration. There is also AHB (Advanced High-performance Bus) for GPIO pins.

The difference between APB1 and APB2 is:

  1. APB1 has clock 4x slower than processor speed, in our case we have 180MHz core clock, APB1 has 45MHz
    1. APB1 communication bus has 45MHz, so SPI works also on 45MHz
    2. And because minimal prescaler for SPI is 2, max frequency is 45/2 = 22.5 MHz
    3. SPI Clock = APBx / prescaler = 45MHz  / 2 = 22.5MHz
    4. By default, prescaler 32 is used:
      1. SPI Clock = APBx / prescaler = 45MHz / 32 = 1.40625MHz
  2. APB2 has clock 2x slower than processor speed, in our case we have 180MHz core clock, APB2 has 90MHz
    1. APB2 communication bus has 90MHz
    2. And because minimal prescaler for SPI is 2, max frequency is 45MHz
    3. SPI Clock = APBx / prescaler = 90MHz / 2 = 45MHz
    4. By default, prescaler 32 is used:
      1. SPI Clock = APBx / prescaler = 90MHz / 32 = 2.8125MHz

This means that SPI1, SPI4, SPI5 and SPI6 have maximum frequency of 45MHz, SPI2 and SPI3 have 22.5MHz. In both cases frequency can be slower, set with internal prescalers.



  • All possible SPI’s available on STM32F4
  • 8- or 16- bit SPI mode
  • Default SPI configuration
    • Master mode
    • 8 data bits
    • prescaler set to divide APBx clock with 32
    • Clock is low on idle and data sampled at rising edge (SPI Mode 0)
    • first bit is MSB bit
    • 2 wires full-duplex
    • SS pin is software configurable


    • STM32F4xx
    • STM32F4xx RCC
    • STM32F4xx GPIO
    • STM32F4xx SPI
  • TM
    • TM GPIO
    • defines.h
    • attributes.h

You can configure your settings in defines.h file:

If you want to initialize SPI1 and set pins PA7, PA6 and PA5 for MOSI, MISO and SCK then you would call something like that:

or with pins pack 2

This principle works for all 6 SPIs.

Then you want to send some data over SPI. You can do this with

This function sends 8bit data over SPIx. When SPI finished transmission, 8bit received data is returned.

Functions and enumerations

Main example

Project is available on Github, download library below.


Owner of this site. Application engineer, currently employed by STMicroelectronics. Exploring latest technologies and owner of different libraries posted on Github.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!