{"id":5849,"date":"2021-03-28T03:11:48","date_gmt":"2021-03-28T01:11:48","guid":{"rendered":"https:\/\/deepbluembedded.com\/?p=5849"},"modified":"2024-01-21T00:50:31","modified_gmt":"2024-01-20T22:50:31","slug":"stm32-spi-tutorial","status":"publish","type":"post","link":"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/","title":{"rendered":"STM32 SPI Tutorial"},"content":{"rendered":"<table style=\"border-collapse: collapse; width: 100%;\" border=\"1\">\n<tbody>\n<tr>\n<td style=\"background-color: #ffffff; width: 5%;\"><a href=\"https:\/\/deepbluembedded.com\/stm32-hc-05-bluetooth-module-examples\/\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1666 alignleft\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L-150x150.png\" alt=\"Previous Tutorial\" width=\"35\" height=\"35\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L-150x150.png 150w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L-160x160.png 160w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L-320x320.png 320w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L-50x50.png 50w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L.png 256w\" sizes=\"auto, (max-width: 35px) 100vw, 35px\" \/><\/a><\/td>\n<td style=\"background-color: #ffffff; width: 30%; text-align: left;\" colspan=\"2\"><a href=\"https:\/\/deepbluembedded.com\/stm32-hc-05-bluetooth-module-examples\/\"><strong>Previous Tutorial<\/strong><\/a><\/td>\n<td style=\"background-color: #ffffff; width: 30%; text-align: center;\" colspan=\"2\"><span style=\"color: #000000;\"><strong><span style=\"font-size: 14pt;\">Tutorial 41<\/span><\/strong><\/span><\/td>\n<td style=\"background-color: #ffffff; width: 30%; text-align: right;\" colspan=\"2\"><a href=\"https:\/\/deepbluembedded.com\/how-to-receive-spi-with-stm32-dma-interrupt\/\"><strong>Next Tutorial<\/strong><\/a><\/td>\n<td style=\"background-color: #ffffff; width: 5%;\"><a href=\"https:\/\/deepbluembedded.com\/how-to-receive-spi-with-stm32-dma-interrupt\/\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1667 alignright\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256-150x150.png\" alt=\"Next Tutorial\" width=\"35\" height=\"35\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256-150x150.png 150w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256-160x160.png 160w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256-320x320.png 320w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256-50x50.png 50w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256.png 256w\" sizes=\"auto, (max-width: 35px) 100vw, 35px\" \/><\/a><\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #ffffff; width: 5%;\"><\/td>\n<td style=\"background-color: #ffffff; text-align: center;\" colspan=\"6\"><span style=\"font-size: 14pt;\"><strong>STM32 SPI Communication Tutorial<\/strong><\/span><\/td>\n<td style=\"background-color: #ffffff; width: 5%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #ffffff; width: 5%;\"><\/td>\n<td style=\"width: 20%; background-color: #ffffff; text-align: center;\" colspan=\"6\"><a href=\"https:\/\/deepbluembedded.com\/stm32-arm-programming-tutorials\/\"><span style=\"font-size: 10pt;\"><strong>STM32 Course Home Page <\/strong><\/span>????<\/a><\/td>\n<td style=\"background-color: #ffffff; width: 5%;\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5871\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Guide.jpg\" alt=\"STM32 SPI Tutorial - Interrupt DMA Polling - SPI HAL Example Code Guide\" width=\"720\" height=\"340\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Guide.jpg 720w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Guide-300x142.jpg 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Guide-520x245.jpg 520w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">In this tutorial, we&#8217;ll be discussing the SPI hardware in STM32 microcontrollers. Starting with an introduction to the Serial Peripheral Interface (SPI) communication. And we&#8217;ll get a closer look at the STM32 SPI hardware module and its internal functionalities, modes of operation, options, and configurations. In conclusion, we&#8217;ll take a look at the possible interrupt signals that can be triggered by the SPI hardware. And the different modes to perform SPI transmit &amp; receive operations like (polling &#8211; interrupt &#8211; DMA).<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Finally, we&#8217;ll check the available SPI configuration inside of CubeMX and how to configure &amp; operate the peripheral using the provided HAL APIs. And that&#8217;s it for this theoretical tutorial. Next, we&#8217;ll do a couple of LABs to practice using SPI in different projects for communication and modules interfacing with STM32 microcontrollers.<\/span><\/p>\n<p>[toc]<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #333333;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a01. Introduction To SPI Communication<\/span><\/strong><strong><span style=\"color: #ffffff;\">\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">SPI is an acronym for (Serial Peripheral Interface) pronounced as \u201cS-P-I\u201d or \u201cSpy\u201d. Which is an interface bus typically used for serial communication between microcomputer systems and other devices, memories, and sensors. Usually used to interface Flash Memories, ADC, DAC, RTC, LCD, SDcards, and much more. <\/span><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The SPI was originally developed by Motorola back in the 80s to provide full-duplex serial communication to be used in embedded systems applications.<\/span><\/p>\n<p><strong>SPI Pin Conventions &amp; Connections<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">In typical SPI communication, there should be at least 2 devices attached to the SPI bus. One of them should be the master and the other will essentially be a slave. The master initiates communication by generating a serial clock signal to shift a data frame out, at the same time serial data is being shifted-in to the master. This process is the same whether it\u2019s a read or write operation.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5862\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/SPI-Tutorial-STM32-Master-Slave-Connection.png\" alt=\"SPI Tutorial STM32 Master - Slave Connection\" width=\"762\" height=\"465\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/SPI-Tutorial-STM32-Master-Slave-Connection.png 762w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/SPI-Tutorial-STM32-Master-Slave-Connection-300x183.png 300w\" sizes=\"auto, (max-width: 762px) 100vw, 762px\" \/><\/p>\n<ul>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>MOSI<\/strong> -&gt; Master output slave input (D<sub>OUT<\/sub> From Master).<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>MISO<\/strong> -&gt; Master input slave output (D<sub>OUT<\/sub> From Slave).<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>SCLK<\/strong>\u00a0-&gt; Serial Clock, generated by the master and goes to the slave.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>SS<\/strong>\u00a0-&gt; Slave Select. Generated by the master to control which slave to talk to. It\u2019s usually an active-low signal.<\/span><\/li>\n<\/ul>\n<p><strong>SPI Modes of Operation<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Devices on the SPI bus can operate in either mode of the following:\u00a0<strong>Master<\/strong>\u00a0or\u00a0<strong>Slave<\/strong>. There must be at least one master who initiates the serial communication process (For Reading\/Writing). On the other hand, there can be single or multiple devices operating in slave mode.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The master device can select which slave to talk to by setting the\u00a0<strong>SS<\/strong>\u00a0(slave select) pin to logic low. If a single slave is being addressed, you can tie the SS pin of this slave device to logic low without the need to control this line by the master.<\/span><\/p>\n<p><strong>SPI Clock Configurations<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The master SPI device is responsible for generating the clock signal to initiate and continue the data transaction process. The master, therefore, determines the data rate by controlling the serial clock line&#8217;s (SCK) frequency which is a programmable parameter in hardware by firmware instructions.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The SPI clock has two more parameters to control which are the Clock Phase (CPHA) and the Clock Polarity (CPOL). The clock phase determines the phase at which the data latching occurs at each bit transfer whether it&#8217;s the leading edge or the trailing edge. The clock polarity determines the IDLE state of the clock line whether it&#8217;s a HIGH or LOW. Having 2 possible states for each of the CPOL and CPHA gives us a total of 4 possible modes for the SPI clock. Typically referred to as &#8220;SPI Mode Number&#8221;. <\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 50%; background-color: #ffffff;\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-2945\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/02\/SPI-Clock-Phase-And-Polarity-Table-1024x723.jpg\" alt=\"SPI Clock Phase And Polarity Table\" width=\"487\" height=\"344\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/02\/SPI-Clock-Phase-And-Polarity-Table-1024x723.jpg 1024w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/02\/SPI-Clock-Phase-And-Polarity-Table-300x212.jpg 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/02\/SPI-Clock-Phase-And-Polarity-Table-768x542.jpg 768w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/02\/SPI-Clock-Phase-And-Polarity-Table.jpg 1654w\" sizes=\"auto, (max-width: 487px) 100vw, 487px\" \/><\/td>\n<td style=\"width: 50%; background-color: #ffffff;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5860\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Mode-Numbers.png\" alt=\"STM32 SPI Mode Numbers\" width=\"277\" height=\"249\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 70%; text-align: center; background-color: #ffffff;\" colspan=\"2\"><strong><span style=\"color: #ff6600;\"><span style=\"color: #ff6600; font-family: arial, helvetica, sans-serif;\"><a style=\"color: #ff6600;\" href=\"https:\/\/deepbluembedded.com\/spi-tutorial-with-pic-microcontrollers\/\" target=\"_blank\" rel=\"noopener noreferrer\">Check this in-depth tutorial for more information about <\/a>SPI<\/span><a style=\"color: #ff6600;\" href=\"https:\/\/deepbluembedded.com\/uart-pic-microcontroller-tutorial\/\" target=\"_blank\" rel=\"noopener noreferrer\"> serial communication<\/a><\/span><\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 46.4848%; background-color: #ffffff;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2601\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/09\/Serial-Com.gif\" alt=\"Serial Communication | UART Tutorial With PIC Microcontroller\" width=\"854\" height=\"396\" \/><\/td>\n<td style=\"width: 23.5152%; background-color: #ffffff;\"><a href=\"https:\/\/deepbluembedded.com\/spi-tutorial-with-pic-microcontrollers\/\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2999\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/02\/SPI-Tutorial-PIC-Microcontrollers.jpg\" alt=\"SPI Tutorial - PIC Microcontrollers\" width=\"720\" height=\"340\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/02\/SPI-Tutorial-PIC-Microcontrollers.jpg 720w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/02\/SPI-Tutorial-PIC-Microcontrollers-300x142.jpg 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/02\/SPI-Tutorial-PIC-Microcontrollers-520x245.jpg 520w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The linked SPI tutorial above is a full guide (+8k words!) that has all the information you may need to know if you&#8217;re just starting to learn about the topic. Take the time to check it out if you need to and come back to resume this tutorial and to see the SPI hardware peripheral implemented in STM32 microcontrollers and the extra features it does have.<\/span><\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #333333;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a02. SPI Hardware In STM32\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<p><strong><span style=\"font-size: 14pt;\">2.1 STM32 SPI Hardware Overview<\/span><\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">the STM32 SPI interface provides two main functions, supporting either the SPI protocol or the I2S audio protocol. By default, it is the SPI function that is selected. It is possible to switch the interface from SPI to I2S by <\/span><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">software.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> The serial peripheral interface (SPI) allows half\/ full-duplex, synchronous, serial communication with external devices. The interface can be configured as the master and in this case, it provides the communication clock (SCK) to the external slave device. The interface is also capable of operating in a multi-master configuration.<\/span><\/p>\n<p><strong><span style=\"font-size: 14pt;\">2.2 STM32 SPI Main Features<\/span><\/strong><\/p>\n<ul>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Full-duplex synchronous transfers on three lines<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Simplex synchronous transfers on two lines with or without a bidirectional data line<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">8- or 16-bit transfer frame format selection<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Master or slave operation<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Multimaster mode capability<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">8 master mode baud rate prescalers (fPCLK\/2 max.)<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Slave mode frequency (fPCLK\/2 max)<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">NSS pin management by hardware or software for both master and slave: dynamic change of master\/slave operations<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Programmable clock polarity and phase<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Programmable data order with MSB-first or LSB-first shifting<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Dedicated transmission and reception flags with interrupt capability<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">SPI bus busy status flag<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Hardware CRC feature for reliable communication: [ CRC value can be transmitted as the last byte in Tx mode \u2013 Automatic CRC error checking for last received byte ]<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Master mode fault, overrun, and CRC error flags with interrupt capability<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">1-byte transmission and reception buffer with DMA capability: Tx and Rx requests<\/span><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #333333;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a03. STM32 SPI Hardware Functionalities\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">In this section, we&#8217;ll get a deep insight into the STM32 SPI module hardware, its block diagram, functionalities, modes of operations, and data reception\/transmission.<\/span><\/p>\n<p><strong><span style=\"font-size: 14pt;\">3.1 STM32 SPI Block Diagram<\/span><\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5863\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Block-Diagram.png\" alt=\"STM32 SPI Block Diagram\" width=\"935\" height=\"732\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Block-Diagram.png 935w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Block-Diagram-300x235.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Block-Diagram-768x601.png 768w\" sizes=\"auto, (max-width: 935px) 100vw, 935px\" \/><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">As you can see in the SPI block diagram above, there is the main shift register lying between two buffer registers one for transmission (TX) and the other for reception (RX). And a logical control unit on the right side with a bunch of signals coming in and out to the control registers.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The control registers give you the ability to change any of the SPI hardware configurations by software instructions. And there is also the status register that gives you some signals about the ongoing and last-done transaction and any error if happened.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The baud rate generator (Clock signal SCK) is also configurable by software as we can tell and there is a control logic dedicated for the NSS pin (if you&#8217;re going to use it).<\/span><\/p>\n<p><strong><span style=\"font-size: 14pt;\">3.2 STM32 SPI Data Frame Format<\/span><\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> Data can be shifted out either MSB-first or LSB-first depending on the value of the LSBFIRST bit in the SPI_CR1 Register.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Each data frame is 8 or 16 bits long depending on the size of the data programmed using the DFF bit in the SPI_CR1 register. The selected data frame format is applicable for transmission and\/or reception.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">It has to be the same on both ends of the communication. The slave should know what to expect in order to read the received data correctly. It has to be formatted coordinately.<\/span><\/p>\n<p><strong><span style=\"font-size: 14pt;\">3.3 STM32 SPI In Slave Mode<\/span><\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> In the slave configuration, the serial clock is received on the SCK pin from the master device. The baud rate value set in the BR[2:0] bits in the SPI_CR1 register, does not affect the data transfer rate. In this configuration, the MOSI pin is a data input pin and the MISO pin is a data output.<br \/>\n<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Note that you need to have the SPI slave device running and configured before the master starts to send anything just to avoid any possible data corruption at the beginning of the first communication session.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The configuration procedure is available in the datasheet if you&#8217;d like to follow it in order to build an SPI initialization function at the register-level. But we&#8217;ll be using the HAL APIs so it&#8217;ll handle this procedure for us regardless of the specific STM32 target microcontroller we&#8217;re using in the design.<\/span><\/p>\n<p><strong>Transmit Sequence in Slave Mode<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> The data byte is parallel-loaded into the Tx buffer during a write cycle. The transmit sequence begins when the slave device receives the clock signal and the most significant bit of the data on its MOSI pin. The remaining bits (the 7 bits in 8-bit data frame format, and the 15 bits in 16-bit data frame format) are loaded into the shift-register. The TXE flag in the SPI_SR register is set on the transfer of data from the Tx Buffer to the shift register and an interrupt is generated if the TXEIE bit in the SPI_CR2 register is set.<\/span><\/p>\n<p><strong>Receive Sequence in Slave Mode<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> For the receiver, when data transfer is complete: <\/span><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The Data in the shift register is transferred to Rx Buffer and the RXNE flag (SPI_SR register) is set. An Interrupt is generated if the RXNEIE bit is set in the SPI_CR2 register.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif;\"><span style=\"color: #000000;\">After the last sampling clock edge, the RXNE bit is set, a copy of the data byte received in the shift register is moved to the Rx buffer. When the SPI_DR register is read, the SPI peripheral returns this buffered value. Clearing of the RXNE bit is performed by reading the SPI_DR register.<\/span><\/span><\/p>\n<p><strong><span style=\"font-size: 14pt;\">3.4 STM32 SPI In Master Mode<\/span><\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> In the master configuration, the serial clock is generated on the SCK pin. In this configuration, the MOSI pin is a data output pin and the MISO pin is data input.<\/span><\/p>\n<p><strong>Transmit Sequence in Master Mode<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> The transmit sequence begins when a byte is written in the Tx Buffer. The data byte is parallel-loaded into the shift register (from the internal bus) during the first-bit\u00a0transmission and then shifted out serially to the MOSI pin MSB first or LSB first depending on the LSBFIRST bit in the SPI_CR1 register. <\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The TXE flag is set on the transfer of data from the Tx Buffer to the shift register and an interrupt is generated if the TXEIE bit in the SPI_CR2 register is set.<\/span><\/p>\n<p><strong>Receive Sequence in Master Mode<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> For the receiver, when data transfer is complete: The data in the shift register is transferred to the RX Buffer and the RXNE flag is set. An interrupt is generated if the RXNEIE bit is set in the SPI_CR2 register<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">At the last sampling clock edge, the RXNE bit is set, a copy of the data byte received in the shift register is moved to the Rx buffer. When the SPI_DR register is read, the SPI peripheral returns this buffered value.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif;\"><span style=\"color: #000000;\">Clearing the RXNE bit is performed by reading the SPI_DR register. A continuous transmit stream can be maintained if the next data to be transmitted is put in the Tx buffer once the transmission is started. Note that the TXE flag should be \u20181 before any attempt to write the Tx buffer is made.<\/span><\/span><\/p>\n<p><strong><span style=\"font-size: 14pt;\">3.5 SPI Half-Duplex Communication Configuration<\/span><\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> The STM32 SPI Hardware is capable of operating in half-duplex mode in 2 configurations.<\/span><\/p>\n<ul style=\"text-align: justify;\">\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">1 clock and 1 bidirectional data wire<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">1 clock and 1 data wire (receive-only or transmit-only)<\/span><\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Check the target MCU&#8217;s datasheet for more information about each configuration of them if you&#8217;re going to use this Half-Duplex mode. I don&#8217;t think we&#8217;d need that in any of the future tutorials. But if we did, I&#8217;ll give some examples to do this type of communication with SPI.\u00a0<\/span><\/p>\n<p><strong><span style=\"font-size: 14pt;\">3.6 STM32 <\/span><\/strong><strong><span style=\"font-size: 14pt;\">SPI Data Transmission &amp; Reception<\/span><\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> In reception, data are received and then stored into an internal Rx buffer while In transmission, data are first stored into an internal Tx buffer before being transmitted.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">A read access to the SPI_DR register returns the Rx buffered value, whereas a write access to the SPI_DR stores the written data into the Tx buffer.<\/span><\/p>\n<p><strong><span style=\"font-size: 14pt;\">3.6 STM32 <\/span><\/strong><strong><span style=\"font-size: 14pt;\">SPI CRC Calculation<\/span><\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> A CRC calculator has been implemented in STM32 SPI hardware for communication reliability. Separate CRC calculators are implemented for transmitted data and received data. The CRC is calculated using a programmable polynomial serially on each bit. It is calculated on the sampling clock edge defined by the CPHA and CPOL bits in the SPI_CR1 register.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> At the end of data and CRC transfers, the CRCERR flag in the SPI_SR register is set if corruption occurs during the transfer. This is similar to a checksum if you&#8217;re familiar with error detection procedures for communication. Actually, the checksum is a very simple way of doing a mathematical operation (addition) to the data being transferred to check the validity of the whole data packet.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The CRC (cyclic redundancy check) is a much &#8220;mathematically&#8221; powerful operation than a normal checksum that&#8217;s much harder to fool. There are many different versions and equations for performing CRC in general but it&#8217;s really good to have it built within the SPI hardware itself.<\/span><\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #333333;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a04. STM32 SPI Flags (Status &amp; Errors)\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">There are some status flags provided for the application to completely monitor the state of the SPI bus.<\/span><\/p>\n<ul>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>Tx buffer empty flag (TXE)<\/strong> &#8211; When it is set, this flag indicates that the Tx buffer is empty and the next data to be transmitted can be loaded into the buffer. The TXE flag is cleared when writing to the SPI_DR register.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>Rx buffer not empty (RXNE)<\/strong> &#8211; When set, this flag indicates that there are valid received data in the Rx buffer. It is cleared when SPI_DR is read.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>BUSY flag<\/strong> &#8211; The BSY flag is useful to detect the end of a transfer if the software wants to disable the SPI and enter Halt mode (or disable the peripheral clock). This avoids corrupting the last transfer. For this, the procedure described below must be strictly respected. The BSY flag is also useful to avoid write collisions in a multi-master system.<\/span><\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">There are also other SPI flags that indicate whether a specific type of error has occurred or not.<\/span><\/p>\n<ul>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong> SPI Master mode fault (MODF)<\/strong><b> &#8211;\u00a0<\/b> Master mode fault occurs when the master device has its NSS pin pulled low (in NSS hardware mode) or SSI bit low (in NSS software mode), this automatically sets the MODF bit.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>SPI Overrun condition<\/strong><b> &#8211;\u00a0<\/b> An overrun condition occurs when the master device has sent data bytes and the slave device has not cleared the RXNE bit resulting from the previous data byte transmitted.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>SPI CRC error<\/strong><b> &#8211;\u00a0<\/b> This flag is used to verify the validity of the value received when the CRCEN bit in the SPI_CR1 register is set. The CRCERR flag in the SPI_SR register is set if the value received in the shift register does not match the receiver SPI_RXCRCR value.<\/span><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #333333;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a05. STM32 SPI Interrupts\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The SPI interrupt events are connected to the same interrupt vector. So the SPI fires a single interrupt signal regardless of the source of it. The software will have to detect it. <\/span><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">These events generate an interrupt if the corresponding Enable Control Bit is set.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-5866\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Interrupts.png\" alt=\"STM32 SPI Interrupts\" width=\"715\" height=\"221\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Interrupts.png 942w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Interrupts-300x93.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Interrupts-768x237.png 768w\" sizes=\"auto, (max-width: 715px) 100vw, 715px\" \/><\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #333333;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a06. STM32 SPI Transmit &amp; Receive Modes\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">In this section, I&#8217;ll list the possible ways that you can handle SPI transactions in your firmware applications. For code example LABs and testing, just click on the next tutorial button and keep going through this series of tutorials. There will be lots of examples and libraries that we&#8217;ll build based on SPI communication.<\/span><\/p>\n<h4><span style=\"color: #000000;\"><strong>SPI With Polling<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The first and the easiest way to do anything in embedded software is just to poll for the hardware resource until it&#8217;s ready to move on to the next step in your program instructions. However, it&#8217;s the least efficient way to do things and the CPU will end up wasting so much time in a &#8220;busy-waiting&#8221; state.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">It&#8217;s the same thing for both transmission and reception. You just wait until the current byte of data to be transmitted so you can start the next one and so on.<\/span><\/p>\n<h4><span style=\"color: #000000;\"><strong>SPI With Interrupts<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">We can, however, enable the SPI interrupts and have a signal when it&#8217;s done and ready for servicing by CPU. Either for data that has been sent or received. Which saves a lot of time and has been always the best way to handle events like that.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">However, in some &#8220;Time Critical&#8221; applications we need everything to be as deterministic, in time, as possible. And a major problem with interrupts is that we can&#8217;t expect when it&#8217;d arrive or during which task. That can potentially screw up the timing behavior of the system, Especially with an extremely fast communication bus like SPI that can definitely block the CPU if you&#8217;re receiving massive data blocks at a very high rate.<\/span><\/p>\n<h4><span style=\"color: #000000;\"><strong>SPI With DMA<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> To operate at its maximum speed, the SPI needs to be fed with the data for transmission and the data received on the Rx buffer should be read to avoid overrun. To facilitate the transfers, the SPI features a DMA capability implementing a simple request\/acknowledge protocol. <\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">A DMA access is requested when the enable bit in the SPI_CR2 register is enabled. Separate requests must be issued to the Tx and Rx buffers.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Using the DMA unit not only will make the SPI going at full speed on both sides of communication, but it will also free the CPU from doing the data transfers &#8220;from peripheral to memory&#8221;. This will end up saving a lot of time and is considered to be the most efficient way to handle this peripheral to memory data transfer and vice versa.<\/span><\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #333333;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a07. SPI Configuration In CubeMX\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">In the next few tutorials, we&#8217;ll be doing some practical LABs to implement SPI receiver\/transmitter code examples. In which we&#8217;ll be using the CubeMX software tool to configure the SPI hardware. Therefore, in this section, I&#8217;ll introduce to you the features and options that can be configured within CubeMX GUI for SPI peripheral.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Here is the configuration tab for the SPI peripheral in CubeMX. <\/span><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">And those are the possible modes for SPI.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5868\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-CubeMX-Configurations1.png\" alt=\"STM32 SPI CubeMX Configurations1\" width=\"365\" height=\"260\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-CubeMX-Configurations1.png 365w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-CubeMX-Configurations1-300x214.png 300w\" sizes=\"auto, (max-width: 365px) 100vw, 365px\" \/><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Let&#8217;s pick the &#8220;Full-Duplex Master&#8221; mode for example. You&#8217;ll find that now we&#8217;re able to set the baud rate, frame type and size, NSS pin control, CRC, SPI Mode Number (Clock Phase &amp; Polarity), and other parameters. <\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">We can also enable\/disable interrupts for SPI in the NVIC tab if you&#8217;re willing to use interrupt mode instead of polling the peripheral. And the same goes for the DMA, you can click the DMA tab to &#8220;Add&#8221; a DMA channel dedicated to SPI transfer and configure its parameters.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-5869\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-CubeMX-Configurations-1024x512.png\" alt=\"STM32 SPI CubeMX Configurations\" width=\"1024\" height=\"512\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-CubeMX-Configurations-1024x512.png 1024w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-CubeMX-Configurations-300x150.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-CubeMX-Configurations-768x384.png 768w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-CubeMX-Configurations.png 1276w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #333333;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a08. SPI HAL Functions APIs\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<h4><span style=\"color: #000000;\"><strong>1.\u00a0 STM32 SPI Blocking Mode HAL Functions<\/strong><\/span><\/h4>\n<p><span style=\"color: #ff6600;\"><strong>For Transmission<\/strong><\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">HAL_SPI_Transmit(SPI_HandleTypeDef * hspi, uint8_t * pData, uint16_t Size, uint32_t Timeout);<\/pre>\n<p><span style=\"color: #ff6600;\"><strong>For Reception<\/strong><\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">HAL_SPI_Receive(SPI_HandleTypeDef * hspi, uint8_t * pData, uint16_t Size, uint32_t Timeout);<\/pre>\n<p><span style=\"color: #ff6600;\"><strong>For Transmit-Receive<\/strong><\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">HAL_SPI_TransmitReceive(SPI_HandleTypeDef * hspi, uint8_t * pTxData, uint8_t * pRxData, uint16_t Size, uint32_t Timeout);\r\n<\/pre>\n<h4><span style=\"color: #000000;\"><strong>2.\u00a0 STM32 SPI Interrupt Mode HAL Functions<\/strong><\/span><\/h4>\n<p><span style=\"color: #ff6600;\"><strong>For Transmission<\/strong><\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">HAL_SPI_Transmit_IT(SPI_HandleTypeDef * hspi, uint8_t * pData, uint16_t Size);<\/pre>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">After calling the above function, the SPI peripheral will start sending all the data bytes in the buffer one by one until it&#8217;s done. When it&#8217;s done this function below will be called and executed, if you&#8217;d like to do something upon data transmission completion, then add that to your code in the application source file (main.c).<\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef * hspi)\r\n{\r\n    \/\/ TX Done .. Do Something ...\r\n}<\/pre>\n<p><span style=\"color: #ff6600;\"><strong>For Reception<\/strong><\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">HAL_SPI_Receive_IT(SPI_HandleTypeDef * hspi, uint8_t * pData, uint16_t Size);<\/pre>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">After calling the above function, the SPI peripheral will start receiving all the incoming data bytes in the buffer one by one until it&#8217;s done. When it&#8217;s done this function below will be called and executed, if you&#8217;d like to do something upon data reception completion, then add that to your code in the application source file (main.c).<\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef * hspi)\r\n{\r\n    \/\/ RX Done .. Do Something ...\r\n}<\/pre>\n<p><span style=\"color: #ff6600;\"><strong>For Transmit-Receive<\/strong><\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef * hspi, uint8_t * pTxData, uint8_t * pRxData, uint16_t Size);\r\n<\/pre>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">After calling the above function, the SPI peripheral will start sending-receiving all the incoming data bytes in the buffers one by one until it&#8217;s done. When it&#8217;s done this function below will be called and executed, if you&#8217;d like to do something upon data transmission-reception completion, then add that to your code in the application source file (main.c).<\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef * hspi)\r\n{\r\n    \/\/ TX-RX Done .. Do Something ...\r\n}<\/pre>\n<h4><span style=\"color: #000000;\"><strong>3.\u00a0 STM32 SPI DMA Mode HAL Functions<\/strong><\/span><\/h4>\n<p><span style=\"color: #ff6600;\"><strong>For Transmission<\/strong><\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">HAL_SPI_Transmit_DMA(SPI_HandleTypeDef * hspi, uint8_t * pData, uint16_t Size);<\/pre>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">After calling the above function, the SPI peripheral will start sending all the data bytes in the buffer one by one until it&#8217;s done (in DMA Mode). When it&#8217;s done this function below will be called and executed, if you&#8217;d like to do something upon data transmission completion, then add that to your code in the application source file (main.c).<\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef * hspi)\r\n{\r\n    \/\/ TX Done .. Do Something ...\r\n}<\/pre>\n<p><span style=\"color: #ff6600;\"><strong>For Reception<\/strong><\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">HAL_SPI_Receive_DMA(SPI_HandleTypeDef * hspi, uint8_t * pData, uint16_t Size);<\/pre>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">After calling the above function, the SPI peripheral will start receiving all the incoming data bytes in the buffer one by one until it&#8217;s done (in DMA Mode). When it&#8217;s done this function below will be called and executed, if you&#8217;d like to do something upon data reception completion, then add that to your code in the application source file (main.c).<\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef * hspi)\r\n{\r\n    \/\/ RX Done .. Do Something ...\r\n}<\/pre>\n<p><span style=\"color: #ff6600;\"><strong>For Transmit-Receive<\/strong><\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef * hspi, uint8_t * pTxData, uint8_t * pRxData, uint16_t Size);\r\n<\/pre>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">After calling the above function, the SPI peripheral will start sending-receiving all the incoming data bytes in the buffers one by one until it&#8217;s done (in DMA Mode). When it&#8217;s done this function below will be called and executed, if you&#8217;d like to do something upon data transmission-reception completion, then add that to your code in the application source file (main.c).<\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef * hspi)\r\n{\r\n    \/\/ TX-RX Done .. Do Something ...\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<hr \/>\n<p><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The SPI Communication Bus Demonstrated in This Tutorial Will Be Used In The Following Next Tutorials:<\/span><\/p>\n<ul>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">MCU &#8211; MCU Communication Over SPI<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">External Serial SPI FLASH<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">SD Card Interfacing<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Dot Matrix Display<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">nRF24L01 Driver Library<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">and more&#8230;<\/span><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p style=\"text-align: center;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">That&#8217;s it for this tutorial. If you&#8217;d like to see the practical LAB examples for SPI and other interfacing projects and libraries we&#8217;ll build using this peripheral, just keep progressing through this series of tutorials and click to the next tutorial link down below.<\/span><\/p>\n<hr \/>\n<p><span style=\"color: #000000;\"><strong>Did you find this helpful? If yes, please consider<span style=\"color: #3366ff;\">\u00a0<a style=\"color: #3366ff;\" href=\"https:\/\/www.patreon.com\/deep_blue\" target=\"_blank\" rel=\"noopener\">supporting this work<\/a>\u00a0<\/span>and sharing these tutorials!<\/strong><\/span><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: center;\"><span style=\"color: #000080;\"><strong>Stay tuned for the upcoming tutorials and don\u2019t forget to<span style=\"color: #ff6600;\">\u00a0SHARE<\/span>\u00a0these tutorials. And consider\u00a0<span style=\"color: #ff6600;\"><a style=\"color: #ff6600;\" href=\"https:\/\/www.patreon.com\/deep_blue\" target=\"_blank\" rel=\"noopener noreferrer\">SUPPORTING<\/a><\/span>\u00a0this work to keep publishing free content just like this!<\/strong><\/span><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<table style=\"border-collapse: collapse; width: 100%;\" border=\"1\">\n<tbody>\n<tr>\n<td style=\"background-color: #ffffff; width: 5%;\"><a href=\"https:\/\/deepbluembedded.com\/stm32-hc-05-bluetooth-module-examples\/\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1666 alignleft\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L-150x150.png\" alt=\"Previous Tutorial\" width=\"35\" height=\"35\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L-150x150.png 150w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L-160x160.png 160w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L-320x320.png 320w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L-50x50.png 50w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L.png 256w\" sizes=\"auto, (max-width: 35px) 100vw, 35px\" \/><\/a><\/td>\n<td style=\"background-color: #ffffff; width: 30%; text-align: left;\" colspan=\"2\"><a href=\"https:\/\/deepbluembedded.com\/stm32-hc-05-bluetooth-module-examples\/\"><strong>Previous Tutorial<\/strong><\/a><\/td>\n<td style=\"background-color: #ffffff; width: 30%; text-align: center;\" colspan=\"2\"><span style=\"color: #000000;\"><strong><span style=\"font-size: 14pt;\">Tutorial 41<\/span><\/strong><\/span><\/td>\n<td style=\"background-color: #ffffff; width: 30%; text-align: right;\" colspan=\"2\"><a href=\"https:\/\/deepbluembedded.com\/how-to-receive-spi-with-stm32-dma-interrupt\/\"><strong>Next Tutorial<\/strong><\/a><\/td>\n<td style=\"background-color: #ffffff; width: 5%;\"><a href=\"https:\/\/deepbluembedded.com\/how-to-receive-spi-with-stm32-dma-interrupt\/\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1667 alignright\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256-150x150.png\" alt=\"Next Tutorial\" width=\"35\" height=\"35\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256-150x150.png 150w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256-160x160.png 160w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256-320x320.png 320w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256-50x50.png 50w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256.png 256w\" sizes=\"auto, (max-width: 35px) 100vw, 35px\" \/><\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p> &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"STM32 SPI Tutorial\" class=\"read-more button\" href=\"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/#more-5849\" aria-label=\"Read more about STM32 SPI Tutorial\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":5871,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[28,30,103],"tags":[322],"class_list":["post-5849","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-embedded-systems","category-embedded-tutorials","category-stm32-arm","tag-stm32-serial-communication","generate-columns","tablet-grid-50","mobile-grid-100","grid-parent","grid-33","no-featured-image-padding"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>STM32 SPI Tutorial - HAL Code Examples - Interrupt \/ DMA &#8211; DeepBlue<\/title>\n<meta name=\"description\" content=\"STM32 SPI Tutorial. STM32 SPI Example Code Using HAL CubeMX. SPI Mode Numbers, Daisy Chain. Read STM32 SPI with interrupts or DMA.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"STM32 SPI Tutorial - HAL Code Examples - Interrupt \/ DMA &#8211; DeepBlue\" \/>\n<meta property=\"og:description\" content=\"STM32 SPI Tutorial. STM32 SPI Example Code Using HAL CubeMX. SPI Mode Numbers, Daisy Chain. Read STM32 SPI with interrupts or DMA.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/\" \/>\n<meta property=\"og:site_name\" content=\"DeepBlue\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/khaled.elrawy.359\/\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/khaled.elrawy.359\/\" \/>\n<meta property=\"article:published_time\" content=\"2021-03-28T01:11:48+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-20T22:50:31+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Guide.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"720\" \/>\n\t<meta property=\"og:image:height\" content=\"340\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Khaled Magdy\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Khaled Magdy\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"20 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/stm32-spi-tutorial\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/stm32-spi-tutorial\\\/\"},\"author\":{\"name\":\"Khaled Magdy\",\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/#\\\/schema\\\/person\\\/30259d66cf68c6c681562dbe551b7867\"},\"headline\":\"STM32 SPI Tutorial\",\"datePublished\":\"2021-03-28T01:11:48+00:00\",\"dateModified\":\"2024-01-20T22:50:31+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/stm32-spi-tutorial\\\/\"},\"wordCount\":3646,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/#\\\/schema\\\/person\\\/30259d66cf68c6c681562dbe551b7867\"},\"image\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/stm32-spi-tutorial\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/deepbluembedded.com\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Guide.jpg\",\"keywords\":[\"STM32 Serial Communication\"],\"articleSection\":[\"Embedded Systems\",\"Embedded Tutorials\",\"STM32 ARM\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/deepbluembedded.com\\\/stm32-spi-tutorial\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/stm32-spi-tutorial\\\/\",\"url\":\"https:\\\/\\\/deepbluembedded.com\\\/stm32-spi-tutorial\\\/\",\"name\":\"STM32 SPI Tutorial - HAL Code Examples - Interrupt \\\/ DMA &#8211; DeepBlue\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/stm32-spi-tutorial\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/stm32-spi-tutorial\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/deepbluembedded.com\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Guide.jpg\",\"datePublished\":\"2021-03-28T01:11:48+00:00\",\"dateModified\":\"2024-01-20T22:50:31+00:00\",\"description\":\"STM32 SPI Tutorial. STM32 SPI Example Code Using HAL CubeMX. SPI Mode Numbers, Daisy Chain. Read STM32 SPI with interrupts or DMA.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/stm32-spi-tutorial\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/deepbluembedded.com\\\/stm32-spi-tutorial\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/stm32-spi-tutorial\\\/#primaryimage\",\"url\":\"https:\\\/\\\/deepbluembedded.com\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Guide.jpg\",\"contentUrl\":\"https:\\\/\\\/deepbluembedded.com\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Guide.jpg\",\"width\":720,\"height\":340,\"caption\":\"STM32 SPI Tutorial - Interrupt DMA Polling - SPI HAL Example Code Guide\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/stm32-spi-tutorial\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/deepbluembedded.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"STM32 SPI Tutorial\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/#website\",\"url\":\"https:\\\/\\\/deepbluembedded.com\\\/\",\"name\":\"DeepBlueMbedded\",\"description\":\"Embedded Systems And Computer Engineering Tutorials &amp; Articles\",\"publisher\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/#\\\/schema\\\/person\\\/30259d66cf68c6c681562dbe551b7867\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/deepbluembedded.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/#\\\/schema\\\/person\\\/30259d66cf68c6c681562dbe551b7867\",\"name\":\"Khaled Magdy\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g\",\"caption\":\"Khaled Magdy\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g\"},\"description\":\"Principal Embedded Systems Engineer with years of experience in embedded software and hardware design. I work in the Automotive &amp; e-Mobility industry. However, I still do Hardware design and SW development for DSP, Control Systems, Robotics, AI\\\/ML, and other fields I'm passionate about. I love reading, writing, creating projects, and teaching. A reader by day and a writer by night, it's my lifestyle. I believe that the combination of brilliant minds, bold ideas, and a complete disregard for what is possible, can and will change the world! I will be there when it happens, will you?\",\"sameAs\":[\"https:\\\/\\\/deepbluembedded.com\",\"https:\\\/\\\/www.facebook.com\\\/khaled.elrawy.359\\\/\",\"https:\\\/\\\/www.instagram.com\\\/deepbluembedded\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/khaled-magdy-\\\/\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCzLSrNZD4rCjSCOVU9hknvA\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"STM32 SPI Tutorial - HAL Code Examples - Interrupt \/ DMA &#8211; DeepBlue","description":"STM32 SPI Tutorial. STM32 SPI Example Code Using HAL CubeMX. SPI Mode Numbers, Daisy Chain. Read STM32 SPI with interrupts or DMA.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/","og_locale":"en_US","og_type":"article","og_title":"STM32 SPI Tutorial - HAL Code Examples - Interrupt \/ DMA &#8211; DeepBlue","og_description":"STM32 SPI Tutorial. STM32 SPI Example Code Using HAL CubeMX. SPI Mode Numbers, Daisy Chain. Read STM32 SPI with interrupts or DMA.","og_url":"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/","og_site_name":"DeepBlue","article_publisher":"https:\/\/www.facebook.com\/khaled.elrawy.359\/","article_author":"https:\/\/www.facebook.com\/khaled.elrawy.359\/","article_published_time":"2021-03-28T01:11:48+00:00","article_modified_time":"2024-01-20T22:50:31+00:00","og_image":[{"width":720,"height":340,"url":"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Guide.jpg","type":"image\/jpeg"}],"author":"Khaled Magdy","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Khaled Magdy","Est. reading time":"20 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/#article","isPartOf":{"@id":"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/"},"author":{"name":"Khaled Magdy","@id":"https:\/\/deepbluembedded.com\/#\/schema\/person\/30259d66cf68c6c681562dbe551b7867"},"headline":"STM32 SPI Tutorial","datePublished":"2021-03-28T01:11:48+00:00","dateModified":"2024-01-20T22:50:31+00:00","mainEntityOfPage":{"@id":"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/"},"wordCount":3646,"commentCount":1,"publisher":{"@id":"https:\/\/deepbluembedded.com\/#\/schema\/person\/30259d66cf68c6c681562dbe551b7867"},"image":{"@id":"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Guide.jpg","keywords":["STM32 Serial Communication"],"articleSection":["Embedded Systems","Embedded Tutorials","STM32 ARM"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/","url":"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/","name":"STM32 SPI Tutorial - HAL Code Examples - Interrupt \/ DMA &#8211; DeepBlue","isPartOf":{"@id":"https:\/\/deepbluembedded.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/#primaryimage"},"image":{"@id":"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Guide.jpg","datePublished":"2021-03-28T01:11:48+00:00","dateModified":"2024-01-20T22:50:31+00:00","description":"STM32 SPI Tutorial. STM32 SPI Example Code Using HAL CubeMX. SPI Mode Numbers, Daisy Chain. Read STM32 SPI with interrupts or DMA.","breadcrumb":{"@id":"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/#primaryimage","url":"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Guide.jpg","contentUrl":"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Guide.jpg","width":720,"height":340,"caption":"STM32 SPI Tutorial - Interrupt DMA Polling - SPI HAL Example Code Guide"},{"@type":"BreadcrumbList","@id":"https:\/\/deepbluembedded.com\/stm32-spi-tutorial\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/deepbluembedded.com\/"},{"@type":"ListItem","position":2,"name":"STM32 SPI Tutorial"}]},{"@type":"WebSite","@id":"https:\/\/deepbluembedded.com\/#website","url":"https:\/\/deepbluembedded.com\/","name":"DeepBlueMbedded","description":"Embedded Systems And Computer Engineering Tutorials &amp; Articles","publisher":{"@id":"https:\/\/deepbluembedded.com\/#\/schema\/person\/30259d66cf68c6c681562dbe551b7867"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/deepbluembedded.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/deepbluembedded.com\/#\/schema\/person\/30259d66cf68c6c681562dbe551b7867","name":"Khaled Magdy","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g","caption":"Khaled Magdy"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g"},"description":"Principal Embedded Systems Engineer with years of experience in embedded software and hardware design. I work in the Automotive &amp; e-Mobility industry. However, I still do Hardware design and SW development for DSP, Control Systems, Robotics, AI\/ML, and other fields I'm passionate about. I love reading, writing, creating projects, and teaching. A reader by day and a writer by night, it's my lifestyle. I believe that the combination of brilliant minds, bold ideas, and a complete disregard for what is possible, can and will change the world! I will be there when it happens, will you?","sameAs":["https:\/\/deepbluembedded.com","https:\/\/www.facebook.com\/khaled.elrawy.359\/","https:\/\/www.instagram.com\/deepbluembedded\/","https:\/\/www.linkedin.com\/in\/khaled-magdy-\/","https:\/\/www.youtube.com\/channel\/UCzLSrNZD4rCjSCOVU9hknvA"]}]}},"jetpack_featured_media_url":"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Guide.jpg","jetpack_shortlink":"https:\/\/wp.me\/p9SirL-1wl","jetpack-related-posts":[{"id":4203,"url":"https:\/\/deepbluembedded.com\/stm32-ecosystem-development-environment-setup\/","url_meta":{"origin":5849,"position":0},"title":"STM32 EcoSystem (Development Environment) Setup","author":"Khaled Magdy","date":"June 2, 2020","format":false,"excerpt":"Previous Tutorial Tutorial 0 Next Tutorial Setting-Up STM32 Ecosystem STM32 Course Home Page ???? \u00a0 At the beginning of this series of tutorials, we'll set up the development environment which we'll be using throughout the entire course tutorials, LABs, and projects. In this short tutorial, I'll list down the required\u2026","rel":"","context":"In &quot;Embedded Systems&quot;","block_context":{"text":"Embedded Systems","link":"https:\/\/deepbluembedded.com\/embedded-systems\/"},"img":{"alt_text":"Setting-Up Dev Env Thumbnail","src":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2020\/05\/Setting-Up-Dev-Env-Thumbnail.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2020\/05\/Setting-Up-Dev-Env-Thumbnail.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2020\/05\/Setting-Up-Dev-Env-Thumbnail.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2020\/05\/Setting-Up-Dev-Env-Thumbnail.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":6769,"url":"https:\/\/deepbluembedded.com\/stm32-i2c-scanner-hal-code-example\/","url_meta":{"origin":5849,"position":1},"title":"STM32 I2C Scanner HAL Code Example","author":"Khaled Magdy","date":"April 17, 2021","format":false,"excerpt":"Previous Tutorial Tutorial 45 Next Tutorial STM32 I2C Scanner Example STM32 Course Home Page ???? In this short tutorial, we'll be creating an STM32 I2C Scanner example project. To check for the connected slave devices on the I2C bus and report their addresses over UART to our PC. The I2C\u2026","rel":"","context":"In &quot;Embedded Systems&quot;","block_context":{"text":"Embedded Systems","link":"https:\/\/deepbluembedded.com\/embedded-systems\/"},"img":{"alt_text":"STM32 I2C Scanner HAL Example Code","src":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2021\/04\/STM32-I2C-Scanner-HAL-Example-Code.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2021\/04\/STM32-I2C-Scanner-HAL-Example-Code.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2021\/04\/STM32-I2C-Scanner-HAL-Example-Code.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2021\/04\/STM32-I2C-Scanner-HAL-Example-Code.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2021\/04\/STM32-I2C-Scanner-HAL-Example-Code.jpg?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":4263,"url":"https:\/\/deepbluembedded.com\/stm32-hal-library-tutorial-examples\/","url_meta":{"origin":5849,"position":2},"title":"STM32 HAL Library Tutorial","author":"Khaled Magdy","date":"June 2, 2020","format":false,"excerpt":"Previous Tutorial Tutorial 2 Next Tutorial STM32 HAL Library STM32 Course Home Page ???? \u00a0 STMCube\u00ae is STMicroelectronics's original initiative to ease and accelerate the development cycle of embedded products. STM32Cube covers the STM32 portfolio of microcontrollers. It provides the developer with all the low-level drivers, APIs, and enables him\/her\u2026","rel":"","context":"In &quot;Embedded Systems&quot;","block_context":{"text":"Embedded Systems","link":"https:\/\/deepbluembedded.com\/embedded-systems\/"},"img":{"alt_text":"STM32 HAL Library","src":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2020\/06\/STM32-HAL-Library.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2020\/06\/STM32-HAL-Library.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2020\/06\/STM32-HAL-Library.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2020\/06\/STM32-HAL-Library.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":4512,"url":"https:\/\/deepbluembedded.com\/stm32-serial-port-uart-with-usb-ttl-converter-pc-interfacing\/","url_meta":{"origin":5849,"position":3},"title":"STM32 Serial Communication With PC (STM32 UART To USB)","author":"Khaled Magdy","date":"June 17, 2020","format":false,"excerpt":"In this tutorial, we'll create an STM32 Serial Communication With PC example project. Using an STM32 With UART To USB TLL converter chip to send serial data from the STM32 microcontroller to the PC over UART. Without further ado, let's get right into it! STM32 Serial Communication With PC Example\u2026","rel":"","context":"In &quot;Embedded Systems&quot;","block_context":{"text":"Embedded Systems","link":"https:\/\/deepbluembedded.com\/embedded-systems\/"},"img":{"alt_text":"STM32-UART-USB-TTL-Converter","src":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2024\/04\/STM32-UART-USB-TTL-Converter.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2024\/04\/STM32-UART-USB-TTL-Converter.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2024\/04\/STM32-UART-USB-TTL-Converter.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2024\/04\/STM32-UART-USB-TTL-Converter.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2024\/04\/STM32-UART-USB-TTL-Converter.jpg?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":12655,"url":"https:\/\/deepbluembedded.com\/stm32-sdmmc-tutorial-examples-dma\/","url_meta":{"origin":5849,"position":4},"title":"STM32 SDMMC Tutorial With Examples + DMA","author":"Khaled Magdy","date":"April 6, 2024","format":false,"excerpt":"This is a comprehensive guide for STM32 SDMMC SD Card Interfacing With FatFS Library. You'll learn how to use SD Cards with STM32 microcontrollers using the SDMMC interface. We'll create some STM32 SD Card Example Test Projects to verify what we'll learn in this tutorial. STM32 SDMMC Some STM32 microcontroller\u2026","rel":"","context":"In &quot;Embedded Systems&quot;","block_context":{"text":"Embedded Systems","link":"https:\/\/deepbluembedded.com\/embedded-systems\/"},"img":{"alt_text":"STM32 SDMMC Tutorial With Example + DMA","src":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2024\/04\/STM32-SDMMC-Tutorial-With-Example-DMA.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2024\/04\/STM32-SDMMC-Tutorial-With-Example-DMA.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2024\/04\/STM32-SDMMC-Tutorial-With-Example-DMA.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2024\/04\/STM32-SDMMC-Tutorial-With-Example-DMA.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2024\/04\/STM32-SDMMC-Tutorial-With-Example-DMA.jpg?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":5877,"url":"https:\/\/deepbluembedded.com\/how-to-receive-spi-with-stm32-dma-interrupt\/","url_meta":{"origin":5849,"position":5},"title":"How To Receive SPI Data With STM32 DMA \/ Interrupt \/ Polling Modes","author":"Khaled Magdy","date":"March 30, 2021","format":false,"excerpt":"Previous Tutorial Tutorial 42 Next Tutorial How To Receive SPI Data With STM32 (DMA-Interrupt-Polling) Modes STM32 Course Home Page ???? In this tutorial, we'll discuss how to and receive SPI data with STM32 microcontrollers in DMA, Interrupt, and Polling modes. Starting with the SPI Master (Transmitter) firmware project, then I'll\u2026","rel":"","context":"In &quot;Embedded Systems&quot;","block_context":{"text":"Embedded Systems","link":"https:\/\/deepbluembedded.com\/embedded-systems\/"},"img":{"alt_text":"STM32 SPI Tutorial - Interrupt DMA Polling - SPI HAL Example Code Projects","src":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Projects.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Projects.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Projects.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2021\/03\/STM32-SPI-Tutorial-Interrupt-DMA-Polling-SPI-HAL-Example-Code-Projects.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/posts\/5849","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/comments?post=5849"}],"version-history":[{"count":12,"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/posts\/5849\/revisions"}],"predecessor-version":[{"id":5906,"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/posts\/5849\/revisions\/5906"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/media\/5871"}],"wp:attachment":[{"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/media?parent=5849"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/categories?post=5849"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/tags?post=5849"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}