{"id":2537,"date":"2024-05-24T05:37:20","date_gmt":"2024-05-24T05:37:20","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=2537"},"modified":"2024-05-24T05:37:23","modified_gmt":"2024-05-24T05:37:23","slug":"getting-started-with-stm32g0-and-stm32cubeide-spi-full-duplex","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=2537","title":{"rendered":"Getting Started with STM32G0 and STM32CubeIDE: SPI Full Duplex"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"400\" height=\"400\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/pt156578902-100_original_arm_mcu_stm32g070kbt6_stm32g070_stm32g_lqfp_32_microcontroller.jpg-2-4-2-1.webp\" alt=\"\" class=\"wp-image-2538\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/pt156578902-100_original_arm_mcu_stm32g070kbt6_stm32g070_stm32g_lqfp_32_microcontroller.jpg-2-4-2-1.webp 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/pt156578902-100_original_arm_mcu_stm32g070kbt6_stm32g070_stm32g_lqfp_32_microcontroller.jpg-2-4-2-1-300x300.webp 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/pt156578902-100_original_arm_mcu_stm32g070kbt6_stm32g070_stm32g_lqfp_32_microcontroller.jpg-2-4-2-1-150x150.webp 150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/pt156578902-100_original_arm_mcu_stm32g070kbt6_stm32g070_stm32g_lqfp_32_microcontroller.jpg-2-4-2-1-250x250.webp 250w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/figure>\n\n\n\n<p>In this guide, we shall configure the SPI of the STM32G070 to communicate with a slave device (MPU9250 in this case) and get the acceleration and gyroscope data.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>What is SPI.<\/li><li>SPI Configuration.<\/li><li>MPU9250 Source and header file.<\/li><li>Main source code.<\/li><li>MPU9250 Connection.<\/li><li>Results.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. What is SPI:<\/h2>\n\n\n\n<p><\/p>\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<figure class=\"wp-block-image\"><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>\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<figure class=\"wp-block-image\"><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>\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.&nbsp; For modes 0 and 1, the clock is low in idle, which is referred to&nbsp; as clock and 0,&nbsp; For modes 2 and 3 then the clock is in high state when idle, so it has&nbsp; polarity&nbsp; , one , For modes 0 and 2, the data will be sampled by the receiving device&nbsp; on the leading edge of a clock signal.&nbsp; 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&nbsp; idle state.&nbsp; And this translates to a following edge for mode 1 and the rising edge for mode 3.&nbsp; 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<figure class=\"wp-block-image\"><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>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. SPI Configuration:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>We start off by creating new project with name of SPI_Full_Duplex. For how to create new project from scratch, please refer to <a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=2299\" target=\"_blank\">this guide<\/a>.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Then from pinout and configuration:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"569\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-52-25-1024x569.jpg\" alt=\"\" class=\"wp-image-2539\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-52-25-1024x569.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-52-25-300x167.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-52-25-768x427.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-52-25-1536x854.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-52-25-2048x1139.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-52-25-1150x639.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-52-25-750x417.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-52-25-400x222.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-52-25-250x139.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Select PA5, PA6 and PA7 for SPI1 as shown in the picture.<\/p>\n\n\n\n<p>From connectivity, enable SPI1 to be full duplex Master mode.<\/p>\n\n\n\n<p>Set the data size to  8-bit.<\/p>\n\n\n\n<p>Next, set PA0 as GPIO to act as CS line as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"586\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-53-34-1024x586.jpg\" alt=\"\" class=\"wp-image-2540\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-53-34-1024x586.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-53-34-300x172.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-53-34-768x439.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-53-34-1536x879.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-53-34-2048x1172.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-53-34-1150x658.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-53-34-750x429.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-53-34-400x229.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_06-53-34-250x143.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Also, enable UART, for more details, please refer to <a href=\"https:\/\/blog.embeddedexpert.io\/?p=2316\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=2316\" target=\"_blank\" rel=\"noreferrer noopener\">this guide<\/a>.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Save the project and this should generate the code.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. MPU9250 source and header file modification:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Before modification, please refer to <a href=\"https:\/\/blog.embeddedexpert.io\/?p=1743\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1743\" target=\"_blank\" rel=\"noreferrer noopener\">this guide<\/a> for MPU9250.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>header file:<\/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 __MPU9250__H__\n#define __MPU9250__H__\n\n#include &quot;stdint.h&quot;\n\n#define Pi 3.14159\n#define MPU9250_ADDRESS_AD0_LOW  0x68\n#define MPU9250_ADDRESS_AD0_HIGH 0x69\n\n#define ACC_FULL_SCALE_2_G       0x00\n#define ACC_FULL_SCALE_4_G       0x08\n#define ACC_FULL_SCALE_8_G       0x10\n#define ACC_FULL_SCALE_16_G      0x18\n\n#define GYRO_FULL_SCALE_250_DPS  0x00\n#define GYRO_FULL_SCALE_500_DPS  0x08\n#define GYRO_FULL_SCALE_1000_DPS 0x10\n#define GYRO_FULL_SCALE_2000_DPS 0x18\n\n#define MAG_MODE_POWERDOWN        0x0\n#define MAG_MODE_SINGLE           0x1\n#define MAG_MODE_CONTINUOUS_8HZ   0x2\n#define MAG_MODE_EXTERNAL         0x4\n#define MAG_MODE_CONTINUOUS_100HZ 0x6\n#define MAG_MODE_SELFTEST         0x8\n#define MAG_MODE_FUSEROM          0xF\n#define AK8963_ADDRESS  0x0C\n#define AK8963_RA_HXL   0x03\n#define AK8963_RA_CNTL1 0x0A\n#define AK8963_RA_ASAX  0x10\n\n#define MPU9250_ADDR_ACCELCONFIG  0x1C\n#define MPU9250_ADDR_INT_PIN_CFG  0x37\n#define MPU9250_ADDR_ACCEL_XOUT_H 0x3B\n#define MPU9250_ADDR_GYRO_XOUT_H  0x43\n#define MPU9250_ADDR_PWR_MGMT_1   0x6B\n#define MPU9250_ADDR_WHOAMI       0x75\n#define address 0x68\n\/\/accelerartion part \nvoid MPU9250_beginAccel(uint8_t mode);\nfloat MPU9250_accelX(void);\nfloat MPU9250_accelY(void);\nfloat MPU9250_accelZ(void);\nuint8_t MPU9250_accelUpdate(void);\n\n\n\/\/gyro part\nvoid MPU9250_beginGyro(uint8_t mode);\nuint8_t MPU9250_gyroUpdate(void);\nfloat MPU9250_gyroX(void);\nfloat MPU9250_gyroY(void);\nfloat MPU9250_gyroZ(void);\n\n\n\n#endif<\/pre><\/div>\n\n\n\n<p>The modification as following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Remove the inclusion of delay header file.<\/li><\/ul>\n\n\n\n<p>Source code:<\/p>\n\n\n\n<p><\/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 &lt;math.h&gt;\n#include &quot;MPU9250.h&quot;\n#include &quot;main.h&quot;\n\n\n\ndouble accelRange,gyroRange;\nuint8_t magBuf[7], magXAdjust, magYAdjust, magZAdjust;\nuint8_t accelBuf[6],gyroBuf[6];\nuint8_t magBuf[7];\nint i;\nint16_t magXOffset, magYOffset, magZOffset;\n\n\n\nextern SPI_HandleTypeDef hspi1;\n\n\n#define READ_FLAG   0x80\n\n\n\/\/start Accelerometer\nvoid MPU9250_beginAccel(uint8_t mode) {\n  switch(mode) {\n  case ACC_FULL_SCALE_2_G:\n    accelRange = 2.0;\n    break;\n  case ACC_FULL_SCALE_4_G:\n    accelRange = 4.0;\n    break;\n  case ACC_FULL_SCALE_8_G:\n    accelRange = 8.0;\n    break;\n  case ACC_FULL_SCALE_16_G:\n    accelRange = 16.0;\n    break;\n  default:\n    return; \/\/ Return without writing invalid mode\n  }\n\n  uint8_t data[2]={MPU9250_ADDR_ACCELCONFIG,mode};\n  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_RESET);\n  HAL_SPI_Transmit(&amp;hspi1, data, 2, 100);\n  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_SET);\n\t\n}\n\n\/\/start gyroscope\nvoid MPU9250_beginGyro(uint8_t mode) {\n  \n  switch (mode) {\n  case GYRO_FULL_SCALE_250_DPS:\n    gyroRange = 250.0;\n    break;\n  case GYRO_FULL_SCALE_500_DPS:\n    gyroRange = 500.0;\n    break;\n  case GYRO_FULL_SCALE_1000_DPS:\n    gyroRange = 1000.0;\n    break;\n  case GYRO_FULL_SCALE_2000_DPS:\n    gyroRange = 2000.0;\n    break;\n  default:\n    return; \/\/ Return without writing invalid mode\n  }\n  uint8_t data[2]={27,mode};\n  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_RESET);\n  HAL_SPI_Transmit(&amp;hspi1, data, 2, 100);\n  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_SET);\n}\n\n\/\/start compass\n\n\n\n\nuint8_t MPU9250_accelUpdate(void)\n{\n\tuint8_t data=0x3B|READ_FLAG;\n\tHAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_RESET);\n\n\tHAL_SPI_Transmit(&amp;hspi1, &amp;data,1,100);\n\tHAL_SPI_Receive(&amp;hspi1, accelBuf, 6, 100);\n\n\tHAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_SET);\n\treturn 0;\n \n}\n\nfloat MPU9250_accelGet(uint8_t highIndex, uint8_t lowIndex) {\n  int16_t v = ((int16_t) accelBuf[highIndex]) &lt;&lt; 8 | accelBuf[lowIndex];\n  return ((float) -v) * accelRange \/ (float) 0x8000; \/\/ (float) 0x8000 == 32768.0\n}\n\nfloat MPU9250_accelSqrt(void) {\n  return sqrt(pow(MPU9250_accelGet(0, 1), 2) +\n              pow(MPU9250_accelGet(2, 3), 2) +\n              pow(MPU9250_accelGet(4, 5), 2));\n}\n\nfloat MPU9250_accelX(void) {\n  return MPU9250_accelGet(0, 1);\n}\n\nfloat MPU9250_accelY(void) {\n  return MPU9250_accelGet(2, 3);\n}\n\nfloat MPU9250_accelZ(void) {\n  return MPU9250_accelGet(4, 5);\n}\n\n\nuint8_t MPU9250_gyroUpdate(void)\n{\n\tuint8_t data=0x43|READ_FLAG;\n\n\tHAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_RESET);\n\n\tHAL_SPI_Transmit(&amp;hspi1, &amp;data,1,100);\n\tHAL_SPI_Receive(&amp;hspi1, gyroBuf, 6, 100);\n\n\tHAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_SET);\n\treturn 0;\n}\n\nfloat MPU9250_gyroGet(uint8_t highIndex, uint8_t lowIndex) {\n  int16_t v = ((int16_t) gyroBuf[highIndex]) &lt;&lt; 8 | gyroBuf[lowIndex];\n  return ((float) -v) * gyroRange \/ (float) 0x8000;\n}\n\nfloat MPU9250_gyroX(void) {\n  return MPU9250_gyroGet(0, 1);\n}\n\nfloat MPU9250_gyroY(void) {\n  return MPU9250_gyroGet(2, 3);\n}\n\nfloat MPU9250_gyroZ(void) {\n  return MPU9250_gyroGet(4, 5);\n}<\/pre><\/div>\n\n\n\n<p>The modification as following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Remove the inclusion of spi header file.<\/li><li>Include main.h header file<\/li><li>Declare this <strong>extern<\/strong> <strong>SPI_HandleTypeDef<\/strong> hspi1; to handle the SPI communication.<\/li><li>Replace cs_loe() with <strong>HAL_GPIO_WritePin<\/strong>(GPIOA, GPIO_PIN_0,<em>GPIO_PIN_RESET<\/em>);<\/li><li>Replace spi_transmit with <strong>HAL_SPI_Transmit<\/strong>(&amp;hspi1, data, 2, 100);<\/li><li>replace cs_high() with <strong>HAL_GPIO_WritePin<\/strong>(GPIOA, GPIO_PIN_0,<em>GPIO_PIN_SET<\/em>);<\/li><li>For the acceleration update function:<\/li><li> <\/li><\/ul>\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;}\">\tHAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_RESET);\n\n\tHAL_SPI_Transmit(&amp;hspi1, &amp;data,1,100);\n\tHAL_SPI_Receive(&amp;hspi1, accelBuf, 6, 100);\n\n\tHAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_SET);<\/pre><\/div>\n\n\n\n<p>For the gyroscope update 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;}\">uint8_t MPU9250_gyroUpdate(void)\n{\n\tuint8_t data=0x43|READ_FLAG;\n\n\tHAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_RESET);\n\n\tHAL_SPI_Transmit(&amp;hspi1, &amp;data,1,100);\n\tHAL_SPI_Receive(&amp;hspi1, gyroBuf, 6, 100);\n\n\tHAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_SET);\n\treturn 0;\n}<\/pre><\/div>\n\n\n\n<p>The rest shall remain the same.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Main source code:<\/h2>\n\n\n\n<p>In main c:<\/p>\n\n\n\n<p>In user code begin includes, 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;MPU9250.h&quot;\n#include &quot;stdio.h&quot;<\/pre><\/div>\n\n\n\n<p>In user code begin 0, declare 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;}\">int __io_putchar(int ch)\n{\n\tHAL_UART_Transmit(&amp;huart2, &amp;ch, 1, 10);\n\treturn ch;\n}<\/pre><\/div>\n\n\n\n<p>This will redirect the printf to use serial.<\/p>\n\n\n\n<p>In user code begin 2:<\/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;}\">  MPU9250_beginAccel(ACC_FULL_SCALE_16_G);\n  MPU9250_beginGyro(GYRO_FULL_SCALE_2000_DPS);<\/pre><\/div>\n\n\n\n<p>Initialize both the accelerometer and gyroscope.<\/p>\n\n\n\n<p>In code begin 3:<\/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\tMPU9250_accelUpdate();\n\t\tMPU9250_gyroUpdate();\n\t\tprintf(&quot;Acceleration data %0.3f %0.3f %0.3f \\r\\n&quot;,MPU9250_accelX(),(MPU9250_accelY()-(float)3.5),MPU9250_accelZ());\n\t\tprintf(&quot;Gyroscope data %0.3f %0.3f %0.3f \\r\\n&quot;,MPU9250_gyroX(),MPU9250_gyroY(),MPU9250_gyroZ());\n\t\tHAL_Delay(200);<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>In order to let printf prints float values, we need to enable it.<\/p>\n\n\n\n<p>Right click on the project and select properties then follow the following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"970\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_08-33-06-1024x970.jpg\" alt=\"\" class=\"wp-image-2541\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_08-33-06-1024x970.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_08-33-06-300x284.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_08-33-06-768x728.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_08-33-06-1536x1455.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_08-33-06-1150x1090.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_08-33-06-750x711.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_08-33-06-400x379.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_08-33-06-250x237.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/2024-05-24_08-33-06.jpg 1638w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Click on apply and close.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Connection:<\/h2>\n\n\n\n<p>The connection as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"774\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-1024x774.png\" alt=\"\" class=\"wp-image-2542\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-1024x774.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-300x227.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-768x581.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-1536x1161.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-1150x869.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-750x567.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-400x302.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1-250x189.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screen-Shot-2022-01-17-at-6.39.56-AM-2048x1548-1.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\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>Open your serial monitor application, select the COM port and set the baud to be 115200 and you should get the following:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"738\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screenshot-2024-05-24-at-7.59.23\u202fAM-1024x738.png\" alt=\"\" class=\"wp-image-2543\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screenshot-2024-05-24-at-7.59.23\u202fAM-1024x738.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screenshot-2024-05-24-at-7.59.23\u202fAM-300x216.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screenshot-2024-05-24-at-7.59.23\u202fAM-768x553.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screenshot-2024-05-24-at-7.59.23\u202fAM-1150x828.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screenshot-2024-05-24-at-7.59.23\u202fAM-750x540.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screenshot-2024-05-24-at-7.59.23\u202fAM-400x288.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screenshot-2024-05-24-at-7.59.23\u202fAM-250x180.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/05\/Screenshot-2024-05-24-at-7.59.23\u202fAM.png 1166w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Happy coding \ud83d\ude09 <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, we shall configure the SPI of the STM32G070 to communicate with a slave device (MPU9250 in this case) and get the acceleration and gyroscope data. In this guide, we shall cover the following: What is SPI. SPI Configuration. MPU9250 Source and header file. Main source code. MPU9250 Connection. Results. 1. What is [&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-2537","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\/2537"}],"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=2537"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2537\/revisions"}],"predecessor-version":[{"id":2544,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2537\/revisions\/2544"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2537"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2537"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2537"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}