{"id":1493,"date":"2023-01-22T06:13:29","date_gmt":"2023-01-22T06:13:29","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=1493"},"modified":"2026-04-17T15:06:53","modified_gmt":"2026-04-17T15:06:53","slug":"getting-started-with-stm32f103-i2c-bus-scanner","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=1493","title":{"rendered":"Getting Started with STM32F103: I2C Bus Scanner"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/1200px-I%C2%B2C_bus_logo.svg_-273x300.png\" alt=\"\" class=\"wp-image-417\" \/><\/figure><\/div>\n\n\n\n<p>n this guide, we shall discuss what is I2C and how to make an i2c bus scanner to scan the slave devices that connected to the i2c1 bus of STM32F103<\/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 I2C<\/li><li>I2C setup for stm32f1<\/li><li>I2C bus scanner code.<\/li><li>Code<\/li><li>Results<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1.1: What is I2C<\/h2>\n\n\n\n<p>I2C or Inter Integrated Circuit is type of synchronous serial communication that capable to communicate with up to 127 slave devices as show in figure below.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"408\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/image-1024x408.png\" alt=\"\" class=\"wp-image-418\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/image-1024x408.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/image-300x119.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/image-768x306.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/image-750x299.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/image-400x159.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/image-250x100.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/image.png 1130w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Like UART communication, I2C only uses two wires to transmit data between devices:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>SDA (Serial Data): &nbsp;The line for the master and slave to send and receive data.&nbsp;<\/li><li>SCL (Serial Clock): The line&nbsp;that carries&nbsp;the clock signal.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1.2: HOW I2C&nbsp;WORKS<\/h2>\n\n\n\n<p>With I2C, data is transferred in&nbsp;<em>messages.&nbsp;<\/em>Messages are broken up into&nbsp;<em>frames<\/em>&nbsp;of data. Each&nbsp;message has an address frame that contains the binary address of the slave, and one or more data frames that contain the data being transmitted. The message also includes&nbsp;start and stop conditions, read\/write bits, and ACK\/NACK bits between each data frame:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.circuitbasics.com\/wp-content\/uploads\/2016\/01\/Introduction-to-I2C-Message-Frame-and-Bit-2.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" src=\"https:\/\/www.circuitbasics.com\/wp-content\/uploads\/2016\/01\/Introduction-to-I2C-Message-Frame-and-Bit-2-1024x258.png\" alt=\"Introduction to I2C - Message, Frame, and Bit\" class=\"wp-image-420891\" \/><\/a><\/figure>\n\n\n\n<p><strong>Start Condition:<\/strong>&nbsp;The SDA line switches from a high voltage&nbsp;level to a low voltage level&nbsp;<em>before<\/em>&nbsp;the SCL line switches from high to low.<\/p>\n\n\n\n<p><strong>Stop Condition:<\/strong>&nbsp;The SDA line switches from a low voltage&nbsp;level to a high voltage level&nbsp;<em>after<\/em>&nbsp;the SCL line switches from low to high.<\/p>\n\n\n\n<p><strong>Address Frame:<\/strong>&nbsp;A 7 or 10 bit sequence unique to each slave that identifies the slave when the master wants to talk to it.<\/p>\n\n\n\n<p><strong>Read\/Write Bit:&nbsp;<\/strong>A single bit specifying whether the master is sending data to the slave (low voltage level) or requesting data from it (high voltage level).<\/p>\n\n\n\n<p><strong>ACK\/NACK Bit:<\/strong>&nbsp;Each frame in a&nbsp;message is followed by an acknowledge\/no-acknowledge bit. If an&nbsp;address frame or data frame was successfully received, an ACK bit is returned to the sender from the receiving device.<\/p>\n\n\n\n<p>For more information and detailed explanations refer to this NXP documentation (<a rel=\"noreferrer noopener\" href=\"https:\/\/www.nxp.com\/docs\/en\/user-guide\/UM10204.pdf\" target=\"_blank\">here<\/a>).<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><br>2.1: I2C setup for STM32F10: locating pins<\/h2>\n\n\n\n<p>First we need to find which pins are for I2C1 bus.<\/p>\n\n\n\n<p>From Table 55 I2C remaping of STM32F103 reference manual, we can find that PB6 is SCL and PB7 os SDA:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"336\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.41.01-AM-1024x336.png\" alt=\"\" class=\"wp-image-1494\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.41.01-AM-1024x336.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.41.01-AM-300x99.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.41.01-AM-768x252.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.41.01-AM-1536x504.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.41.01-AM-1150x378.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.41.01-AM-750x246.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.41.01-AM-400x131.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.41.01-AM-250x82.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.41.01-AM.png 1882w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Hence, we shall configure PB6 and PB7.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2.2: I2C setup for STM32F103:  Pin Configuration<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>We start off by setting up the pins as following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Set the mode to be output 50MHz.<\/li><li>Set the configuration alternate open drain.<\/li><li>Enable clock access to alternate mode of GPIO.<\/li><\/ul>\n\n\n\n<p>We start off by creating new source and header file with name i2c.c and i2c.h respectively <\/p>\n\n\n\n<p>Within header, the following is declared:<\/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 I2C_H_\n#define I2C_H_\n#include &quot;stdint.h&quot;\n#include &quot;stdio.h&quot;\nvoid i2c_init();\nvoid i2c1_scan_bus(void);\n\n#endif \/* I2C_H_ *\/\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Within source 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;i2c.h&quot;\n#include &quot;stm32f1xx.h&quot;\n\n<\/pre><\/div>\n\n\n\n<p>For i2c_init function:<\/p>\n\n\n\n<p>First, enable clock access to GPIOB:<\/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;}\">\/*Enable clock access to GPIOB*\/\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_IOPBEN;<\/pre><\/div>\n\n\n\n<p>Then set PB6 and PB7 to the requirements:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"855\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.44.38-AM-1024x855.png\" alt=\"\" class=\"wp-image-1495\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.44.38-AM-1024x855.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.44.38-AM-300x250.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.44.38-AM-768x641.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.44.38-AM-1536x1282.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.44.38-AM-2048x1710.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.44.38-AM-1150x960.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.44.38-AM-750x626.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.44.38-AM-400x334.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.44.38-AM-250x209.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\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;}\">\/*Set PB6 to output 50MHz*\/\n\tGPIOB-&gt;CRL|=GPIO_CRL_MODE6;\n\t\/*Set PB6 to ALternate Open drain*\/\n\tGPIOB-&gt;CRL|=GPIO_CRL_CNF6;\n\n\t\/*Set PB7 to output 50MHz*\/\n\tGPIOB-&gt;CRL|=GPIO_CRL_MODE7;\n\t\/*Set PB7 to ALternate Open drain*\/\n\tGPIOB-&gt;CRL|=GPIO_CRL_CNF7;\n<\/pre><\/div>\n\n\n\n<p>Finally enable clock access to AFIO:<\/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 clock access to alternate function of the pins*\/\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_AFIOEN;<\/pre><\/div>\n\n\n\n<p>Thats all for GPIO settings.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2.3 I2C setup for STM32F103:  I2C configuration<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>We start off by finding which bus is I2C1 is connected to.<\/p>\n\n\n\n<p>From the datasheet we can find that I2C1 is connected to APB1:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"809\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.48.32-AM-809x1024.png\" alt=\"\" class=\"wp-image-1496\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.48.32-AM-809x1024.png 809w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.48.32-AM-237x300.png 237w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.48.32-AM-768x972.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.48.32-AM-750x949.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.48.32-AM-400x506.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.48.32-AM-250x316.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.48.32-AM.png 928w\" sizes=\"(max-width: 809px) 100vw, 809px\" \/><\/figure>\n\n\n\n<p>Hence, we can enable clock access to I2C1 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;}\">\t\/*Enable clock access to I2C1*\/\n\tRCC-&gt;APB1ENR|=RCC_APB1ENR_I2C1EN;<\/pre><\/div>\n\n\n\n<p>Now, we shall tell the i2c the frequency of the bus. Since the MCU is running by default at 8MHz, se shall set it to 8:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"234\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.50.49-AM-1024x234.png\" alt=\"\" class=\"wp-image-1497\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.50.49-AM-1024x234.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.50.49-AM-300x69.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.50.49-AM-768x176.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.50.49-AM-1536x352.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.50.49-AM-2048x469.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.50.49-AM-1150x263.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.50.49-AM-750x172.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.50.49-AM-400x92.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.50.49-AM-250x57.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\/*Tell the peripheral that the clock is 8MHz*\/\n\tI2C1-&gt;CR2&amp;=~(I2C_CR2_FREQ);\n\tI2C1-&gt;CR2|=(8&lt;&lt;I2C_CR2_FREQ_Pos);<\/pre><\/div>\n\n\n\n<p>Now, we shall set the rise time and we shall use the maximum recommended value of 9.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"234\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.29-AM-1024x234.png\" alt=\"\" class=\"wp-image-1498\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.29-AM-1024x234.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.29-AM-300x69.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.29-AM-768x176.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.29-AM-1536x352.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.29-AM-2048x469.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.29-AM-1150x263.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.29-AM-750x172.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.29-AM-400x92.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.29-AM-250x57.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\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=\"350\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.44-AM-1024x350.png\" alt=\"\" class=\"wp-image-1499\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.44-AM-1024x350.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.44-AM-300x102.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.44-AM-768x262.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.44-AM-1536x524.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.44-AM-2048x699.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.44-AM-1150x393.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.44-AM-750x256.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.44-AM-400x137.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.52.44-AM-250x85.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\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;}\">\t\/*Set the rise time*\/\n\tI2C1-&gt;TRISE=9;<\/pre><\/div>\n\n\n\n<p>Now for the CCR value:<\/p>\n\n\n\n<p>The calculation as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"701\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.35.02-AM-1024x701.png\" alt=\"\" class=\"wp-image-1500\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.35.02-AM-1024x701.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.35.02-AM-300x205.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.35.02-AM-768x526.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.35.02-AM-1150x788.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.35.02-AM-750x514.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.35.02-AM-400x274.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.35.02-AM-250x171.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.35.02-AM.png 1168w\" 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;}\">I2C1-&gt;CCR|=0x28;<\/pre><\/div>\n\n\n\n<p>Finally enable the peripheral:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"255\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.55.04-AM-1024x255.png\" alt=\"\" class=\"wp-image-1501\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.55.04-AM-1024x255.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.55.04-AM-300x75.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.55.04-AM-768x191.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.55.04-AM-1536x383.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.55.04-AM-2048x511.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.55.04-AM-1150x287.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.55.04-AM-750x187.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.55.04-AM-400x100.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-22-at-8.55.04-AM-250x62.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;}\">I2C1-&gt;CR1|=I2C_CR1_PE;<\/pre><\/div>\n\n\n\n<p>That all for the initializing sequence.<\/p>\n\n\n\n<p>Hence, the source 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;}\">\nvoid i2c_init()\n{\n\t\/*Enable clock access to GPIOB*\/\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_IOPBEN;\n\n\t\/*Set PB6 to output 50MHz*\/\n\tGPIOB-&gt;CRL|=GPIO_CRL_MODE6;\n\t\/*Set PB6 to ALternate Open drain*\/\n\tGPIOB-&gt;CRL|=GPIO_CRL_CNF6;\n\n\t\/*Set PB7 to output 50MHz*\/\n\tGPIOB-&gt;CRL|=GPIO_CRL_MODE7;\n\t\/*Set PB7 to ALternate Open drain*\/\n\tGPIOB-&gt;CRL|=GPIO_CRL_CNF7;\n\n\t\/*Enable clock access to alternate function of the pins*\/\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_AFIOEN;\n\n\t\/*Enable clock access to I2C1*\/\n\tRCC-&gt;APB1ENR|=RCC_APB1ENR_I2C1EN;\n\n\n\t\/*Tell the peripheral that the clock is 8MHz*\/\n\tI2C1-&gt;CR2&amp;=~(I2C_CR2_FREQ);\n\tI2C1-&gt;CR2|=(8&lt;&lt;I2C_CR2_FREQ_Pos);\n\t\/*Set the rise time*\/\n\tI2C1-&gt;TRISE=9;\n\n\tI2C1-&gt;CCR|=0x28;\n\n\tI2C1-&gt;CR1|=I2C_CR1_PE;\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. I2C bus scan:<\/h2>\n\n\n\n<p>To perform bus scann, the following step shall be done:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Send the start condition and wait until the start is generated.<\/li><li>Send the address with write operation and wait for SR1 or SR2 to be any value.<\/li><li>Generate stop condition.<\/li><li>wait for about 100uS.<\/li><li>If the address is set, the print the address.<\/li><li>Loop for all 127 address.<\/li><\/ul>\n\n\n\n<p>Hence, the scan 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;}\">\nvoid i2c1_scan_bus(void)\n{        int a=0;\n         for (uint8_t i=0;i&lt;128;i++)\n   {\n            I2C1-&gt;CR1 |= I2C_CR1_START;\n            while(!(I2C1-&gt;SR1 &amp; I2C_SR1_SB));\n            I2C1-&gt;DR=(i&lt;&lt;1|0);\n            while(!(I2C1-&gt;SR1)|!(I2C1-&gt;SR2)){};\n            I2C1-&gt;CR1 |= I2C_CR1_STOP;\n            delay(100);\/\/minium wait time is 40 uS, but for sure, leave it 100 uS\n            a=(I2C1-&gt;SR1&amp;I2C_SR1_ADDR);\n            if (a==2)\n         {\n                printf(&quot;Found I2C device at adress 0x%X (hexadecimal), or %d (decimal)\\n\\r&quot;,i,i);\n         }\n     }\n}<\/pre><\/div>\n\n\n\n<p>Within the main.c file, initialize the function and in while 1 loop, call the scan bus function 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;}\">#include &quot;stm32f1xx.h&quot;\n#include &quot;i2c.h&quot;\n#include &quot;uart.h&quot;\n\n\nint main(void)\n{\n\tuart2_init();\n\ti2c_init();\n\twhile(1)\n\t{\n\t\ti2c1_scan_bus();\n\n\t}\n}\n<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">4. Code:<\/h2>\n\n\n\n<p>You may download the code from here:<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/I2C_Scanner.zip\">I2C_Scanner<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/I2C_Scanner.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\">5. Results<\/h2>\n\n\n\n<p>Compile, upload the code and open your favourite terminal, set the baudrate to 115200 and you shall see the address of connected devices (Note: I got only 1 device connected)<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"528\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-16-at-7.39.27-AM-1024x528.png\" alt=\"\" class=\"wp-image-422\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-16-at-7.39.27-AM-1024x528.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-16-at-7.39.27-AM-300x155.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-16-at-7.39.27-AM-768x396.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-16-at-7.39.27-AM-1150x593.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-16-at-7.39.27-AM-750x387.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-16-at-7.39.27-AM-400x206.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-16-at-7.39.27-AM-250x129.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-16-at-7.39.27-AM.png 1338w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Happy coding \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>n this guide, we shall discuss what is I2C and how to make an i2c bus scanner to scan the slave devices that connected to the i2c1 bus of STM32F103 In this guide we will cover the following: What is I2C I2C setup for stm32f1 I2C bus scanner code. Code Results 1.1: What is I2C [&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-1493","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\/1493"}],"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=1493"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1493\/revisions"}],"predecessor-version":[{"id":1503,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1493\/revisions\/1503"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1493"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1493"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1493"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}