{"id":1603,"date":"2023-03-01T05:31:28","date_gmt":"2023-03-01T05:31:28","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=1603"},"modified":"2023-03-01T05:31:32","modified_gmt":"2023-03-01T05:31:32","slug":"getting-started-with-stm32f103-spi-serial-peripheral-interface","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=1603","title":{"rendered":"Getting Started with STM32F103: SPI (Serial Peripheral Interface)"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/AdobeStock_122425803-1024x683.jpeg\" alt=\"\" class=\"wp-image-1604\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/AdobeStock_122425803-1024x683.jpeg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/AdobeStock_122425803-300x200.jpeg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/AdobeStock_122425803-768x512.jpeg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/AdobeStock_122425803-1536x1024.jpeg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/AdobeStock_122425803-2048x1365.jpeg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/AdobeStock_122425803-1150x767.jpeg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/AdobeStock_122425803-750x500.jpeg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/AdobeStock_122425803-400x267.jpeg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/AdobeStock_122425803-250x167.jpeg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In this guide, we shall discuss what is SPI and how transmit data over SPI.<\/p>\n\n\n\n<p>In this guide, we will cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>What is SPI.<\/li><li>SPI pin setup.<\/li><li>SPI initialize.<\/li><li>SPI transmite function.<\/li><li>Result.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1. What is SPI<\/h2>\n\n\n\n<p>SPI, which stands for Serial Peripheral Interface, is a standard with a very specific hardware interface. A connection is between a master and a slave, with the master typical being a processor, and the slave being a peripheral such as a sensor, flash memory device, or a modem chip.&nbsp;&nbsp; It can also be used for processor to processor communications, but in this case, an additional handshake signal is often used. There are normally four signals between a master and a slave, the first is a clock signal, and this signal is always driven by the master, regard which device is transmitting.&nbsp; The second line is a data line for data going from the master to the slave, and this is designated as the master output, slave input line, are MOSI for short. It connects the SPI data out connection on the master and to the SPI data in connection on the slave.<\/p>\n\n\n\n<p>The next conductor is for data in the opposite direction and is labelled as the master input slave output line, are MISO for short. The last conductor is slave select with the slave chip selecting input, and is active low.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/community.nxp.com\/t5\/image\/serverpage\/image-id\/1775i2B1DEDD6CA621B46\/image-size\/large?v=v2&amp;px=999\" alt=\"pastedImage_0.png\" title=\"pastedImage_0.png\" \/><\/figure><\/div>\n\n\n\n<p>If you have more than one slave, with the first being perhaps a sensor of some kind, the slave will be dedicated to slave 1. If you add a second sensor, the top 3 interface line will be shared, but it dedicates for slave\u2019s line will be required for the second device, and the same is true of course for each of additional slave device.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/community.nxp.com\/t5\/image\/serverpage\/image-id\/1823iA304AA7FB6E2C238\/image-size\/large?v=v2&amp;px=999\" alt=\"pastedImage_1.png\" title=\"pastedImage_1.png\" \/><\/figure><\/div>\n\n\n\n<p>Most processors have a maxim of 4 slave selected lines.&nbsp; The four lines could be used effectively as a multiplexed address lines to access more than 4 slaves. You cannot have more than one master on the bus,&nbsp;&nbsp; since the interface is not support coordination between two masters as to which one is controlling the bus.<\/p>\n\n\n\n<p>Transmissions are typically sent as a sequence of bytes, but without a formal protocol, there is nothing restricting communication being&nbsp;&nbsp; byte based. Typical by frame sizes, are in 8 to 32 bits range.&nbsp; Also note the bytes and packets are not acknowledged as they are in i2c, and you could have a master synching communicating with the slave but, you don\u2019t really know of your communications are being received OK. However, some slave devices will echo bytes sent to it, which provides an acknowledgement to the master.&nbsp; it is how the data lines are synchronized with a clock signal.<\/p>\n\n\n\n<p><strong>Clock Polarity and Phasing<\/strong><\/p>\n\n\n\n<p>There are four different modes available, one mode each combination clocking in a low state and high state, with a data being read in a rising edge or falling edge of the clock signal.\u00a0 For modes 0 and 1, the clock is low in idle, which is referred to\u00a0 as clock and 0,\u00a0 For modes 2 and 3 then the clock is in high state when idle, so it has\u00a0 polarity\u00a0 , one , For modes 0 and 2, the data will be sampled by the receiving device\u00a0 on the leading edge of a clock signal.\u00a0 Relative to the idle state, which is referred to a clock phase of zero. So for mode 0, this means the rising edge of the clock and for mode 2, means the following edge of the clock, the other two modes, use a clock phase 1 which means that trailing edge of clock as a returns to an\u00a0 idle state.\u00a0 And this translates to a following edge for mode 1 and the rising edge for mode 3.\u00a0 Mode 0 is the most commonly supported setting. If multiple slaves in the same bus, you may have to reconfigure the settings for the master to which modes when you want to communicate with a different slave.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/community.nxp.com\/t5\/image\/serverpage\/image-id\/1822i008127221D9DF901\/image-size\/large?v=v2&amp;px=999\" alt=\"pastedImage_2.png\" title=\"pastedImage_2.png\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. SPI pins Setup:<\/h2>\n\n\n\n<p>First, we need to find which pins are related to SPI. This can be found in SPI1 alternate function remapping section of the reference manual.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"269\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-7.55.36-AM-1024x269.png\" alt=\"\" class=\"wp-image-1605\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-7.55.36-AM-1024x269.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-7.55.36-AM-300x79.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-7.55.36-AM-768x202.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-7.55.36-AM-1536x403.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-7.55.36-AM-2048x537.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-7.55.36-AM-1150x302.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-7.55.36-AM-750x197.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-7.55.36-AM-400x105.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-7.55.36-AM-250x66.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Since we shall use software slave management, we shall not use NSS pin. Hence, the pins required are:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>PA5 for SCK<\/li><li>PA6 for MISO<\/li><li>PA7 for MOSI<\/li><\/ul>\n\n\n\n<p>The pins configuration as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"769\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.00.40-AM-1024x769.png\" alt=\"\" class=\"wp-image-1606\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.00.40-AM-1024x769.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.00.40-AM-300x225.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.00.40-AM-768x577.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.00.40-AM-1536x1153.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.00.40-AM-2048x1538.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.00.40-AM-1150x864.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.00.40-AM-750x563.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.00.40-AM-400x300.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.00.40-AM-250x188.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Hence, create a new source and header file with name of spi.c and spi.h respectively.<\/p>\n\n\n\n<p>Within the header file, include the following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;stdint.h&quot;<\/pre><\/div>\n\n\n\n<p>Declare the following functions:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void spi_init(void);\nvoid spi_transmit(uint8_t *data,uint32_t size);\nvoid cs_low();\nvoid cs_high();<\/pre><\/div>\n\n\n\n<p>Hence, the header file as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef SPI_H_\n#define SPI_H_\n\n#include &quot;stdint.h&quot;\n\n\nvoid spi_init(void);\nvoid spi_transmit(uint8_t *data,uint32_t size);\nvoid cs_low();\nvoid cs_high();\n\n\n\n#endif \/* SPI_H_ *\/\n<\/pre><\/div>\n\n\n\n<p>Within the source file, we start with <strong>spi_init<\/strong> function:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void spi_init(){<\/pre><\/div>\n\n\n\n<p>within the function, we shall configure both SPI and GPIO.<\/p>\n\n\n\n<p>For the GPIO:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t\/\/Enable Port A clock\n\tRCC-&gt;APB2ENR |= RCC_APB2ENR_IOPAEN;\n\tRCC-&gt;APB2ENR |= RCC_APB2ENR_AFIOEN;\n\t\/* PA5-SCK and PA7-MOSI *\/\n\t\/\/Mode: Output, Speed: 10MHz\n\tGPIOA-&gt;CRL &amp;= ~(GPIO_CRL_MODE5);\n\tGPIOA-&gt;CRL &amp;= ~(GPIO_CRL_MODE7);\n\tGPIOA-&gt;CRL |= (GPIO_CRL_MODE5_0);\n\tGPIOA-&gt;CRL |= (GPIO_CRL_MODE7_0);\n\t\/\/Alternate function push-pull\n\tGPIOA-&gt;CRL &amp;= ~(GPIO_CRL_CNF5);\n\tGPIOA-&gt;CRL &amp;= ~(GPIO_CRL_CNF7);\n\tGPIOA-&gt;CRL |= (GPIO_CRL_CNF5_1);\n\tGPIOA-&gt;CRL |= (GPIO_CRL_CNF7_1);\n\n\t\/* PA5-MISO *\/\n\t\/\/Mode input\n\tGPIOA-&gt;CRL &amp;= ~(GPIO_CRL_MODE6);\n\t\/\/Floating input\n\tGPIOA-&gt;CRL &amp;= ~(GPIO_CRL_CNF6);\n\tGPIOA-&gt;CRL |= (GPIO_CRL_CNF6_0);\n\n\t\/\/Remap 0: PA5, PA6, PA7\n\tAFIO-&gt;MAPR &amp;= ~(1UL &lt;&lt; 0);\n\t\n\t\/*Configure PA0 as output CS*\/\n\tGPIOA-&gt;CRL|=GPIO_CRL_MODE0;\n\tGPIOA-&gt;CRL&amp;=~(GPIO_CRL_CNF0);<\/pre><\/div>\n\n\n\n<p>Thats all for the GPIO.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. SPI initializing:<\/h2>\n\n\n\n<p>Before we start with the initializing the SPI, we need to enable clock access to SPI. From the datasheet, from the block diagram, we can find the SPI1 is connected to APB2 BUS:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"896\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.08.24-AM-1024x896.png\" alt=\"\" class=\"wp-image-1607\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.08.24-AM-1024x896.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.08.24-AM-300x263.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.08.24-AM-768x672.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.08.24-AM-1536x1344.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.08.24-AM-2048x1792.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.08.24-AM-1150x1006.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.08.24-AM-750x656.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.08.24-AM-400x350.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-01-at-8.08.24-AM-250x219.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>Hence, we can enable clock access to SPI as following:<\/figcaption><\/figure>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t\/\/Enable SPI Clock\n\tRCC-&gt;APB2ENR |= RCC_APB2ENR_SPI1EN;<\/pre><\/div>\n\n\n\n<p>Then we set the SPI<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Set SSM and SSI<br>Set SPI to master mode<\/li><li>Finally enable SPI module&nbsp;<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"275\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-03-at-8.12.43-AM-1024x275.png\" alt=\"\" class=\"wp-image-1068\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-03-at-8.12.43-AM-1024x275.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-03-at-8.12.43-AM-300x80.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-03-at-8.12.43-AM-768x206.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-03-at-8.12.43-AM-1536x412.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-03-at-8.12.43-AM-2048x549.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-03-at-8.12.43-AM-1150x308.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-03-at-8.12.43-AM-750x201.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-03-at-8.12.43-AM-400x107.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-03-at-8.12.43-AM-250x67.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t\/\/Mode: Master\n\tSPI1-&gt;CR1 |= SPI_CR1_MSTR;\n\t\/\/Baud rate to (8MHz \/ 2 = 4MHz)\n\tSPI1-&gt;CR1 &amp;= ~SPI_CR1_BR;\n\t\/\/MSB first\n\tSPI1-&gt;CR1 &amp;= ~(SPI_CR1_LSBFIRST);\n\t\/\/Full duplex (Transmit\/Receive)\n\tSPI1-&gt;CR1 &amp;= ~(SPI_CR1_RXONLY);\n\t\/\/Data format 8-bit\n\tSPI1-&gt;CR1 &amp;= ~(SPI_CR1_DFF);\n\t\/\/Software Slave select\n\tSPI1-&gt;CR1 |= SPI_CR1_SSI;\n\tSPI1-&gt;CR1 |= SPI_CR1_SSM;\n\t\/\/SPI Enable\n\tSPI1-&gt;CR1 |= SPI_CR1_SPE;\n\t\/\/Clear initial flags\n\t(void)SPI1-&gt;SR;<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">4. SPI transfer function:<\/h2>\n\n\n\n<p>We start off by declaring the following function:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void spi_transmit(uint8_t *data,uint32_t size)<\/pre><\/div>\n\n\n\n<p>The function takes the following two parameters:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>pointer to array that holds the data to be transmitted.<\/li><li>Length of the data.<\/li><\/ul>\n\n\n\n<p>Within the function, declare the following variable:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint32_t i=0;<\/pre><\/div>\n\n\n\n<p>Then:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\twhile(i&lt;size)\n\t{\n\t\t \/*Wait for the TXE bit to set in the Status Register*\/\n\t\t\/*This will indicate that the transmit buffer is empty*\/\n\t\t while (!((SPI1-&gt;SR)&amp;(1&lt;&lt;1))) {};\n\t\t   \/*Write the data to the Data Register*\/\n\t\t   SPI1-&gt;DR = data[i];\n\t\t   i++;\n\t}<\/pre><\/div>\n\n\n\n<p>We shall transmit the data one after the other as following:<\/p>\n\n\n\n<p>While the i is less than the size of the data, do the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Wait until TXE bit is set (indicates that TX buffer is empty).<\/li><li>Send the data by writing it to DR register.<\/li><li>increment the counter.<\/li><li>Do this until i is equal or bigger than size.<\/li><\/ul>\n\n\n\n<p>Outside the while loop:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\"> \/*Wait for the TXE bit to set in the Status Register*\/\n\t while (!((SPI1-&gt;SR)&amp;(1&lt;&lt;1))) {};\n\n\t \/*Wait for the BSY bit to reset in the Status Register*\/\n\t while (((SPI1-&gt;SR)&amp;(1&lt;&lt;7))) {};\n\n\t \/*Clear OVR flag*\/\n\t(void) SPI1-&gt;DR;\n\t(void) SPI1-&gt;SR;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>For chip select:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void cs_low()\n{\n\tGPIOA-&gt;BSRR=GPIO_BSRR_BR0;\n}\n\nvoid cs_high()\n{\n\tGPIOA-&gt;BSRR=GPIO_BSRR_BS0;\n}\n<\/pre><\/div>\n\n\n\n<p>Hence, the entire source code as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\/*\n * spi.c\n *\n *  Created on: Mar 1, 2023\n *      Author: hussamaldean\n *\/\n\n\n#include &quot;spi.h&quot;\n#include &quot;stm32f1xx.h&quot;\n\n\nvoid spi_init(void)\n{\n\t\/\/Enable Port A clock\n\tRCC-&gt;APB2ENR |= RCC_APB2ENR_IOPAEN;\n\tRCC-&gt;APB2ENR |= RCC_APB2ENR_AFIOEN;\n\t\/* PA5-SCK and PA7-MOSI *\/\n\t\/\/Mode: Output, Speed: 10MHz\n\tGPIOA-&gt;CRL &amp;= ~(GPIO_CRL_MODE5);\n\tGPIOA-&gt;CRL &amp;= ~(GPIO_CRL_MODE7);\n\tGPIOA-&gt;CRL |= (GPIO_CRL_MODE5_0);\n\tGPIOA-&gt;CRL |= (GPIO_CRL_MODE7_0);\n\t\/\/Alternate function push-pull\n\tGPIOA-&gt;CRL &amp;= ~(GPIO_CRL_CNF5);\n\tGPIOA-&gt;CRL &amp;= ~(GPIO_CRL_CNF7);\n\tGPIOA-&gt;CRL |= (GPIO_CRL_CNF5_1);\n\tGPIOA-&gt;CRL |= (GPIO_CRL_CNF7_1);\n\n\t\/* PA5-MISO *\/\n\t\/\/Mode input\n\tGPIOA-&gt;CRL &amp;= ~(GPIO_CRL_MODE6);\n\t\/\/Floating input\n\tGPIOA-&gt;CRL &amp;= ~(GPIO_CRL_CNF6);\n\tGPIOA-&gt;CRL |= (GPIO_CRL_CNF6_0);\n\n\t\/\/Remap 0: PA5, PA6, PA7\n\tAFIO-&gt;MAPR &amp;= ~(1UL &lt;&lt; 0);\n\t\n\t\/*Configure PA0 as output CS*\/\n\tGPIOA-&gt;CRL|=GPIO_CRL_MODE0;\n\tGPIOA-&gt;CRL&amp;=~(GPIO_CRL_CNF0);\n\t\n\n\t\/\/Enable SPI Clock\n\tRCC-&gt;APB2ENR |= RCC_APB2ENR_SPI1EN;\n\n\t\/\/Mode: Master\n\tSPI1-&gt;CR1 |= SPI_CR1_MSTR;\n\t\/\/Baud rate to (8MHz \/ 2 = 4MHz)\n\tSPI1-&gt;CR1 &amp;= ~SPI_CR1_BR;\n\t\/\/MSB first\n\tSPI1-&gt;CR1 &amp;= ~(SPI_CR1_LSBFIRST);\n\t\/\/Full duplex (Transmit\/Receive)\n\tSPI1-&gt;CR1 &amp;= ~(SPI_CR1_RXONLY);\n\t\/\/Data format 8-bit\n\tSPI1-&gt;CR1 &amp;= ~(SPI_CR1_DFF);\n\t\/\/Software Slave select\n\tSPI1-&gt;CR1 |= SPI_CR1_SSI;\n\tSPI1-&gt;CR1 |= SPI_CR1_SSM;\n\t\/\/SPI Enable\n\tSPI1-&gt;CR1 |= SPI_CR1_SPE;\n\t\/\/Clear initial flags\n\t(void)SPI1-&gt;SR;\n\n\n}\n\nvoid spi_transmit(uint8_t *data,uint32_t size)\n{\n\tuint32_t i=0;\n\n\twhile(i&lt;size)\n\t{\n\t\t \/*Wait for the TXE bit to set in the Status Register*\/\n\t\t\/*This will indicate that the transmit buffer is empty*\/\n\t\t while (!((SPI1-&gt;SR)&amp;(1&lt;&lt;1))) {};\n\t\t   \/*Write the data to the Data Register*\/\n\t\t   SPI1-&gt;DR = data[i];\n\t\t   i++;\n\t}\n\t \/*Wait for the TXE bit to set in the Status Register*\/\n\t while (!((SPI1-&gt;SR)&amp;(1&lt;&lt;1))) {};\n\n\t \/*Wait for the BSY bit to reset in the Status Register*\/\n\t while (((SPI1-&gt;SR)&amp;(1&lt;&lt;7))) {};\n\n\t \/*Clear OVR flag*\/\n\t(void) SPI1-&gt;DR;\n\t(void) SPI1-&gt;SR;\n}\n\n\nvoid cs_low()\n{\n\tGPIOA-&gt;BSRR=GPIO_BSRR_BR0;\n}\n\nvoid cs_high()\n{\n\tGPIOA-&gt;BSRR=GPIO_BSRR_BS0;\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Within main.c:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;spi.h&quot;\n\nuint8_t data[5]={0x01,0x02,0x03,0x04,0x05};\n\n\nint main(void)\n{\n\tspi_init();\n\n\twhile(1)\n\t{\tcs_low();\n\t\tspi_transmit(data, 5);\n\t\tcs_high();\n\t\tfor (int i=0;i&lt;10000;i++);\n\t}\n}\n<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">5. Code:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>You may download the source code from here:<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/SPI_TX.zip\">SPI_TX<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/03\/SPI_TX.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Results:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>When you connect logic analyzer to PA5, PA7 and PA0, you will get the following results:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"156\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-1024x156.png\" alt=\"\" class=\"wp-image-1069\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-1024x156.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-300x46.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-768x117.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-1536x234.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-2048x311.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-1150x175.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-750x114.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-400x61.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-02-at-4.36.43-PM-250x38.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Happy coding \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, we shall discuss what is SPI and how transmit data over SPI. In this guide, we will cover the following: What is SPI. SPI pin setup. SPI initialize. SPI transmite function. Result. 1. What is SPI SPI, which stands for Serial Peripheral Interface, is a standard with a very specific hardware interface. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,11,12],"tags":[],"class_list":["post-1603","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1603"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1603"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1603\/revisions"}],"predecessor-version":[{"id":1609,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1603\/revisions\/1609"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1603"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1603"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1603"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}