{"id":5366,"date":"2015-03-05T08:55:11","date_gmt":"2015-03-05T16:55:11","guid":{"rendered":"https:\/\/blog.digilentinc.com\/?p=5366"},"modified":"2025-06-02T03:38:03","modified_gmt":"2025-06-02T10:38:03","slug":"i2c-how-does-it-work","status":"publish","type":"post","link":"https:\/\/digilent.com\/blog\/i2c-how-does-it-work\/","title":{"rendered":"How I2C Interface Functions?"},"content":{"rendered":"<p>Welcome back to the Digilent Blog!<\/p>\n<p>&nbsp;<\/p>\n<p>Inter-integrated-circuit, more\u00a0commonly known as I\u00b2C (generally pronounced I-squared-C), is a communication style originally developed by Phillips Semiconductor (now NXP Semiconductor). Its design allows multiple components to be able to talk to each other on the same data line, making it widely used in a variety of systems, including Pmods. As a fan of Pmods, I&#8217;m in favor of learning how you can communicate with them and get them what you want to do. Let&#8217;s find out more.<\/p>\n<p>&nbsp;<\/p>\n<p>One of the reasons why this protocol is so widely used is that it uses only two communication wires: a serial data line (SDA) and a serial clock line (SCL), which are both natively held in a logic high position through the use of\u00a0<a title=\"Digilent Learn Module on pull-up resistors\" href=\"http:\/\/learn.blog.digilentinc.com\/Documents\/176\" target=\"_blank\" rel=\"noopener\">pull-up resistors<\/a>. Many other communication protocols, such as <a title=\"Pmod Communication: Serial Peripheral Interface\" href=\"https:\/\/digilent.com\/blog\/index.php\/pmod-communication-serial-peripheral-interface-in-detail\/\" target=\"_blank\" rel=\"noopener\">SPI<\/a>, require more I\/O pins to function, as well as additional pins for each subsequent component that is added to the communication bus (the wires that allow multiple devices to talk to each other). A &#8220;master&#8221; device can easily choose to talk to just one of the many &#8220;slave&#8221; devices by issuing a start condition, sending out the address of the device that it wants to talk to as well as an indicator of whether\u00a0it wants to read from or write to the device.<\/p>\n<figure id=\"attachment_5448\" aria-describedby=\"caption-attachment-5448\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/Multiple-devices-on-one-I2C-bus-cropped.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-5448\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/Multiple-devices-on-one-I2C-bus-cropped.jpg\" alt=\"Multiple I2C devices can be attached to a single I2C port on a system board\" width=\"600\" height=\"478\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/Multiple-devices-on-one-I2C-bus-cropped.jpg 2701w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/Multiple-devices-on-one-I2C-bus-cropped-600x478.jpg 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/Multiple-devices-on-one-I2C-bus-cropped-1024x816.jpg 1024w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/Multiple-devices-on-one-I2C-bus-cropped-225x179.jpg 225w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/Multiple-devices-on-one-I2C-bus-cropped-800x638.jpg 800w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a><figcaption id=\"caption-attachment-5448\" class=\"wp-caption-text\">Multiple I2C devices can be attached to a single I2C port on a system board.<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>If the device that the host board is calling is on the line (pun intended), that device will respond with an acknowledge (ACK) bit by pulling the SDA line low. The slave device will then listen for the next command while all of the other devices that are also on the bus wait for another start condition before listening for their address again.\u00a0After receiving an ACK, the master can then tell the listening device which register address within the on-board chip that it wants to read from (or write). Once an additional ACK is received, confirming that particular action is permissible, data transmission between the two devices can occur.\u00a0Once all of the desired data transfer has occurred (as determined by the user&#8217;s preferences) the master may then issue a &#8220;restart&#8221; (pulling SDA low while SCL is idling high)to start a fresh communication session or should release the SDA line while SCL is high as its &#8220;stop&#8221; condition.<\/p>\n<p>&nbsp;<\/p>\n<p>However, this all presumes that everything goes smoothly and the receiving device acknowledges the 8 bits of data by pulling the serial data line low. But what about when the data line is instead left at a high voltage state from the pull-up resistor? This would indicate that the data transfer was not acknowledged, implying that something was wrong with the data. Naturally, what exactly went wrong is dependent on when the NACK (a negative-acknowledge character) was read by the receiving device. The table below illustrates when a NACK might occur and what you could do about it.<\/p>\n<p>&nbsp;<\/p>\n<figure id=\"attachment_5435\" aria-describedby=\"caption-attachment-5435\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/large-nack-table.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-5435\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/large-nack-table.jpg\" alt=\"What you can do when you receive a NACK\" width=\"600\" height=\"338\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/large-nack-table.jpg 1632w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/large-nack-table-600x338.jpg 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/large-nack-table-1024x577.jpg 1024w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/large-nack-table-225x127.jpg 225w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a><figcaption id=\"caption-attachment-5435\" class=\"wp-caption-text\">What you can do when you receive a NACK.<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p>Within the\u00a0I\u00b2C protocol, the master device always retains control of the serial clock, driving the line low to indicate to the transmitting device that it should place a bit on the SDA line (blue bars)\u00a0and allowing the\u00a0line to go high telling the receiving device to read the bit on the SDA line (green bars).<\/p>\n<figure style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"\" src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/6\/64\/I2C_data_transfer.svg\/600px-I2C_data_transfer.svg.png\" alt=\"\" width=\"600\" height=\"100\" \/><figcaption class=\"wp-caption-text\">I2C timing diagram. Image from the <a href=\"https:\/\/en.wikipedia.org\/wiki\/I%C2%B2C#Timing_diagram\" target=\"_blank\" rel=\"noopener\">I2C Wikipedia webpage<\/a>.<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p>But because the only feedback that a transmitter receives is an ACK or NACK after 8 bits have already been transferred, there is no way for the master device to instinctively know if it is pulsing the SCL line too quickly for the slave device to place or read bits to or from the data line.\u00a0Luckily, the I\u00b2C protocol mitigates this problem through a feature called clock stretching.<\/p>\n<p>&nbsp;<\/p>\n<p>Clocking stretching is the ability of a slave device to continue to drive the serial clock line low after the master device has already released the clock line to be pulled up to the high voltage state. This is used to guarantee the slave device enough time (as determined internally by the slave device) to read or prepare the next bit before the clock &#8220;ticks&#8221; again. In accordance with this, the master device waits for the serial clock line to actually reach the high voltage state before delaying a set amount of time (to ensure the receiver reads the bit on the data line) and subsequently driving the SCL line to a low voltage state.<\/p>\n<figure id=\"attachment_5467\" aria-describedby=\"caption-attachment-5467\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/I2C-clock-stretching.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-5467\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/I2C-clock-stretching.jpg\" alt=\"I2C Clock Stretching\" width=\"600\" height=\"351\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/I2C-clock-stretching.jpg 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/I2C-clock-stretching-225x132.jpg 225w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a><figcaption id=\"caption-attachment-5467\" class=\"wp-caption-text\">I2C clock stretching.<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p>With the feature in I\u00b2C of\u00a0multiple devices being able to connect to the same\u00a0I\u00b2C bus, there is a possibility that two masters might initiate start condition at the same time or have multiple slave devices that respond to a single address. As\u00a0there is no way for any of the components on the line to instinctively &#8220;know&#8221; that there is another device also using the data line, this raises the possibility that a bus collision (literally) might occur.<\/p>\n<p>&nbsp;<\/p>\n<p>To avoid this breakdown in communication, all devices that are currently using the SDA\u00a0line will go through arbitration on every bit to determine if they have control of the line. This is done by having each device that may be trying to use the data line place their bit of data as they normally would (driving SDA low or leaving it to idle high) and then reading the voltage level on the line to see if it is what the device expects. If a device sees that the line has been driven low when it expects it to be idling high, it will conclude that another device must also be using the SDA line and subsequently relinquish control of the data line, losing arbitration.<\/p>\n<p>&nbsp;<\/p>\n<figure id=\"attachment_5471\" aria-describedby=\"caption-attachment-5471\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/I2C-arbitration.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-5471\" src=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/I2C-arbitration.jpg\" alt=\"I2C arbitration example\" width=\"600\" height=\"450\" srcset=\"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/I2C-arbitration.jpg 600w, https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/I2C-arbitration-225x169.jpg 225w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a><figcaption id=\"caption-attachment-5471\" class=\"wp-caption-text\">I2C arbitration example.<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p>The second device, seeing\u00a0that the voltage level is as it expected, will continue transmitting its message although it will also continue to check the line after each bit in case there is another device that has happened to exactly match its bit values so far. When a master device loses arbitration, it will relinquish control of both the SDA and SCL line and wait for a stop condition before attempting to transmit its message again.<\/p>\n<p>&nbsp;<\/p>\n<p>But what about if two devices match each other&#8217;s bit values for the entire duration of the communication session from the start bit to the stop bit? I&#8217;ll leave you with a question of my own for you to answer:\u00a0is this actually a problem for my system?<\/p>\n<div class='watch-action'><div class='watch-position align-left'><div class='action-like'><a class='lbg-style6 like-5366 jlk' data-task='like' data-post_id='5366' data-nonce='1c819b3974' rel='nofollow'><img src='https:\/\/digilent.com\/blog\/wp-content\/plugins\/wti-like-post-pro\/images\/pixel.gif' title='Like' \/><span class='lc-5366 lc'>+1<\/span><\/a><\/div><div class='action-unlike'><a class='unlbg-style6 unlike-5366 jlk' data-task='unlike' data-post_id='5366' data-nonce='1c819b3974' rel='nofollow'><img src='https:\/\/digilent.com\/blog\/wp-content\/plugins\/wti-like-post-pro\/images\/pixel.gif' title='Unlike' \/><span class='unlc-5366 unlc'>0<\/span><\/a><\/div><\/div> <div class='status-5366 status align-left'><\/div><\/div><div class='wti-clear'><\/div>","protected":false},"excerpt":{"rendered":"<p>Inter-integrated-circuit, more commonly known as I\u00b2C (generally pronounced I-squared-C), is a communication style originally developed by Phillips Semiconductor (now NXP Semiconductor). Its design allows multiple components to be able to talk to each other on the same data line, making it widely used in a variety of systems, including Pmods. As a fan of Pmods, I&#8217;m in favor of learning how you can communicate with them and get them what you want to do. Let&#8217;s find out more.<\/p>\n","protected":false},"author":17,"featured_media":5448,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[1563],"tags":[],"ppma_author":[4469],"class_list":["post-5366","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-guide"],"jetpack_featured_media_url":"https:\/\/digilent.com\/blog\/wp-content\/uploads\/2015\/02\/Multiple-devices-on-one-I2C-bus-cropped.jpg","authors":[{"term_id":4469,"user_id":17,"is_guest":0,"slug":"jamescolvin","display_name":"James Colvin","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/8aa85f7d11711acc7e571e1ed26c901b614a7064a2e15e522f54d9f26792ea9e?s=96&d=mm&r=g","1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":"","9":"","10":""}],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/posts\/5366","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/users\/17"}],"replies":[{"embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/comments?post=5366"}],"version-history":[{"count":2,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/posts\/5366\/revisions"}],"predecessor-version":[{"id":31607,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/posts\/5366\/revisions\/31607"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/media\/5448"}],"wp:attachment":[{"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/media?parent=5366"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/categories?post=5366"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/tags?post=5366"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/digilent.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=5366"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}