{"id":3665,"date":"2019-09-11T16:27:34","date_gmt":"2019-09-11T14:27:34","guid":{"rendered":"https:\/\/deepbluembedded.com\/?p=3665"},"modified":"2023-08-17T23:52:34","modified_gmt":"2023-08-17T20:52:34","slug":"i2c-communication-protocol-tutorial-pic","status":"publish","type":"post","link":"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/","title":{"rendered":"I2C Communication Protocol Tutorial"},"content":{"rendered":"<table style=\"border-collapse: collapse; width: 100%;\" border=\"1\">\n<tbody>\n<tr>\n<td style=\"background-color: #ffffff; width: 5%;\"><a href=\"https:\/\/deepbluembedded.com\/embedded-systems-tutorials\/\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1666 alignleft\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L-150x150.png\" alt=\"Previous Tutorial\" width=\"35\" height=\"35\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L-150x150.png 150w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L-160x160.png 160w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L-320x320.png 320w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L-50x50.png 50w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256L.png 256w\" sizes=\"auto, (max-width: 35px) 100vw, 35px\" \/><\/a><\/td>\n<td style=\"background-color: #ffffff; width: 30%; text-align: left;\" colspan=\"2\"><a href=\"https:\/\/deepbluembedded.com\/interfacing-16x2-lcd-with-pic-microcontrollers-mplab-xc8\/\"><strong>Previous Tutorial<\/strong><\/a><\/td>\n<td style=\"background-color: #ffffff; width: 30%; text-align: center;\" colspan=\"2\"><span style=\"color: #000000;\"><strong><span style=\"font-size: 14pt;\">Tutorial 26<\/span><\/strong><\/span><\/td>\n<td style=\"background-color: #ffffff; width: 30%; text-align: right;\" colspan=\"2\"><strong>Next Tutorial<\/strong><\/td>\n<td style=\"background-color: #ffffff; width: 5%;\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1667 alignright\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256-150x150.png\" alt=\"Next Tutorial\" width=\"35\" height=\"35\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256-150x150.png 150w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256-160x160.png 160w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256-320x320.png 320w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256-50x50.png 50w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/play-256.png 256w\" sizes=\"auto, (max-width: 35px) 100vw, 35px\" \/><\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #ffffff; width: 5%;\"><\/td>\n<td style=\"background-color: #ffffff; text-align: center;\" colspan=\"6\"><span style=\"font-size: 14pt;\"><strong>I<sup>2<\/sup>C Communication Protocol With PIC MCUs<\/strong><\/span><\/td>\n<td style=\"background-color: #ffffff; width: 5%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #ffffff; width: 5%;\"><\/td>\n<td style=\"width: 20%; background-color: #ffffff; text-align: center;\" colspan=\"6\"><span style=\"font-size: 10pt;\"><strong>Intermediate Level \u2605\u2605\u2606\u2606\u2606<\/strong><\/span><\/td>\n<td style=\"background-color: #ffffff; width: 5%;\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3738\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Tutorial-With-PIC-Microcontrollers-Thumbnail.jpg\" alt=\"I2C Tutorial With PIC Microcontrollers Thumbnail\" width=\"720\" height=\"327\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Tutorial-With-PIC-Microcontrollers-Thumbnail.jpg 720w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Tutorial-With-PIC-Microcontrollers-Thumbnail-300x136.jpg 300w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">In this article, we&#8217;ll deep dive into I<sup>2<\/sup>C serial communication protocol. What is I<sup>2<\/sup>C communication? And how I<sup>2<\/sup>C works? And where I<sup>2<\/sup>C bus is used? And much more questions will be answered. This article will start by defining the I<sup>2<\/sup>C communication basics and show you the I<sup>2<\/sup>C bus specifications and standards as published by NXP the originator of I<sup>2<\/sup>C<sup>TM<\/sup>. Then we&#8217;ll discuss specifically the I<sup>2<\/sup>C hardware in Microchip PIC microcontrollers, and see how it works and how to configure it. We&#8217;ll then develop a simple driver code to test it out. And finally, do a couple of LAB projects to put it all together and get it to work practically.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">It&#8217;s going to be a very long read, so stick around and let&#8217;s get started!<\/span><\/p>\n<p>[toc]<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #7094ff;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a0Required Components For This Tutorial\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<table style=\"width: 100%; border-collapse: collapse; border-style: solid; background-color: #ffffff; border-color: #000000;\">\n<tbody>\n<tr>\n<td style=\"width: 10%; text-align: center; background-color: #212121;\"><span style=\"color: #ffffff;\"><strong>Qty.<\/strong><\/span><\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #212121;\"><span style=\"color: #ffffff;\"><strong>Component Name<\/strong><\/span><\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #212121;\"><span style=\"color: #ffffff;\"><strong>Buy<\/strong> On Amazon.com<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 10%; text-align: center; background-color: #ffffff;\">2<\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">PIC16F877A or PIC18F2550 or anyother<\/span><\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><a href=\"https:\/\/amzn.to\/2S35QkL\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 10%; text-align: center; background-color: #ffffff;\">2<\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">BreadBoard<\/span><\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><a href=\"https:\/\/amzn.to\/2LFYimS\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 10%; text-align: center; background-color: #ffffff;\">8<\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">LED<\/span><\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><a href=\"https:\/\/amzn.to\/2XyQNWb\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a>\u00a0 \u00a0 <a href=\"https:\/\/amzn.to\/2LFQ0eU\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 10%; text-align: center; background-color: #ffffff;\">1<\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">Resistors Kit<\/span><\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><a href=\"https:\/\/amzn.to\/2XufO4F\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a>\u00a0 \u00a0 <a href=\"https:\/\/amzn.to\/2JhXGSK\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 10%; text-align: center; background-color: #ffffff;\">1<\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">Capacitors Kit<\/span><\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><a href=\"https:\/\/amzn.to\/2LAIQsi\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a>\u00a0 \u00a0 <a href=\"https:\/\/amzn.to\/2Jjt4Aq\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 10%; text-align: center; background-color: #ffffff;\">1<\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">Jumper Wires Pack<\/span><\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><a href=\"https:\/\/amzn.to\/2Xvs4gu\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a>\u00a0 \u00a0 <a href=\"https:\/\/amzn.to\/32cgJWk\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 10%; text-align: center; background-color: #ffffff;\">2<\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">LM7805 Voltage Regulator (5v)<\/span><\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><a href=\"https:\/\/amzn.to\/2XtVETJ\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 10%; text-align: center; background-color: #ffffff;\">2<\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">Crystal Oscillator<\/span><\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><a href=\"https:\/\/amzn.to\/2LBpWS9\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 10%; text-align: center; background-color: #ffffff;\">1<\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">PICkit2 or 3 Programmer<\/span><\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><a href=\"https:\/\/amzn.to\/2LHhJvy\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 10%; text-align: center; background-color: #ffffff;\">2<\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">9v Battery or DC Power Supply<\/span><\/td>\n<td style=\"width: 33.3333%; text-align: center; background-color: #ffffff;\"><a href=\"https:\/\/amzn.to\/2LIlPDG\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a>\u00a0 \u00a0 <a href=\"https:\/\/amzn.to\/2XsWoNE\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a>\u00a0 \u00a0 <a href=\"https:\/\/amzn.to\/2JhneiW\" target=\"_blank\" rel=\"noopener noreferrer\">Add<\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong><a href=\"https:\/\/deepbluembedded.com\/microcontroller-programming-tutorial\/#_Prototyping_Board\" target=\"_blank\" rel=\"noopener noreferrer\">The Prototyping Board Setup<\/a><\/strong><\/p>\n<p><a href=\"https:\/\/deepbluembedded.com\/microcontroller-programming-tutorial\/#_Prototyping_Board\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1962\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/Prototyping-Board-Embedded-Systems-Tutorials-With-PIC-MCUs-1024x489.jpg\" alt=\"Prototyping Board - Embedded Systems Tutorials With PIC MCUs\" width=\"750\" height=\"358\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/Prototyping-Board-Embedded-Systems-Tutorials-With-PIC-MCUs-1024x489.jpg 1024w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/Prototyping-Board-Embedded-Systems-Tutorials-With-PIC-MCUs-300x143.jpg 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/Prototyping-Board-Embedded-Systems-Tutorials-With-PIC-MCUs-768x367.jpg 768w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/Prototyping-Board-Embedded-Systems-Tutorials-With-PIC-MCUs.jpg 1500w\" sizes=\"auto, (max-width: 750px) 100vw, 750px\" \/><\/a><\/p>\n<p><strong>Debugging Tools:<\/strong><\/p>\n<ul>\n<li>Digital Storage Oscilloscope (DSO): <a href=\"https:\/\/amzn.to\/2Na9oSW\" target=\"_blank\" rel=\"noopener noreferrer\">Siglent SDS1104 (on Amazon.com)<\/a><\/li>\n<li><a href=\"https:\/\/amzn.to\/2NRtq45\" target=\"_blank\" rel=\"noopener noreferrer\">Logic Analyzer (on Amazon.com)<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #7094ff;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a0Introduction To I<sup>2<\/sup>C\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<h4><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Up till now, we&#8217;ve introduced UART, SPI serial communication ports. We&#8217;ve also done a handful of practical LABs using both of them. Before introducing the I<sup>2<\/sup>C bus, let&#8217;s just quickly review the previous serial ports.<\/span><\/p>\n<h4><a href=\"https:\/\/deepbluembedded.com\/uart-pic-microcontroller-tutorial\/\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"color: #000000;\"><strong>UART<\/strong><\/span><\/a><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Universal Asynchronous Receiver\/Transmitter\u00a0or\u00a0UART\u00a0for short represents the hardware circuitry (module) being used for serial communication. UART is sold\/shipped as a standalone integrated circuit (IC) or as an internal module within microcontrollers. There is a couple of io pins dedicated to the UART serial communication module highlighted in the following figure. Namely, RX\u00a0(data input \u2013 receiving end) &amp;\u00a0TX (data output \u2013 transmitting end).<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">There are actually two forms of UART Hardware as follows:<\/span><\/p>\n<ul style=\"text-align: justify;\">\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">UART\u00a0\u2013 Universal Asynchronous Receiver\/Transmitter<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">USART\u00a0\u2013 Universal Synchronous\/Asynchronous Receiver\/Transmitter<\/span><\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The\u00a0Synchronous\u00a0type of transmitters generates the data clock and sends it to the receiver which works accordingly in a synchronized manner. On the other hand, the\u00a0Asynchronous\u00a0type of transmitter generates the data clock internally. There is no incoming serial clock signal, so in order to achieve proper communication between the two ends, both of them must be using the same\u00a0baud rate. The baud rate is the rate at which bits are being sent\u00a0bps\u00a0(bits per second).<\/span><\/p>\n<h4><a href=\"https:\/\/deepbluembedded.com\/spi-tutorial-with-pic-microcontrollers\/\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"color: #000000;\"><strong>SPI<\/strong><\/span><\/a><\/h4>\n<p style=\"text-align: justify;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">SPI is an acronym for (Serial Peripheral Interface) pronounced as \u201cS-P-I\u201d or \u201cSpy\u201d. Which is a serial, synchronous, single-master, multi-slave, full-duplex interface bus typically used for serial communication between microcomputer systems and other devices, memories, and sensors. Usually used to interface Flash Memories, ADC, DAC, RTC, LCD, SDcards, and much more.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">The SPI was originally developed by Motorola back in the 80s to provide full-duplex serial communication to be used in embedded systems applications. Specifically for very short distance communications (ob-board).<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">In typical SPI communication, there should be at least 2 devices attached to the SPI bus. One of them should be the master and the other will essentially be a slave. The master initiates communication by generating a serial clock signal to shift a data frame out, at the same time serial data is being shifted-in to the master. This process is the same whether it\u2019s a read or write operation.<\/span><\/p>\n<h4><span style=\"color: #000000;\"><strong>I<sup>2<\/sup>C<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">I<sup>2<\/sup>C (i-square-c) is an acronym for &#8220;Inter-Integrated-Circuit&#8221; which was originally created by Philips Semiconductors (now NXP) back in 1982. I<sup>2<\/sup>C<sup>TM<\/sup> is a registered trademark for its respective owner and maybe it was the reason they call it &#8220;Two Wire Interface (TWI)&#8221; in some microcontrollers like Atmel AVR. The I<sup>2<\/sup>C is a multi-master, multi-slave, synchronous, bidirectional, half-duplex serial communication bus. It&#8217;s widely used for attaching lower-speed peripheral ICs to processors and microcontrollers in short-distance, intra-board communication.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The I<sup>2<\/sup>C-bus is used in various control architectures such as System Management Bus (SMBus), Power Management Bus (PMBus), Intelligent Platform Management Interface (IPMI), Display Data Channel (DDC) and Advanced Telecom Computing Architecture (ATCA).<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3683\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Definitions-of-I2C-Bus-Terminologies-1024x486.png\" alt=\"Definitions of I2C Bus Terminologies\" width=\"751\" height=\"357\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Definitions-of-I2C-Bus-Terminologies-1024x486.png 1024w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Definitions-of-I2C-Bus-Terminologies-300x142.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Definitions-of-I2C-Bus-Terminologies-768x365.png 768w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Definitions-of-I2C-Bus-Terminologies.png 1108w\" sizes=\"auto, (max-width: 751px) 100vw, 751px\" \/><\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #7094ff;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a0Features Of I<sup>2<\/sup>C Bus\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<p><strong>Here are some of the most important features of I<sup>2<\/sup>C Bus:<\/strong><\/p>\n<ul>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> Only two bus lines are required; a serial data line (SDA) and a serial clock line (SCL).<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Each device connected to the bus is software addressable by a unique address and simple master\/slave relationships exist at all times; masters can operate as master-transmitters or as master-receivers.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">It is a true multi-master bus including collision detection and arbitration to prevent data corruption if two or more masters simultaneously initiate data transfer.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Serial, 8-bit oriented, bidirectional data transfers can be made at up to 100 kbit\/s in the Standard-mode, up to 400 kbit\/s in the Fast-mode, up to 1 Mbit\/s in Fast-mode Plus, or up to 3.4 Mbit\/s in the High-speed mode.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Serial, 8-bit oriented, unidirectional data transfers up to 5 Mbit\/s in Ultra Fast-mode<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">On-chip filtering rejects spikes on the bus data line to preserve data integrity.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The number of ICs that can be connected to the same bus is limited only by a maximum bus capacitance. More capacitance may be allowed under some conditions.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Supports various control architectures such as System Management Bus (SMBus), Power Management Bus (PMBus), Intelligent Platform Management Interface (IPMI), Display Data Channel (DDC) and Advanced Telecom Computing Architecture (ATCA).<\/span><\/li>\n<\/ul>\n<p><strong>I2C Applications Examples Diagram<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3674\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Applications-Examples-Diagram.png\" alt=\"I2C Applications Examples Diagram\" width=\"788\" height=\"502\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Applications-Examples-Diagram.png 788w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Applications-Examples-Diagram-300x191.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Applications-Examples-Diagram-768x489.png 768w\" sizes=\"auto, (max-width: 788px) 100vw, 788px\" \/><\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #7094ff;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a0I<sup>2<\/sup>C Bus Protocol\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">In this section, we&#8217;ll start discussing the I<sup>2<\/sup>C Bus protocol in detail. What are the essential elements of I<sup>2<\/sup>C transactions? And how does the physical layer of I<sup>2<\/sup>C look like? And the modes, speeds of I<sup>2<\/sup>C, and much more. This is going to be the densest part of this tutorial and will be divided into many sub-sections for each topic. One at a time to successively build a very deep understanding of every little detail in the working mechanics of I<sup>2<\/sup>C communication.<\/span><\/p>\n<h4><span style=\"color: #000000;\"><strong>I<sup>2<\/sup>C Modes &amp; Bus Speeds<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> Originally, the I2C-bus was limited to 100 kbit\/s operation. Over time there have been several additions to the specification so that there are now five operating speed categories. Standard-mode, Fast-mode (Fm), Fast-mode Plus (Fm+), and High-speed mode (Hs-mode) devices are downward-compatible. Which means any device may be operated at lower bus speed. Ultra Fast-mode devices are not compatible with previous versions since the bus is unidirectional.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Bidirectional bus:<\/span><\/p>\n<ul style=\"text-align: justify;\">\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>Standard-Mode<\/strong><b> (Sm)<\/b>, with a bit rate up to 100 kbit\/s<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><b><\/b><strong>Fast-Mode<\/strong><b> (Fm)<\/b>, with a bit rate up to 400 kbit\/s<\/span><br \/>\n<b><\/b><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>Fast-Mode Plus<\/strong><b> (Fm+)<\/b>, with a bit rate up to 1 Mbit\/s<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>High-speed Mode<\/strong><b> (Hs-mode)<\/b>, with a bit rate up to 3.4 Mbit\/s.<\/span><\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Unidirectional bus:<\/span><\/p>\n<ul>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>Ultra Fast-Mode<\/strong><b> (UFm)<\/b>, with a bit rate up to 5 Mbit\/s<\/span><\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Note: You have to refer to the specific device datasheet to check the typical details for the i2c hardware specifications that have actually been implemented on-chip.<\/span><\/p>\n<h4><span style=\"color: #000000;\"><strong>I<sup>2<\/sup>C Physical Layer (Hardware)<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Have a quick look at this short demo figure. Then continue reading and let me explain what&#8217;s going on over there.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3736\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Bus-Hardware-Physical-Layer-Demo.jpg\" alt=\"I2C Bus Hardware - Physical Layer Demo\" width=\"1200\" height=\"1365\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Bus-Hardware-Physical-Layer-Demo.jpg 1200w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Bus-Hardware-Physical-Layer-Demo-264x300.jpg 264w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Bus-Hardware-Physical-Layer-Demo-768x874.jpg 768w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Bus-Hardware-Physical-Layer-Demo-900x1024.jpg 900w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The I2C bus uses what&#8217;s known as an <strong>open-drain<\/strong> (open-collector) output driver. You should also note that the I2C pins (SDA &amp; SCL) both should be isolated from the IO pins driver (PORT Register), so these pins must be configured as input which makes the TRIState in high-impedance mode. As if they aren&#8217;t connected to the IO output driver and now both of SCL, SDA line are under the control of the I2C open-drain output driver.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">As the name suggests, the open-drain driver transistor connects the SDA or SCL pin to ground if it&#8217;s activated (input=1), if not the pins will be floating as they are connected to open drains. To eliminate this floating state, we must pull the I2C bus line up with external resistors, so its IDLE state is HIGH. When an open drain driver gets activated, the line will go down (LOW). And that&#8217;s how open drain drivers work.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">When the driver transistor is ON, the line is held LOW.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">When the driver transistor is OFF, the line is released and pulled to HIGH (by the effect of external pull-up resistors).<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">A typical I2C message has a format like the shown above in the figure. Starting with a start condition, ending by a stop condition. This format will be discussed in more detail hereafter. But the thing to note is as follows.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">If 2 master MCUs (MCU1 And MCU2) are sending data to the same slave (motor driver) at the same time. This will cause no problem, and here is why I2C bus is immune to such conditions. Both messages are identical in the first part (address) as they are actually sending to the same slave with the same address. But the data byte will be definitely different. At a moment, one of them will put 1 to the bus and the other will put 0.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">This will not cause a short! instead, the master who puts 1 is actually releasing the SDA line while the other is holding it low. So, the MCU1 master chip will lose arbitration and will have to wait until MCU2 finished the communication so it can start once again!<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">This great feature in the I2C bus is called &#8220;Arbitration&#8221;. And will be discussed in detail hereafter in the article.<\/span><\/p>\n<h4><span style=\"color: #000000;\"><strong>SDA &amp; SCL, Data Validity<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Both SDA and SCL are bidirectional lines, connected to a positive supply voltage via a current-source or pull-up resistor. When the bus is free, both lines are HIGH. The output stages of devices connected to the bus must have an open-drain or open-collector to perform the wired-AND function. Data on the I2C-bus can be transferred at rates of up to 100 kbit\/s in the Standard-mode, up to 400 kbit\/s in the Fast-mode, up to 1 Mbit\/s in Fast-mode Plus, or up to 3.4 Mbit\/s in the High-speed mode. The bus capacitance limits the number of interfaces connected to the bus.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> Due to the variety of different technology devices (CMOS, NMOS, bipolar), that can be connected to the I<sup>2<\/sup>C-bus, the levels of the logical \u20180\u2019 (LOW) and \u20181\u2019 (HIGH) are not fixed and depend on the associated level of V<sub>DD<\/sub>. Input reference levels are set as 30 % and 70 % of V<sub>DD<\/sub>; V<sub>IL<\/sub> is 0.3V<sub>DD<\/sub> and V<sub>IH<\/sub> is 0.7V<sub>DD<\/sub>.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The data on the SDA line must be stable during the HIGH period of the clock. The HIGH or LOW state of the data line can only change when the clock signal on the SCL line is LOW. One clock pulse is generated for each data bit transferred.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3681\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Data-Validity-Timing-Diagram.png\" alt=\"I2C Data Validity Timing Diagram\" width=\"725\" height=\"238\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Data-Validity-Timing-Diagram.png 864w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Data-Validity-Timing-Diagram-300x99.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Data-Validity-Timing-Diagram-768x252.png 768w\" sizes=\"auto, (max-width: 725px) 100vw, 725px\" \/><\/p>\n<h4><span style=\"color: #000000;\"><strong>Elements of I<sup>2<\/sup>C Transactions<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">A typical I2C message consists of some basic elements (conditions) that take place on the I2C bus sequentially and it always starts with a <strong>start condition (s)<\/strong>. Followed by the desired slave device <strong>address (7-Bits or 10-Bits)<\/strong>, then a <strong>R\/W bit<\/strong> to determine whether the master (who initiated the S condition for communication) wants to read or write to this slave having that address. Then if the slave exists and works OK, it&#8217;ll acknowledge back to the master by sending an <strong>Acknowledge bit ACK<\/strong> otherwise, it&#8217;s considered a <strong>Negative Acknowledge NACK<\/strong>.\u00a0 Afterward, the byte of <strong>Data<\/strong> is sent, followed by acknowledging from the slave. And finally, the master can terminate the communication by sending the <strong>Stop Condition (P)<\/strong> sequence.<\/span><\/p>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3734\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C_write.jpg\" alt=\"I2C_write\" width=\"889\" height=\"250\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C_write.jpg 889w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C_write-300x84.jpg 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C_write-768x216.jpg 768w\" sizes=\"auto, (max-width: 889px) 100vw, 889px\" \/><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">We can summarize these conditions (elements) of I2C bus signaling as follows:<\/span><\/p>\n<ul>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Start Condition (S)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Stop Condition (P)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Repeated Start (Restart) Condition (Sr)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Acknowledge ACK (A)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Not Acknowledge NACK (~A)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Address + R\/W<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Data Byte<\/span><\/li>\n<\/ul>\n<h4><span style=\"color: #000000;\"><strong>( Start, Stop, Restart ) Conditions<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> All transactions begin with a START (S) and are terminated by a STOP (P).<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>&gt;<\/strong> A HIGH-to-LOW transition on the SDA line, while SCL is HIGH, defines a START condition.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>&gt;<\/strong> A LOW-to-HIGH transition on the SDA line, while SCL is HIGH, defines a STOP condition.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3685\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Start-And-Stop-Conditions-1024x334.png\" alt=\"I2C Start And Stop Conditions\" width=\"696\" height=\"227\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Start-And-Stop-Conditions-1024x334.png 1024w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Start-And-Stop-Conditions-300x98.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Start-And-Stop-Conditions-768x251.png 768w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Start-And-Stop-Conditions.png 1066w\" sizes=\"auto, (max-width: 696px) 100vw, 696px\" \/><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> START and STOP conditions are always generated by the master. The bus is considered to be busy after the START condition. The bus is considered to be free again a certain time after the STOP condition. The bus stays busy if a repeated START (Sr) is generated instead of a STOP condition. In this respect, the START (S) and repeated START (Sr) conditions are functionally identical.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-3686\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/i2c_restart_condition-1024x248.jpg\" alt=\"i2c_restart_condition\" width=\"1024\" height=\"248\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/i2c_restart_condition-1024x248.jpg 1024w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/i2c_restart_condition-300x73.jpg 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/i2c_restart_condition-768x186.jpg 768w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/i2c_restart_condition.jpg 1299w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p style=\"text-align: justify;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif; text-align: justify;\">Detection of START, STOP, and RESTART conditions by devices connected to the bus is easy if they <\/span><span style=\"color: #000000; font-family: arial, helvetica, sans-serif; text-align: justify;\">incorporate the necessary interfacing hardware. However, microcontrollers with no such <\/span><span style=\"color: #000000; font-family: arial, helvetica, sans-serif; text-align: justify;\">interface have to sample the SDA line at least twice per clock period to sense the <\/span><span style=\"color: #000000; font-family: arial, helvetica, sans-serif; text-align: justify;\">transition.<\/span><\/p>\n<h4><span style=\"color: #000000;\"><strong>Acknowledge ACK &amp; NACK<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><strong>ACK<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The acknowledge takes place after every byte. The acknowledge bit allows the receiver to signal the transmitter that the byte was successfully received and another byte may be sent. The master generates all clock pulses, including the acknowledge ninth clock pulse. The Acknowledge signal is defined as follows: the transmitter releases the SDA line during the acknowledge clock pulse so the receiver can pull the SDA line LOW and it remains stable LOW during the HIGH period of this clock pulse.<\/span><\/p>\n<p><strong>NACK<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">When SDA remains HIGH during this ninth clock pulse, this is defined as the Not Acknowledge signal. It&#8217;s also called a Negative Acknowledge or simply NACK. The master can then generate either a STOP condition to abort the transfer, or a repeated START condition to start a new transfer. <\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3688\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-ACK-NACK-1024x406.png\" alt=\"I2C ACK NACK\" width=\"568\" height=\"225\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-ACK-NACK-1024x406.png 1024w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-ACK-NACK-300x119.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-ACK-NACK-768x305.png 768w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-ACK-NACK.png 1920w\" sizes=\"auto, (max-width: 568px) 100vw, 568px\" \/><\/p>\n<p style=\"text-align: justify;\"><strong><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">There are five conditions that lead to the generation of a NACK:<\/span><\/strong><\/p>\n<ol>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">No receiver is present on the bus with the transmitted address so there is no device to respond with an acknowledge.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The receiver is unable to receive or transmit because it is performing some real-time function and is not ready to start communication with the master.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">During the transfer, the receiver gets data or commands that it does not understand.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">During the transfer, the receiver cannot receive any more data bytes.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">A master-receiver must signal the end of the transfer to the slave transmitter.<\/span><\/li>\n<\/ol>\n<h4><span style=\"color: #000000;\"><strong>I<sup>2<\/sup>C Byte Format<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> Every byte put on the SDA line must be eight bits long. The number of bytes that can be transmitted per transfer is unrestricted. Each byte must be followed by an Acknowledge bit. Data is transferred with the Most Significant Bit (MSB) first. If a slave cannot receive or transmit another complete byte of data until it has performed some other function, for example servicing an internal interrupt, it can hold the clock line SCL LOW to force the master into a wait state. Data transfer then continues when the slave is ready for another byte of data and releases clock line SCL.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3689\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Data-Transaction-Format.png\" alt=\"I2C Data Transaction Format\" width=\"1002\" height=\"314\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Data-Transaction-Format.png 1002w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Data-Transaction-Format-300x94.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Data-Transaction-Format-768x241.png 768w\" sizes=\"auto, (max-width: 1002px) 100vw, 1002px\" \/><\/p>\n<h4><span style=\"color: #000000;\"><strong>I<sup>2<\/sup>C Clock Synchronization<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Two masters can begin transmitting on a free bus at the same time and there must be a method for deciding which takes control of the bus and complete its transmission. This is done by clock synchronization and arbitration. In single master systems, clock synchronization and arbitration are not needed.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Clock synchronization is performed using the wired-AND connection of I<sup>2<\/sup>C interfaces to the SCL line. This means that a HIGH to LOW transition on the SCL line causes the masters concerned to start counting off their LOW period and, once a master clock has gone LOW, it holds the SCL line in that state until the clock HIGH state is reached. However, if another clock is still within its LOW period, the LOW to HIGH transition of this clock may not change the state of the SCL line. The SCL line is therefore held LOW by the master with the longest LOW period. Masters with shorter LOW periods enter a HIGH wait-state during this time.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3691\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Clock-Synchronization.png\" alt=\"I2C Clock Synchronization\" width=\"546\" height=\"320\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Clock-Synchronization.png 765w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Clock-Synchronization-300x176.png 300w\" sizes=\"auto, (max-width: 546px) 100vw, 546px\" \/><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> When all masters concerned have counted off their LOW period, the clock line is released and goes HIGH. There is then no difference between the master clocks and the state of the SCL line, and all the masters start counting their HIGH periods. The first master to complete its HIGH period pulls the SCL line LOW again. In this way, a synchronized SCL clock is generated with its LOW period determined by the master with the longest clock LOW period, and its HIGH period determined by the one with the shortest clock HIGH period.<\/span><\/p>\n<h4><span style=\"color: #000000;\"><strong>I<sup>2<\/sup>C Bus Arbitration<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> Arbitration, like synchronization, refers to a portion of the protocol required only if more than one master is used in the system. Slaves are not involved in the arbitration procedure. A master may start a transfer only if the bus is free. Two masters may generate a START condition within the minimum hold time (tHD;STA) of the START condition which results in a valid START condition on the bus. Arbitration is then required to determine which master will complete its transmission.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Arbitration proceeds bit by bit. During every bit, while SCL is HIGH, each master checks to <\/span><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">see if the SDA level matches what it has sent. This process may take many bits. Two <\/span><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">masters can actually complete an entire transaction without error, as long as the transmissions are identical. The first time a master tries to send a HIGH but detects that the SDA level is LOW, the master knows that it has lost the arbitration and turns off its SDA output driver. The other master goes on to complete its transaction.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">No information is lost during the arbitration process. A master that loses the arbitration can generate clock pulses until the end of the byte in which it loses the arbitration and must restart its transaction when the bus is free. If a master also incorporates a slave function and it loses arbitration during the addressing stage, it is possible that the winning master is trying to address it. The losing master must, therefore,\u00a0switch over immediately to its slave mode.<\/span><\/p>\n<p><strong>Consider The Following Example For 2 I<sup>2<\/sup>C Masters Arbitration<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3692\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Bus-Arbitration-Example.png\" alt=\"I2C Bus Arbitration Example\" width=\"679\" height=\"371\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Bus-Arbitration-Example.png 864w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Bus-Arbitration-Example-300x164.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Bus-Arbitration-Example-768x420.png 768w\" sizes=\"auto, (max-width: 679px) 100vw, 679px\" \/><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> The moment there is a difference between the internal data level of the master generating DATA1 and the actual level on the SDA line, the DATA1 output is switched off. This does not affect the data transfer initiated by the winning master. Since control of the I<sup>2<\/sup>C-bus is decided solely on the address and data sent by competing masters, there is no central master, nor any order of priority on the bus. There is an undefined condition if the arbitration procedure is still in progress at the moment when one master sends a repeated START or a STOP condition while the other master is still sending data.<\/span><\/p>\n<h4><span style=\"color: #000000;\"><strong>Clock Stretching<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> Clock stretching pauses a transaction by holding the SCL line LOW. The transaction cannot continue until the line is released HIGH again. Clock stretching is optional and in fact, most slave devices do not include an SCL driver so they are unable to stretch the clock.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">On the byte level, a device may be able to receive bytes of data at a fast rate, but needs more time to store a received byte or prepare another byte to be transmitted. Slaves can then hold the SCL line LOW after reception and acknowledgment of a byte to force the master into a wait state until the slave is ready for the next byte transfer in a type of handshake procedure.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">On the bit level, a device such as a microcontroller with or without limited hardware for the I<sup>2<\/sup>C-bus can slow down the bus clock by extending each clock LOW period. The speed of any master is adapted to the internal operating rate of this device.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3691\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Clock-Synchronization.png\" alt=\"I2C Clock Synchronization\" width=\"546\" height=\"320\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Clock-Synchronization.png 765w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Clock-Synchronization-300x176.png 300w\" sizes=\"auto, (max-width: 546px) 100vw, 546px\" \/><\/p>\n<h4><span style=\"color: #000000;\"><strong>I<sup>2<\/sup>C Addressing &amp; Direction Control<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> Data transfers follow the format shown below. After the START condition (S), a slave address is sent. This address is seven bits long followed by an eighth bit which is a data direction bit (R\/W) \u2014 a \u2018zero\u2019 indicates a transmission (WRITE), a \u2018one\u2019 indicates a request for data (READ). A data transfer is always terminated by a STOP condition (P) generated by the master. However, if a master still wishes to communicate on the bus, it can generate a repeated START condition (Sr) and address another slave without first generating a STOP condition. Various combinations of read\/write formats are then possible within such a transfer.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-3695\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Complete-Data-Transfer-1024x373.png\" alt=\"I2C Complete Data Transfer\" width=\"1024\" height=\"373\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Complete-Data-Transfer-1024x373.png 1024w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Complete-Data-Transfer-300x109.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Complete-Data-Transfer-768x280.png 768w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Complete-Data-Transfer.png 1070w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">In general settings, the default address length is 7-bits. Which means a master can, theoretically, address up to 128 different slaves. But in fact, many slave devices gives you only 3 bits to change. And there are some other addresses reserved by the hardware of the I<sup>2<\/sup>C-Bus itself as we&#8217;ll see hereafter. However, the I2C-Bus can be also configured to operate in 10-Bit Addressing mode, which will significantly raise up the fundamental limitation of the number of slaves to communicate with. Where it becomes up to the limit of total bus capacitance.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3698\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Master-Addressing-7-Bit-Slaves-1024x405.png\" alt=\"I2C Master Addressing 7-Bit Slaves\" width=\"688\" height=\"272\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Master-Addressing-7-Bit-Slaves-1024x405.png 1024w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Master-Addressing-7-Bit-Slaves-300x119.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Master-Addressing-7-Bit-Slaves-768x303.png 768w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Master-Addressing-7-Bit-Slaves.png 1068w\" sizes=\"auto, (max-width: 688px) 100vw, 688px\" \/><\/p>\n<p>&nbsp;<\/p>\n<h4><span style=\"color: #000000;\"><strong>10-Bit Addressing<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> 10-bit addressing expands the number of possible addresses. Devices with 7-bit and 10-bit addresses can be connected to the same I2C-bus, and both 7-bit and 10-bit addressing can be used in all bus speed modes. Currently, 10-bit addressing is not being widely used.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The 10-bit slave address is formed from the first two bytes following a START condition (S) or a repeated START condition (Sr). The first seven bits of the first byte are the combination 1111 0XX of which the last two bits (XX) are the two Most-Significant Bits (MSB) of the 10-bit address; the eighth bit of the first byte is the R\/W bit that determines the direction of the message.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Although there are eight possible combinations of the reserved address bits 1111 XXX, only the four combinations 1111 0XX are used for 10-bit addressing. The remaining four combinations 1111 1XX are reserved for future I2C-bus enhancements.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3697\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Master-Addressing-10-Bit-Slave.png\" alt=\"I2C Master Addressing 10-Bit Slave\" width=\"1002\" height=\"187\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Master-Addressing-10-Bit-Slave.png 1002w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Master-Addressing-10-Bit-Slave-300x56.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Master-Addressing-10-Bit-Slave-768x143.png 768w\" sizes=\"auto, (max-width: 1002px) 100vw, 1002px\" \/><\/p>\n<h4><span style=\"color: #000000;\"><strong>I<sup>2<\/sup>C General Call &amp; Reserved Addresses<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> Two groups of eight addresses (0000 XXX and 1111 XXX) are reserved for the purposes shown in the table below.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3699\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Reserved-Addresses-In-I2C-1024x412.png\" alt=\"Reserved Addresses In I2C\" width=\"701\" height=\"282\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Reserved-Addresses-In-I2C-1024x412.png 1024w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Reserved-Addresses-In-I2C-300x121.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Reserved-Addresses-In-I2C-768x309.png 768w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Reserved-Addresses-In-I2C.png 1078w\" sizes=\"auto, (max-width: 701px) 100vw, 701px\" \/><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> The general call address is for addressing every device connected to the I2C-bus at the same time. However, if a device does not need any of the data supplied within the general call structure, it can ignore this address by not issuing an acknowledgment. If a device does require data from a general call address, it acknowledges this address and behaves as a slave-receiver. The master does not actually know how many devices acknowledged if one or more devices respond. The second and following bytes are acknowledged by every slave-receiver capable of handling this data. A slave who cannot process one of these bytes must ignore it by not acknowledging. Again, if one or more slaves acknowledge, the not-acknowledge will not be seen by the master. The meaning of the general call address is always specified in the second byte.<\/span><\/p>\n<h4><span style=\"color: #000000;\"><strong>Applicability Of I2C-Bus Protocol Features<\/strong><\/span><\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3693\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Applicability-Of-I2C-Bus-Protocol-Features.png\" alt=\"Applicability Of I2C Bus Protocol Features\" width=\"598\" height=\"354\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Applicability-Of-I2C-Bus-Protocol-Features.png 867w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Applicability-Of-I2C-Bus-Protocol-Features-300x178.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Applicability-Of-I2C-Bus-Protocol-Features-768x454.png 768w\" sizes=\"auto, (max-width: 598px) 100vw, 598px\" \/><\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #7094ff;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a0I<sup>2<\/sup>C In Microchip PIC MCUs\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<h4><span style=\"color: #000000;\"><strong>I<sup>2<\/sup>C Mode For MSSP<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> The MSSP module in I<sup>2<\/sup>C mode fully implements all master and slave functions (including general call support) and provides interrupts on Start and Stop bits in hardware to determine a free bus (multi-master function). The MSSP module implements the standard mode specifications as well as 7-bit and 10-bit addressing. Two pins are used for data transfer:<\/span><\/p>\n<ul style=\"text-align: justify;\">\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Serial clock (SCL) \u2013 RB1\/AN10\/INT1\/SCK\/<span style=\"color: #3366ff;\">SCL<\/span><\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Serial data\u00a0 (SDA) \u2013 RB0\/AN12\/INT0\/FLT0\/SDI\/<span style=\"color: #3366ff;\">SDA<\/span><\/span><\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The user must configure these pins as inputs or outputs through the TRISB&lt;1:0&gt; bits.<\/span><\/p>\n<h4><span style=\"color: #000000;\"><strong>I<sup>2<\/sup>C Block Diagram<\/strong><\/span><\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3701 \" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Block-Diagram-In-PIC-Microcontrollers-e1568007240909.png\" alt=\"I2C Block Diagram In PIC Microcontrollers\" width=\"400\" height=\"514\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Block-Diagram-In-PIC-Microcontrollers-e1568007240909.png 445w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Block-Diagram-In-PIC-Microcontrollers-e1568007240909-233x300.png 233w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<h4><span style=\"color: #000000;\"><strong>MSSP I<sup>2<\/sup>C Registers<\/strong><\/span><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> The MSSP module has six registers for I<sup>2<\/sup>C operation. These are:<\/span><\/p>\n<ul style=\"text-align: justify;\">\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">MSSP Control Register 1 (SSPCON1)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">MSSP Control Register 2 (SSPCON2)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">MSSP Status Register (SSPSTAT)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Serial Receive\/Transmit Buffer Register (SSPBUF)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">MSSP Shift Register (SSPSR) \u2013 Not directly accessible<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">MSSP Address Register (SSPADD)<\/span><\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">SSPCON1, SSPCON2, and SSPSTAT are the control and status registers in I<sup>2<\/sup>C mode operation. The SSPCON1 and SSPCON2 registers are readable and writable. The lower six bits of the SSPSTAT are read-only. The upper two bits of the SSPSTAT are read\/write.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">SSPSR is the shift register used for shifting data in or out. SSPBUF is the buffer register to which data bytes are written to or read from. SSPADD register holds the slave device address when the SSP is configured in I<sup>2<\/sup>C Slave mode. When the SSP is configured in Master mode, the lower seven bits of SSPADD act as the Baud Rate Generator reload value.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">In receive operations, SSPSR and SSPBUF together create a double-buffered receiver. When SSPSR receives a complete byte, it is transferred to SSPBUF and the SSPIF interrupt is set. During transmission, the SSPBUF is not double-buffered. A write to SSPBUF will write to both SSPBUF and SSPSR.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h4><span style=\"color: #000000;\"><strong>I<sup>2<\/sup>C Module Operation<\/strong><\/span><\/h4>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> The MSSP module functions are enabled by setting MSSP enable bit, SSPEN (SSPCON1&lt;5&gt;). The SSPCON1 register allows control of the I<sup>2<\/sup>C operation. Four mode selection bits (SSPCON1&lt;3:0&gt;) allow one of the following I<sup>2<\/sup>C modes to be selected:<\/span><\/p>\n<ul style=\"text-align: justify;\">\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">I<sup>2<\/sup>C Master mode<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">I<sup>2<\/sup>C Slave mode (7-bit address)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">I<sup>2<\/sup>C Slave mode (10-bit address)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">I<sup>2<\/sup>C Slave mode (7-bit address) with Start and Stop bit interrupts enabled<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">I<sup>2<\/sup>C Slave mode (10-bit address) with Start and Stop bit interrupts enabled<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">I<sup>2<\/sup>C Firmware Controlled Master mode, the slave is Idle<\/span><\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Selection of any I2C mode with the SSPEN bit set forces the SCL and SDA pins to be open-drain, provided these pins are programmed to inputs by setting the appropriate TRISB bits. To ensure proper operation of the module, pull-up resistors must be provided externally to the SCL and SDA pins.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h4><span style=\"color: #000000;\"><strong>Slave Mode Operation<\/strong><\/span><\/h4>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> In Slave mode, the SCL and SDA pins must be configured as inputs (TRISB&lt;1:0&gt; set). The MSSP module will override the input state with the output data when required (slave-transmitter). The I2C Slave mode hardware will always generate an interrupt on an address match. Through the mode select bits, the user can also choose to interrupt on Start and Stop bits.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">When an address is matched or the data transfer after an address match is received, the hardware automatically will generate the Acknowledge (ACK) pulse and load the SSPBUF register with the received value currently in the SSPSR register. Any combination of the following conditions will cause the MSSP module not to give this ACK pulse:<\/span><\/p>\n<ul>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The Buffer Full bit, BF (SSPSTAT&lt;0&gt;), was set before the transfer was received.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The overflow bit, SSPOV (SSPCON1&lt;6&gt;), was set before the transfer was received.<\/span><\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">In this case, the SSPSR register value is not loaded into the SSPBUF, but bit SSPIF (PIR1&lt;3&gt;) is set. The BF bit is cleared by reading the SSPBUF register, while bit SSPOV is cleared through software.<\/span><\/p>\n<p><span style=\"color: #000000;\"><strong>Slave Addressing<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> Once the MSSP module has been enabled, it waits for a Start condition to occur. Following the Start condition, the eight bits are shifted into the SSPSR register. All incoming bits are sampled with the rising edge of the clock (SCL) line. The value of register SSPSR&lt;7:1&gt; is compared to the value of the SSPADD register. The address is compared on the falling edge of the 8th clock (SCL) pulse. If the addresses match and the BF and SSPOV bits are clear, the following events occur:<\/span><\/p>\n<ol>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The SSPSR register value is loaded into the SSPBUF register.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The Buffer Full bit, BF, is set.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">An ACK pulse is generated.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">MSSP Interrupt Flag bit, SSPIF (PIR1&lt;3&gt;), is set (interrupt is generated if enabled) on the falling edge of the 9th SCL pulse.<\/span><\/li>\n<\/ol>\n<p><span style=\"color: #000000;\"><strong>Slave Reception<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> When the R\/W bit of the address byte is clear and an address match occurs, the R\/W bit of the SSPSTAT register is cleared. The received address is loaded into the SSPBUF register and the SDA line is held low (ACK).<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">When the address byte overflow condition exists, then the no Acknowledge (ACK) pulse is given. An overflow condition is defined as either bit, BF (SSPSTAT&lt;0&gt;), is set or the bit, SSPOV (SSPCON1&lt;6&gt;), is set.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">An MSSP interrupt is generated for each data transfer byte. Flag bit, SSPIF (PIR1&lt;3&gt;), must be cleared in software. The SSPSTAT register is used to determine the status of the byte. If SEN is enabled (SSPCON2&lt;0&gt; = 1), RB1\/SCL will be held low (clock stretch) following each data transfer. The clock must be released by setting bit, CKP (SSPCON1&lt;4&gt;).<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-3713\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Slave-Reception-Timing-Diagram-1024x766.jpg\" alt=\"Slave Reception Timing Diagram\" width=\"1024\" height=\"766\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Slave-Reception-Timing-Diagram-1024x766.jpg 1024w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Slave-Reception-Timing-Diagram-300x224.jpg 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Slave-Reception-Timing-Diagram-768x574.jpg 768w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Slave-Reception-Timing-Diagram.jpg 1958w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p><span style=\"color: #000000;\"><strong>Slave Transmission<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> When the R\/W bit of the incoming address byte is set and an address match occurs, the R\/W bit of the SSPSTAT register is set. The received address is loaded into the SSPBUF register. The ACK pulse will be sent on the ninth bit and pin RB1\/SCL is held low regardless of SEN. By stretching the clock, the master will be unable to assert another clock pulse until the slave is done preparing the transmit data. The transmit data must be loaded into the SSPBUF register which also loads the SSPSR register.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Then pin RB1\/SCL should be enabled by setting bit, CKP (SSPCON1&lt;4&gt;). The eight data bits are shifted out on the falling edge of the SCL input. This ensures that the SDA signal is valid during the SCL high time. The ACK pulse from the master-receiver is latched on the rising edge of the ninth SCL input pulse. If the SDA line is high (not ACK), then the data transfer is complete. In this case, when the ACK is latched by the slave, the slave logic is reset (resets SSPSTAT register) and the slave monitors for another occurrence of the Start bit. If the SDA line was low (ACK), the next transmit data must be loaded into the SSPBUF register. Again, pin RB1\/SCL must be enabled by setting bit CKP (SSPCON1&lt;4&gt;).<\/span><\/p>\n<figure id=\"attachment_3706\" aria-describedby=\"caption-attachment-3706\" style=\"width: 1014px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-3706 size-large\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Slave-Transmission-Timing-Diagram-1024x754.jpg\" alt=\"I2C Slave Transmission Timing Diagram\" width=\"1024\" height=\"754\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Slave-Transmission-Timing-Diagram-1024x754.jpg 1024w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Slave-Transmission-Timing-Diagram-300x221.jpg 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Slave-Transmission-Timing-Diagram-768x566.jpg 768w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Slave-Transmission-Timing-Diagram.jpg 1943w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption id=\"caption-attachment-3706\" class=\"wp-caption-text\">Open In New Tab Or Look it up in the datasheet<\/figcaption><\/figure>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">An MSSP interrupt is generated for each data transfer byte. The SSPIF bit must be cleared in software and the SSPSTAT register is used to determine the status of the byte. The SSPIF bit is set on the falling edge of the 9th clock pulse.<\/span><\/p>\n<p><span style=\"color: #000000;\"><strong>Slave Clock Stretching<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> Both 7 and 10-bit Slave modes implement automatic clock stretching during a transmit sequence. The SEN bit (SSPCON2&lt;0&gt;) allows clock stretching to be enabled during receives. Setting SEN will cause the SCL pin to be held low at the end of each data receive sequence.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><span style=\"color: #3366ff;\"> In 7-bit Slave Receive mode<\/span>, on the falling edge of the 9th clock at the end of the ACK sequence, if the BF bit is set, the CKP bit in the SSPCON1 register is automatically cleared, forcing the SCL output to be held low. The CKP bit being cleared to \u20180\u2019 will assert the SCL line low. The CKP bit must be set in the user\u2019s ISR before the reception is allowed to continue. <\/span><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">By holding the SCL line low, the user has time to service the ISR and read the contents of the SSPBUF before the master device can initiate another receive sequence. This will prevent buffer overruns from occurring.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><span style=\"color: #3366ff;\"> 7-bit Slave Transmit mode<\/span> implements clock stretching by clearing the CKP bit after the falling edge of the 9th clock if the BF bit is clear. This occurs regardless of the state of the SEN bit. The user\u2019s ISR must set the CKP bit before transmission is allowed to continue. By holding the SCL line low, the user has time to service the ISR and load the contents of the SSPBUF before the master device can initiate another transmit sequence.<\/span><\/p>\n<p><span style=\"color: #000000;\"><strong>Slave Clock Synchronization &amp; CKP Bit<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> When the CKP bit is cleared, the SCL output is forced to \u20180\u2019. However, setting the CKP bit will not assert the SCL output low until the SCL output is already sampled low. Therefore, the CKP bit will not assert the SCL line until an external I<sup>2<\/sup>C master device has already asserted the SCL line. The SCL output will remain low until the CKP bit is set and all other devices on the I<sup>2<\/sup>C bus have deasserted SCL. This ensures that a write to the CKP bit will not violate the minimum high time requirement for SCL.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h4><span style=\"color: #000000;\"><strong>Master Mode Operation<\/strong><\/span><\/h4>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> Master mode is enabled by setting and clearing the appropriate SSPM bits in SSPCON1 and by setting the SSPEN bit. In Master mode, the SCL and SDA lines are manipulated by the MSSP hardware. Master mode operation is supported by interrupt generation on the detection of the Start and Stop conditions. The Stop (P) and Start (S) bits are cleared from a Reset or when the MSSP module is disabled. Control of the I<sup>2<\/sup>C bus may be taken when the P bit is set or the bus is Idle, with both the S and P bits clear.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">In Firmware Controlled Master mode, user code conducts all I<sup>2<\/sup>C bus operations based on Start and Stop bit conditions. Once Master mode is enabled, the user has six options:<\/span><\/p>\n<ol>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Assert a Start condition on SDA and SCL.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Assert a Repeated Start condition on SDA and SCL.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Write to the SSPBUF register initiating transmission of data\/address.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Configure the I<sup>2<\/sup>C port to receive data.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Generate an Acknowledge condition at the end of a received byte of data.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Generate a Stop condition on SDA and SCL.<\/span><\/li>\n<\/ol>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 100%; background-color: #f5f5f5;\">\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Note That<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> The MSSP module, when configured in I<sup>2<\/sup>C Master mode, does not allow queueing of events. For instance, the user is not allowed to initiate a Start condition and immediately write the SSPBUF register to initiate transmission before the Start condition is complete. In this case, the SSPBUF will not be written to and the WCOL bit will be set, indicating that a write to the SSPBUF did not occur.<\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> The following events will cause SSP Interrupt Flag bit, SSPIF, to be set (SSP interrupt if enabled):<\/span><\/p>\n<ul>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Start condition<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Stop condition<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Data transfer byte transmitted\/received<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Acknowledge transmit<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Repeated Start (Restart) Condition<\/span><\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><strong>Operation<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The master device generates all of the serial clock pulses and the Start and Stop conditions. A transfer is ended with a Stop condition or with a Repeated Start condition. Since the Repeated Start condition is also the beginning of the next serial transfer, the I<sup>2<\/sup>C bus will not be released.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">In Master Transmitter mode, serial data is output through SDA, while SCL outputs the serial clock. The first byte transmitted contains the slave address of the receiving device (seven bits) and the Read\/Write (R\/W) bit. In this case, the R\/W bit will be logic \u20180\u2019. Serial data is transmitted eight bits at a time. After each byte is transmitted, an Acknowledge bit is received. Start and Stop conditions are output to indicate the beginning and the end of a serial transfer.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">In Master Receive mode, the first byte transmitted contains the slave address of the transmitting device (7 bits) and the R\/W bit. In this case, the R\/W bit will be logic \u20181\u2019 Thus, the first byte transmitted is a 7-bit slave address followed by a \u20181\u2019 to indicate receive bit. Serial data is received via SDA, while SCL outputs the serial clock. Serial data is received eight bits at a time. After each byte is received, an Acknowledge bit is transmitted. Start and Stop conditions indicate the beginning and end of the transmission.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The Baud Rate Generator used for the SPI mode operation is used to set the SCL clock frequency for either 100 kHz, 400 kHz or 1 MHz I<sup>2<\/sup>C operation. Here is the formula to calculate the I<sup>2<\/sup>C Baud Rate given a specific Fosc frequency and SSPADD register. And note that you&#8217;ve to find out the value of SSPADD that you&#8217;ve to write into this register in order to obtain a specific I<sup>2<\/sup>C Baud Rate.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3708\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Baud-Rate-Formula-Equation.png\" alt=\"I2C Baud Rate Formula Equation\" width=\"242\" height=\"43\" \/><\/p>\n<p><strong>Baud Rate Generation<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> In I<sup>2<\/sup>C Master mode, the Baud Rate Generator (BRG) reload value is placed in the lower seven bits of the SSPADD register. When a write occurs to SSPBUF, the Baud Rate Generator will automatically begin counting. The BRG counts down to \u20180\u2019 and stops until another reload has taken place. The BRG count is decremented twice per instruction cycle (T<sub>CY<\/sub>) on the Q<sub>2<\/sub> and Q<sub>4<\/sub> clocks. In I<sup>2<\/sup>C Master mode, the BRG is reloaded automatically. Once the given operation is complete (i.e., the transmission of the last data bit is followed by ACK), the internal clock will automatically stop counting and the SCL pin will remain in its last state.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3709\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Baud-Rate-Generator-For-I2C.png\" alt=\"Baud Rate Generator For I2C\" width=\"693\" height=\"194\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Baud-Rate-Generator-For-I2C.png 957w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Baud-Rate-Generator-For-I2C-300x84.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Baud-Rate-Generator-For-I2C-768x215.png 768w\" sizes=\"auto, (max-width: 693px) 100vw, 693px\" \/><\/p>\n<p><strong>Clock Arbitration<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> Clock arbitration occurs when the master, during any receive, transmit or Repeated Start\/Stop condition, deasserts the SCL pin (SCL allowed to float high). When the SCL pin is allowed to float high, the Baud Rate Generator (BRG) is suspended from counting until the SCL pin is actually sampled high. When the SCL pin is sampled high, the Baud Rate Generator is reloaded with the contents of SSPADD&lt;6:0&gt; and begins counting. This ensures that the SCL high time will always be at least one BRG rollover count in the event that the clock is held low by an external device.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3710\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Clock-Arbitration.png\" alt=\"Clock Arbitration\" width=\"734\" height=\"306\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Clock-Arbitration.png 953w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Clock-Arbitration-300x125.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/Clock-Arbitration-768x321.png 768w\" sizes=\"auto, (max-width: 734px) 100vw, 734px\" \/><\/p>\n<p><strong>Start Condition<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><span style=\"color: #3366ff;\"> To initiate a Start condition, the user sets the Start Enable bit, SEN<\/span> (SSPCON2&lt;0&gt;). If the SDA and SCL pins are sampled high, the Baud Rate Generator is reloaded with the contents of SSPADD&lt;6:0&gt; and starts its count. If SCL and SDA are both sampled high when the Baud Rate Generator times out (TBRG), the SDA pin is driven low. The action of the SDA being driven low while SCL is high is the Start condition and causes the S bit (SSPSTAT&lt;3&gt;) to be set. Following this, the Baud Rate Generator is reloaded with the contents of SSPADD&lt;6:0&gt; and resumes its count. When the Baud Rate Generator times out (TBRG), the SEN bit (SSPCON2&lt;0&gt;) will be automatically cleared by hardware, the Baud Rate Generator is suspended, leaving the SDA line held low and the Start condition is complete.<\/span><\/p>\n<p><strong>Stop Condition<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><span style=\"color: #3366ff;\"> A Stop bit is asserted on the SDA pin at the end of a receive\/transmit by setting the Stop Enable bit, PEN<\/span> (SSPCON2&lt;2&gt;). At the end of a receive\/transmit, the SCL line is held low after the falling edge of the ninth clock. When the PEN bit is set, the master will assert the SDA line low. When the SDA line is sampled low, the Baud Rate Generator is reloaded and counts down to \u20180\u2019. When the Baud Rate Generator times out, the SCL pin will be brought high and one TBRG (Baud Rate Generator rollover count) later, the SDA pin will be deasserted. When the SDA pin is sampled high while SCL is high, the P bit (SSPSTAT&lt;4&gt;) is set. A TBRG later, the PEN bit is cleared and the SSPIF bit is set.<\/span><\/p>\n<p><strong>Repeated Started (Restart) Condition<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><span style=\"color: #3366ff;\"> A Repeated Start condition occurs when the RSEN bit<\/span> (SSPCON2&lt;1&gt;) is programmed high and the I2C logic module is in the Idle state. When the RSEN bit is set, the SCL pin is asserted low. When the SCL pin is sampled low, the Baud Rate Generator is loaded with the contents of SSPADD&lt;5:0&gt; and begins counting. The SDA pin is released (brought high) for one Baud Rate Generator count (TBRG). When the Baud Rate Generator times out, if SDA is sampled high, the SCL pin will be deasserted (brought high). When SCL is sampled high, the Baud Rate Generator is reloaded with the contents of SSPADD&lt;6:0&gt; and begins counting. SDA and SCL must be sampled high for one TBRG. This action is then followed by assertion of the SDA pin (SDA = 0) for one TBRG while SCL is high. <\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Following this, the RSEN bit (SSPCON2&lt;1&gt;) will be automatically cleared and the Baud Rate Generator will not be reloaded, leaving the SDA pin held low. As soon as a Start condition is detected on the SDA and SCL pins, the S bit (SSPSTAT&lt;3&gt;) will be set. The SSPIF bit will not be set until the Baud Rate Generator has timed out. Immediately following the SSPIF bit getting set, the user may write the SSPBUF with the 7-bit address in 7-bit mode or the default first address in 10-bit mode. After the first eight bits are transmitted and an ACK is received, the user may then transmit an additional eight bits of address (10-bit mode) or eight bits of data (7-bit mode).<\/span><\/p>\n<p><strong>Acknowledge Sequence<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><span style=\"color: #3366ff;\"> An Acknowledge sequence is enabled by setting the Acknowledge sequence enable bit, ACKEN<\/span> (SSPCON2&lt;4&gt;). When this bit is set, the SCL pin is pulled low and the contents of the Acknowledge data bit are presented on the SDA pin. If the user wishes to generate an Acknowledge, then the ACKDT bit should be cleared. If not, the user should set the ACKDT bit before starting an Acknowledge sequence. The Baud Rate Generator then counts for one rollover period (TBRG) and the SCL pin is deasserted (pulled high). When the SCL pin is sampled high (clock arbitration), the Baud Rate Generator counts for TBRG. The SCL pin is then pulled low. Following this, the ACKEN bit is automatically cleared, the Baud Rate Generator is turned off and the MSSP module then goes into Idle mode.<\/span><\/p>\n<p><strong>Master Mode Transmission<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><span style=\"color: #3366ff;\"> Transmission of a data byte, a 7-bit address or the other half of a 10-bit address is accomplished by simply writing a value to the SSPBUF register<\/span>. This action will set the Buffer Full flag bit, BF and allow the Baud Rate Generator to begin counting and start the next transmission. Each bit of address\/data will be shifted out onto the SDA pin after the falling edge of SCL is asserted. SCL is held low for one Baud Rate Generator rollover count (T<sub>BRG<\/sub>). Data should be valid before SCL is released high.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">When the SCL pin is released high, it is held that way for T<sub>BRG<\/sub>. The data on the SDA pin must remain stable for that duration and some hold time after the next falling edge of SCL. After the eighth bit is shifted out (the falling edge of the eighth clock), the BF flag is cleared and the master releases SDA. This allows the slave device being addressed to respond with an ACK bit during the ninth bit time if an address match occurred, or if data was received properly. The status of ACK is written into the ACKDT bit on the falling edge of the ninth clock. If the master receives an Acknowledge, the Acknowledge Status bit, ACKSTAT, is cleared. If not, the bit is set. After the ninth clock, the SSPIF bit is set and the master clock (Baud Rate Generator) is suspended until the next data byte is loaded into the SSPBUF, leaving SCL low and SDA unchanged.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><span style=\"color: #3366ff;\">After the write to the SSPBUF, each bit of address will be shifted out on the falling edge of SCL until all seven address bits and the R\/W bit are completed. On the falling edge of the eighth clock, the master will deassert the SDA pin, allowing the slave to respond with an Acknowledge<\/span>. On the falling edge of the ninth clock, the master will sample the SDA pin to see if the address was recognized by a slave. The status of the ACK bit is loaded into the ACKSTAT status bit (SSPCON2&lt;6&gt;). Following the falling edge of the ninth clock transmission of the address, the SSPIF is set, the BF flag is cleared and the Baud Rate Generator is turned off until another write to the SSPBUF takes place, holding SCL low and allowing SDA to float.<\/span><\/p>\n<p><strong>Master Mode Reception<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><span style=\"color: #3366ff;\"> Master mode reception is enabled by programming the Receive Enable bit, RCEN<\/span> (SSPCON2&lt;3&gt;). The Baud Rate Generator begins counting and on each rollover, the state of the SCL pin changes (high-to-low\/ low-to-high) and data is shifted into the SSPSR. After the falling edge of the eighth clock, the receive enable flag is automatically cleared, the contents of the SSPSR are loaded into the SSPBUF, the BF flag bit is set, the SSPIF flag bit is set and the Baud Rate Generator is suspended from counting, holding SCL low. <\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The MSSP is now in Idle state awaiting the next command. When the buffer is read by the CPU, the BF flag bit is automatically cleared. The user can then send an Acknowledge bit at the end of the reception by setting the Acknowledge sequence enable bit, ACKEN (SSPCON2&lt;4&gt;).<\/span><\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #7094ff;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a0How To Configure I<sup>2<\/sup>C Master\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<h4><strong><span style=\"color: #000000;\">Steps To Configure I2C Master Mode Transmitter<\/span><\/strong><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Down below are the typical steps for a master transmission sequence, as stated in the datasheet.<\/span><\/p>\n<p><span style=\"color: #000000;\"><strong>Setup I<sup>2<\/sup>C Master<\/strong><\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>1.<\/strong> Set the I<sup>2<\/sup>C Pins into input mode (High-Impedance). SCL, SDA pins are set to input.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>2.<\/strong> Set The Desired Baud Rate For The I<sup>2<\/sup>C. By writing to SSPADD.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>3.<\/strong> Select And Enable I2C Master Mode Operation For The MSSP module.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>4.<\/strong> Enable interrupt signals, if needed.<\/span><\/p>\n<p><span style=\"color: #000000;\"><strong>Transmit Sequence<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\">(Some of them are done automatically by hardware)<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>1.<\/strong> The user generates a Start condition by setting the Start Enable bit, SEN (SSPCON2&lt;0&gt;).<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>2.<\/strong> SSPIF is set. The MSSP module will wait the required start time before any other operation takes place.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>3.<\/strong> The user loads the SSPBUF with the slave address to transmit.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>4.<\/strong> The address is shifted out the SDA pin until all eight bits are transmitted.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>5.<\/strong> The MSSP module shifts in the ACK bit from the slave device and writes its value into the SSPCON2 register (SSPCON2&lt;6&gt;).<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>6.<\/strong> The MSSP module generates an interrupt at the end of the ninth clock cycle by setting the SSPIF bit.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>7.<\/strong> The user loads the SSPBUF with eight bits of data.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>8.<\/strong> Data is shifted out the SDA pin until all eight bits are transmitted.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>9.<\/strong> The MSSP module shifts in the ACK bit from the slave device and writes its value into the SSPCON2 register (SSPCON2&lt;6&gt;).<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>10.<\/strong> The MSSP module generates an interrupt at the end of the ninth clock cycle by setting the SSPIF bit.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>11.<\/strong> The user generates a Stop condition by setting the Stop Enable bit, PEN (SSPCON2&lt;2&gt;).<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>12.<\/strong> An interrupt is generated once the Stop condition is complete.<\/span><\/p>\n<h4><\/h4>\n<h4><strong><span style=\"color: #000000;\">Implementing I2C Master Mode Transmitter Driver<\/span><\/strong><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">I know that the amount of details mentioned earlier makes it seem kind of intimidating but in fact most of the pre-described mechanics work automatically in the background by the hardware support. Driving the hardware is way easier than what you might be thinking of. Down below are the exact steps with Embedded-C code snippets to implement each step, one at a time.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">First of all, the I2C_Wait() function which makes your master MCU sure that the previous state has reached completion successfully and the bus is on IDLE, so it can proceed to the desired command.<\/span><\/p>\n<pre class=\"lang:c decode:true \">void I2C_Wait()\r\n{\r\n  while ((SSPSTAT &amp; 0x04) || (SSPCON2 &amp; 0x1F));\r\n}<\/pre>\n<p><strong>1.\u00a0 <\/strong>Setup I2C (For Master Mode)<\/p>\n<pre class=\"lang:c decode:true \">void I2C_Master_Init()\r\n{\r\n  SSPCON = 0x28;\r\n  SSPCON2 = 0x00;\r\n  SSPSTAT = 0x00;\r\n  SSPADD = ((_XTAL_FREQ\/4)\/I2C_BaudRate) - 1;\r\n  TRISC3 = 1;\r\n  TRISC4 = 1;\r\n}<\/pre>\n<p><strong>2.\u00a0 <\/strong>Initiate An I2C Start Condition<\/p>\n<pre class=\"lang:c decode:true \">void I2C_Start()\r\n{\r\n  \/\/---[ Initiate I2C Start Condition Sequence ]---\r\n  I2C_Wait();\r\n  SEN = 1;\r\n}<\/pre>\n<p><strong>3.\u00a0 <\/strong>Initiate An I2C Stop Condition<\/p>\n<pre class=\"lang:c decode:true \">void I2C_Stop()\r\n{\r\n  \/\/---[ Initiate I2C Stop Condition Sequence ]---\r\n  I2C_Wait();\r\n  PEN = 1;\r\n}<\/pre>\n<p><strong>4.\u00a0 <\/strong>Initiate An I2C Restart Condition<\/p>\n<pre class=\"lang:c decode:true \">void I2C_Restart()\r\n{\r\n  \/\/---[ Initiate I2C Restart Condition Sequence ]---\r\n  I2C_Wait();\r\n  RSEN = 1;\r\n}<\/pre>\n<p><strong>5.\u00a0 <\/strong>Send ACK Signal (For Master Receiver Mode Only)<\/p>\n<pre class=\"lang:c decode:true \">void I2C_ACK(void)\r\n{\r\n  \/\/---[ Send ACK - For Master Receiver Mode ]---\r\n  I2C_Wait();\r\n  ACKDT = 0; \/\/ 0 -&gt; ACK, 1 -&gt; NACK\r\n  ACKEN = 1; \/\/ Send ACK Signal!\r\n}<\/pre>\n<p><strong>6.\u00a0 <\/strong>Send NACK Signal (For Master Receiver Mode Only)<\/p>\n<pre class=\"lang:c decode:true \">void I2C_NACK(void)\r\n{\r\n  \/\/---[ Send NACK - For Master Receiver Mode ]---\r\n  I2C_Wait();\r\n  ACKDT = 1; \/\/ 1 -&gt; NACK, 0 -&gt; ACK\r\n  ACKEN = 1; \/\/ Send NACK Signal!\r\n}<\/pre>\n<p><strong>7.\u00a0 <\/strong>Send Byte Via I2C Bus, And Return The ACK\/NACK From The Slave<\/p>\n<pre class=\"lang:c decode:true \">unsigned char I2C_Write(unsigned char Data)\r\n{\r\n  \/\/---[ Send Byte, Return The ACK\/NACK ]---\r\n  I2C_Wait();\r\n  SSPBUF = Data;\r\n  I2C_Wait();\r\n  return ACKSTAT;\r\n}<\/pre>\n<p><strong>8.\u00a0 <\/strong>Receive And Return A Byte From The I2C Bus<\/p>\n<pre class=\"lang:c decode:true\">unsigned char I2C_Read_Byte(void)\r\n{\r\n  \/\/---[ Receive &amp; Return A Byte ]---\r\n  RCEN = 1;        \/\/ Enable &amp; Start Reception\r\n  while(!SSPIF);   \/\/ Wait Until Completion\r\n  SSPIF = 0;       \/\/ Clear The Interrupt Flag Bit\r\n  return SSPBUF;   \/\/ Return The Received Byte\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Let&#8217;s put it all together and write a simple example I2C master mode that transmits a single byte 0x52 to a slave I2C device with an address of 0x42 .. It&#8217;s going to be as shown below in the main.c file snippet.<\/span><\/p>\n<pre class=\"lang:c decode:true\">void main(void) \r\n{\r\n  I2C_Init();\r\n\r\n  I2C_Start();\r\n  I2C_Write(0x42); \/\/ Slave I2C Device Address + Write\r\n  I2C_Write(0x52); \/\/ Data To Be Sent\r\n  I2C_Stop();\r\n  \r\n  while(1)\r\n  {\r\n\r\n  }\r\n  return;\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #7094ff;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a0How To Configure I<sup>2<\/sup>C Slave\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<h4><strong><span style=\"color: #000000;\">Steps To Configure I2C Master Mode Transmitter<\/span><\/strong><\/h4>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Down below are the steps to follow in order to configure your microcontroller to be an I2C slave device. And how to receive data from the I2C bus.<\/span><\/p>\n<p><span style=\"color: #000000;\"><strong>Setup I<sup>2<\/sup>C Slave<\/strong><\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>1.<\/strong> Set the I2C Pins To Input Mode (High-Impedance). Both SCL, SDA are set to input.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>2.<\/strong> Set the address you want to assign for this slave by writing it to the SSPADD register.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>3.<\/strong> Disable Slew Rate Control (For Standard Mode Operation).<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>4.<\/strong> Select And Enable I2C Slave Mode Operation For The MSSP module.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>5.<\/strong> Enable The Interrupts Signals.<\/span><\/p>\n<p><span style=\"color: #000000;\"><strong>Data Reception Sequence<\/strong><\/span><\/p>\n<p style=\"text-align: justify;\">( Automatic or Done By Hardware )<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Once the MSSP module has been enabled, it waits for a Start condition to occur. Following the Start condition, the eight bits are shifted into the SSPSR register. All incoming bits are sampled with the rising edge of the clock (SCL) line. The value of register SSPSR&lt;7:1&gt; is compared to the value of the SSPADD register. The address is compared on the falling edge of the eighth clock (SCL) pulse. If the addresses match and the BF and SSPOV bits are clear, the following events occur:<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong> 1.<\/strong> The SSPSR register value is loaded into the SSPBUF register.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>2.<\/strong> The Buffer Full bit, BF, is set.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>3.<\/strong> An ACK pulse is generated.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif;\"><span style=\"color: #000000;\"><strong>4.<\/strong> MSSP Interrupt Flag bit, SSPIF (PIR1&lt;3&gt;), is set (interrupt is generated if enabled) on the<\/span> falling edge of the ninth <span style=\"color: #000000;\">SCL pulse.<\/span><\/span><\/p>\n<p>( Steps To Do In Software, typically in the ISR )<\/p>\n<p>In The ISR For SSPIF<\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>1.<\/strong> Clear The CKP bit (Clock Stretching). To stop the master, no data will be received until the recent byte is read.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>2.<\/strong> Check for the source of the interrupt signal. Whether it&#8217;s data read, data write, or bus collision.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>3.<\/strong> Read The SSPBUF buffer. If it&#8217;s a write signal, then write your data to the buffer after reading it.<\/span><br \/>\n<span style=\"font-family: arial, helvetica, sans-serif;\"><span style=\"color: #000000;\"><strong>4.<\/strong> Set The CKP bit to release the SCL clock line.<\/span><\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\"><span style=\"color: #000000;\"><strong>5.<\/strong> Clear The Interrupt flag bit and it&#8217;s the end of ISR.<\/span><\/span><\/p>\n<h4><\/h4>\n<h4><strong><span style=\"color: #000000;\">Implementing I2C Slave Mode Receiver Driver<\/span><\/strong><\/h4>\n<p><strong>1.\u00a0 <\/strong>Setup I2C (For Slave Mode + Assign It An Address ), Enable Interrupts<\/p>\n<pre class=\"lang:c decode:true\">void I2C_Slave_Init(void)\r\n{\r\n  \/\/---[ Configures The I2C In Slave Mode]---\r\n  TRISB0 = 1;     \/\/ Set As Input - SDA\r\n  TRISB1 = 1;     \/\/ Set As Input - SCL\r\n  SSPADD = Address;  \/\/ Set I2C Device Address\r\n  SSPSTAT = 0x80; \/\/ Disable Slew Rate Control (Standard Mode)\r\n  SSPCON1 = 0x36; \/\/ Select &amp; Enable I2C (Slave Mode)\r\n  SSPCON2 = 0x01; \/\/ Enable Clock Stretching\r\n  SSPIF = 0;      \/\/ Enbable Interrupts\r\n  SSPIE = 1;\r\n  PEIE = 1;\r\n  GIE = 1;\r\n}<\/pre>\n<p><strong>2.\u00a0 <\/strong>Write The ISR Handler For I2C Slave<\/p>\n<p>(General ISR For I2C Slave. it could be for write, read, or overflow error)<\/p>\n<pre class=\"lang:c decode:true\">void __interrupt() ISR(void)\r\n{\r\n  if(SSPIF)\r\n  {\r\n    CKP = 0; \/\/ Hold (Stretch) The Clock Line LOW\r\n    if (SSPOV || WCOL) \/\/ Bus Collision or Buffer Overflow\r\n    {\r\n      char Dummy = SSPBUF; \/\/ Read The Last Byte To Clear The Buffer\r\n      SSPOV = 0;           \/\/ Clear the overflow flag\r\n      WCOL = 0;            \/\/ Clear the collision bit\r\n      CKP = 1;             \/\/ Release Clock Line SCL\r\n    }\r\n    if(!R_nW) \/\/ Read\r\n    {\r\n      char Dummy = SSPBUF; \/\/ Read The Last Byte To Clear The Buffer\r\n      while(!BF);\r\n      RX_Data = SSPBUF;    \/\/ Read The Received Data Byte\r\n      CKP = 1; \/\/ Release Clock Line SCL\r\n    }\r\n    else if(!R_nW) \/\/ Write\r\n    {\r\n      char Dummy = SSPBUF; \/\/ Read The Last Byte To Clear The Buffer\r\n      BF = 0;\r\n      SSPBUF = dummy;      \/\/ Write Your Data (REMOVE THE DUMMY)\r\n      CKP = 1; \/\/ Release Clock Line SCL\r\n      while(BF);\r\n    } \r\n    SSPIF = 0;\r\n  }\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #7094ff;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u03bcC-To-\u03bcC I<sup>2<\/sup>C Communication &#8211; LAB1\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<table style=\"background-color: #ffffff;\">\n<tbody>\n<tr>\n<td style=\"background-color: #ffffff; text-align: left; width: 20%;\"><span style=\"font-family: arial, helvetica, sans-serif;\"><strong><span style=\"color: #000000;\">Lab Name<\/span><\/strong><\/span><\/td>\n<td style=\"background-color: #ffffff; text-align: left; width: 80%;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">MCU-To-MCU I2C Basic Communication Demo<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #ffffff; text-align: left; width: 20%;\"><span style=\"font-family: arial, helvetica, sans-serif;\"><strong><span style=\"color: #000000;\">Lab Number<\/span><\/strong><\/span><\/td>\n<td style=\"background-color: #ffffff; text-align: left; width: 80%;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">30<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #ffffff; text-align: left; width: 20%;\"><span style=\"font-family: arial, helvetica, sans-serif;\"><strong><span style=\"color: #000000;\">Lab Level<\/span><\/strong><\/span><\/td>\n<td style=\"background-color: #ffffff; text-align: left; width: 80%;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">Intermediate<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #ffffff; text-align: left; width: 20%;\"><span style=\"font-family: arial, helvetica, sans-serif;\"><strong><span style=\"color: #000000;\">Lab Objectives<\/span><\/strong><\/span><\/td>\n<td style=\"background-color: #ffffff; text-align: justify; width: 80%;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">Learn how to use I2C Communication works. And create an I2C Communication network. A very simple one, in fact, consisting of a master transmitter and a slave receiver I2C devices and making sure everything is running correctly.<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<h4 style=\"text-align: center;\"><span style=\"color: #ffffff; background-color: #453f3f;\"><strong>\u00a0 \u00a0 \u00a0 \u00a01. Coding\u00a0 \u00a0 \u00a0 \u00a0<\/strong><\/span><\/h4>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>Open<\/strong> the MPLAB IDE and create a couple of new projects and name them &#8220;I2C_Master_Transmitter&#8221;, and &#8220;I2C_Slave_Receiver&#8221;. If you have some issues doing so, you can always refer to the previous tutorial using the link below.<\/span><\/p>\n<p><a href=\"https:\/\/deepbluembedded.com\/creating-new-project-with-mplab\/\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1991\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/link_frame_newproject.jpg\" alt=\"Create New Project With MPLAB IDE\" width=\"375\" height=\"107\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/link_frame_newproject.jpg 700w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/link_frame_newproject-300x86.jpg 300w\" sizes=\"auto, (max-width: 375px) 100vw, 375px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>Set<\/strong> the configuration bits to match the generic setting which we&#8217;ve stated earlier. And if you also find troubles creating this file, you can always refer to the previous tutorial using the link below.<\/span><\/p>\n<p><a href=\"https:\/\/deepbluembedded.com\/configuration-bits-fuses-for-microcontrollers\/\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1581\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/tutorial_link_frame_config.jpg\" alt=\"\" width=\"375\" height=\"107\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/tutorial_link_frame_config.jpg 700w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/tutorial_link_frame_config-300x86.jpg 300w\" sizes=\"auto, (max-width: 375px) 100vw, 375px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Now, open the <strong>main.c<\/strong> file and let&#8217;s start developing the firmware for our project.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The master I2C Transmitter initiates the I2C Communication and starts sending some bytes sequentially. Let&#8217;s send a running counter from 0 upto 255.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The salve will setup the I2C slave receiver port and respond to data reception interrupt signals. Each time a byte of data is received via the I2C bus, the slave device will output it to PORTD in order to check it out for validation. <\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Yes, it&#8217;s not something useful at all, but this lab will make you confident that the system is working as it should be. Then, we can interface some modules and sensors over the I2C bus in the upcoming tutorials. So, stay tuned for that!<\/span><\/p>\n<p><strong><span style=\"font-size: 14pt;\">The Full Code Listing For This Lab<\/span><\/strong><\/p>\n<p><span style=\"color: #3366ff;\"><strong>I2C Master Transmitter Firmware (main.c)<\/strong><\/span><\/p>\n<pre class=\"lang:c decode:true \">\/*\r\n* File: main.c\r\n* Author: Khaled Magdy\r\n* I2C Master Transmitter\r\n* PIC16F877A - Or Any Other Similar PIC MCU\r\n* Tweak The Code To Get It Working With Other MCU\r\n*\/\r\n#include &lt;xc.h&gt;\r\n#include \"config.h\"\r\n#define _XTAL_FREQ 4000000 \/\/ Fosc\r\n#define I2C_BaudRate 100000 \/\/ I2C Baud Rate = 100 Kbps\r\n\/\/----------------------------------------------------------\r\n\/\/-----------------[ Functions' Prototypes ]----------------\r\nvoid I2C_Master_Init(void);\r\nvoid I2C_Wait(void);\r\nvoid I2C_Start(void);\r\nvoid I2C_Stop(void);\r\nvoid I2C_Restart(void);\r\nvoid I2C_ACK(void);\r\nvoid I2C_NACK(void);\r\nunsigned char I2C_Write(unsigned char Data);\r\n\/\/----------------------------------------------------------\r\nvoid main()\r\n{\r\n  TRISB = 0xFF;\r\n  TRISD = 0x00;\r\n  PORTD = 0x00;\r\n  unsigned char i=1;\r\n  I2C_Master_Init();\r\n  while(1)\r\n  {\r\n    I2C_Start(); \/\/ I2C Start Sequence\r\n    I2C_Write(0x40); \/\/ I2C Slave Device Address + Write\r\n    I2C_Write(i++); \/\/ The Data To Be Sent\r\n    I2C_Stop(); \/\/ I2C Stop Sequence\r\n    __delay_ms(500);\r\n    RD3 = ~RD3; \/\/ Toggle LED Each Time A Byte Is Sent!\r\n  }\r\n}\r\n\/\/------------[ END OF MAIN ]--------------\r\n\/\/-----------------------------------------\r\nvoid I2C_Master_Init()\r\n{\r\n  SSPCON = 0x28;\r\n  SSPCON2 = 0x00;\r\n  SSPSTAT = 0x00;\r\n  SSPADD = ((_XTAL_FREQ\/4)\/I2C_BaudRate) - 1;\r\n  TRISC3 = 1;\r\n  TRISC4 = 1; \r\n}\r\nvoid I2C_Wait()\r\n{\r\n  while ((SSPSTAT &amp; 0x04) || (SSPCON2 &amp; 0x1F));\r\n}\r\nvoid I2C_Start()\r\n{\r\n  \/\/---[ Initiate I2C Start Condition Sequence ]---\r\n  I2C_Wait();\r\n  SEN = 1;\r\n}\r\nvoid I2C_Stop()\r\n{\r\n  \/\/---[ Initiate I2C Stop Condition Sequence ]---\r\n  I2C_Wait();\r\n  PEN = 1;\r\n}\r\nvoid I2C_Restart()\r\n{\r\n  \/\/---[ Initiate I2C Restart Condition Sequence ]---\r\n  I2C_Wait();\r\n  RSEN = 1;\r\n}\r\nvoid I2C_ACK(void)\r\n{\r\n  \/\/---[ Send ACK - For Master Receiver Mode ]---\r\n  I2C_Wait();\r\n  ACKDT = 0; \/\/ 0 -&gt; ACK, 1 -&gt; NACK\r\n  ACKEN = 1; \/\/ Send ACK Signal!\r\n}\r\nvoid I2C_NACK(void)\r\n{\r\n  \/\/---[ Send NACK - For Master Receiver Mode ]---\r\n  I2C_Wait();\r\n  ACKDT = 1; \/\/ 1 -&gt; NACK, 0 -&gt; ACK\r\n  ACKEN = 1; \/\/ Send NACK Signal!\r\n}\r\nunsigned char I2C_Write(unsigned char Data)\r\n{\r\n  \/\/---[ Send Byte, Return The ACK\/NACK ]---\r\n  I2C_Wait();\r\n  SSPBUF = Data;\r\n  I2C_Wait();\r\n  return ACKSTAT;\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\"><strong>I2C Slave Receiver Firmware (main.c)<\/strong><\/span><\/p>\n<pre class=\"lang:c decode:true\">\/*\r\n* File: main.c\r\n* Author: Khaled Magdy\r\n* I2C Slave Receiver\r\n* PIC16F877A - Or Any Similar PIC MCU\r\n* Different Parts Will Need Few Tweaking Before Running\r\n*\/\r\n#include &lt;xc.h&gt;\r\n#include \"config.h\"\r\n#define _XTAL_FREQ 4000000 \/\/ Fosc\r\nunsigned char RX_Data = 0x00;\r\n\/\/-----------[ Functions' Prototypes ]--------------\r\nvoid I2C_Slave_Init(unsigned char);\r\n\/\/==================================================\r\nvoid main(void) \r\n{\r\n  TRISD = 0x00;\r\n  PORTD = 0x00;\r\n  I2C_Slave_Init(0x40); \/\/ Initiate I2C Slave With Address = 64 or 0x40\r\n  while(1)\r\n  {\r\n\r\n  }\r\n  return;\r\n}\r\n\/\/----------------[ END OF MAIN ]-------------------\r\n\/\/==================================================\r\nvoid __interrupt() ISR(void)\r\n{\r\n  if(SSPIF)\r\n  {\r\n    if(!R_nW) \/\/ Slave Write (Receive)\r\n    {\r\n      char Dummy = SSPBUF; \/\/ Dummy Read\r\n      CKP = 1; \/\/ Release The SCL Clock Line\r\n      while(!BF); \/\/ Wait Until Completion\r\n      RX_Data = SSPBUF; \/\/ Read The Buffer Data\r\n      PORTD = RX_Data;  \/\/ Output The Received Byte\r\n    }\r\n  CKP = 1;   \/\/ Release The SCL Clock Line\r\n  SSPIF = 0; \/\/ Clear The Interrupt Flag\r\n  }\r\n}\r\n\/\/---------------[ I2C Routines ]-------------------\r\nvoid I2C_Slave_Init(unsigned char Address)\r\n{\r\n  \/\/---[ Configures The I2C In Slave Mode]---\r\n  SSPADD = Address; \/\/ Set The I2C Slave Device Address\r\n  SSPSTAT = 0x80;\r\n  SSPCON = 0x36;\r\n  SSPCON2 = 0x01;\r\n  TRISC3 = 1; \/\/ SCL Set To Input\r\n  TRISC4 = 1; \/\/ SDA Set To Input\r\n  GIE = 1;    \/\/ Enable Interrupts\r\n  PEIE = 1;\r\n  SSPIF = 0;\r\n  SSPIE = 1;\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<h4 style=\"text-align: center;\"><span style=\"color: #ffffff; background-color: #453f3f;\"><strong>\u00a0 \u00a0 \u00a0 \u00a02. Simulation\u00a0 \u00a0 \u00a0 \u00a0<\/strong><\/span><\/h4>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Here is an animation for the running simulation results. The master MCU (on the left) is sending bytes of data (0 to 255) one byte per second. And the receiver is forwarding the received data to PORTD so you can see the data bits on the LEDs. Moreover, the I2C Bus debugger shows you the timestamps and exact format of each byte of data being transferred over the I2C bus.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3722\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C_LAB1_Animation.gif\" alt=\"I2C_LAB1_Animation\" width=\"1160\" height=\"628\" \/><\/p>\n<p>&nbsp;<\/p>\n<h4 style=\"text-align: center;\"><span style=\"color: #ffffff; background-color: #453f3f;\"><strong>\u00a0 \u00a0 \u00a0 \u00a03. Prototyping\u00a0 \u00a0 \u00a0 \u00a0<\/strong><\/span><\/h4>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Down below is the real-life running test for this LAB on real boards. It&#8217;s very easy to hook everything up in this LAB. And it might be challenging to get it to work in case you MCU has different hardware implementation that needs a little bit of tweaking in code to get it to work well.<\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 100%; text-align: center;\"><a href=\"https:\/\/www.youtube.com\/watch?v=D1CAuHWLcl8\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2053\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/Play-Video-On-YouTube.jpg\" alt=\"Play Video On YouTube\" width=\"560\" height=\"70\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/Play-Video-On-YouTube.jpg 560w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/Play-Video-On-YouTube-300x38.jpg 300w\" sizes=\"auto, (max-width: 560px) 100vw, 560px\" \/><\/a><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 100%; text-align: center;\"><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube-nocookie.com\/embed\/D1CAuHWLcl8\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/www.mediafire.com\/file\/y20i3m8h179csrv\/I2C_LAB1_Attachments.rar\/file\" target=\"_blank\" rel=\"noopener noreferrer\"><strong>Download I2C LAB1 Project (Code+Simulation)<\/strong><\/a><\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #7094ff;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a0<\/span><\/strong><\/span><span style=\"background-color: #7094ff;\"><strong><span style=\"color: #ffffff;\">\u03bcC-To-\u03bcC I<sup>2<\/sup>C Communication<\/span><\/strong><\/span><span style=\"background-color: #7094ff;\"><strong><span style=\"color: #ffffff;\">\u00a0&#8211; LAB2\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<table style=\"background-color: #ffffff;\">\n<tbody>\n<tr>\n<td style=\"background-color: #ffffff; text-align: left; width: 20%;\"><span style=\"font-family: arial, helvetica, sans-serif;\"><strong><span style=\"color: #000000;\">Lab Name<\/span><\/strong><\/span><\/td>\n<td style=\"background-color: #ffffff; text-align: left; width: 80%;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">MCU-To-MCU I2C Basic Communication Demo<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #ffffff; text-align: left; width: 20%;\"><span style=\"font-family: arial, helvetica, sans-serif;\"><strong><span style=\"color: #000000;\">Lab Number<\/span><\/strong><\/span><\/td>\n<td style=\"background-color: #ffffff; text-align: left; width: 80%;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">31<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #ffffff; text-align: left; width: 20%;\"><span style=\"font-family: arial, helvetica, sans-serif;\"><strong><span style=\"color: #000000;\">Lab Level<\/span><\/strong><\/span><\/td>\n<td style=\"background-color: #ffffff; text-align: left; width: 80%;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">Intermediate<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #ffffff; text-align: left; width: 20%;\"><span style=\"font-family: arial, helvetica, sans-serif;\"><strong><span style=\"color: #000000;\">Lab Objectives<\/span><\/strong><\/span><\/td>\n<td style=\"background-color: #ffffff; text-align: justify; width: 80%;\"><span style=\"color: #000000; font-family: arial, helvetica, sans-serif;\">Learn how to use I2C Communication works. And create an I2C Communication network. A very simple one, in fact, consisting of a master transmitter and a slave receiver I2C devices and making sure everything is running correctly.<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<h4 style=\"text-align: center;\"><span style=\"color: #ffffff; background-color: #453f3f;\"><strong>\u00a0 \u00a0 \u00a0 \u00a01. Coding\u00a0 \u00a0 \u00a0 \u00a0<\/strong><\/span><\/h4>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>Open<\/strong> the MPLAB IDE and create a couple of new projects and name them &#8220;I2C_Master_Transmitter&#8221;, and &#8220;I2C_Slave_Receiver&#8221;. If you have some issues doing so, you can always refer to the previous tutorial using the link below.<\/span><\/p>\n<p><a href=\"https:\/\/deepbluembedded.com\/creating-new-project-with-mplab\/\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1991\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/link_frame_newproject.jpg\" alt=\"Create New Project With MPLAB IDE\" width=\"375\" height=\"107\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/link_frame_newproject.jpg 700w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/link_frame_newproject-300x86.jpg 300w\" sizes=\"auto, (max-width: 375px) 100vw, 375px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>Set<\/strong> the configuration bits to match the generic setting which we&#8217;ve stated earlier. And if you also find troubles creating this file, you can always refer to the previous tutorial using the link below.<\/span><\/p>\n<p><a href=\"https:\/\/deepbluembedded.com\/configuration-bits-fuses-for-microcontrollers\/\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1581\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/tutorial_link_frame_config.jpg\" alt=\"\" width=\"375\" height=\"107\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/tutorial_link_frame_config.jpg 700w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/tutorial_link_frame_config-300x86.jpg 300w\" sizes=\"auto, (max-width: 375px) 100vw, 375px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Now, open the <strong>main.c<\/strong> file and let&#8217;s start developing the firmware for our project.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The master I2C receiver initiates the communication by actively sending data read requests to the slave device. The slave reads the DIP switches on PORTx and then report the state of this register (byte) to the master each time it requests data.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">You can think of it like the slave I2C device is acting as an io expansion for the master I2C device which reads the IO pins states from the slave device periodically. You can also combine this lab with the previous one in order to send data from the master that will be transferred to the slave&#8217;s IO ports or whatever.<\/span><\/p>\n<p><strong><span style=\"font-size: 14pt;\">The Full Code Listing For This Lab<\/span><\/strong><\/p>\n<p><span style=\"color: #3366ff;\"><strong>I2C Master Receiver Firmware (main.c)<\/strong><\/span><\/p>\n<pre class=\"lang:c decode:true\">\/*\r\n* File: main.c\r\n* Author: Khaled Magdy\r\n* I2C Master Receiver\r\n*\/\r\n#include &lt;xc.h&gt;\r\n#include \"config.h\"\r\n#define _XTAL_FREQ 16000000 \/\/ Fosc\r\n#define I2C_BaudRate 100000 \/\/ I2C Baud Rate = 100 Kbps\r\n\/\/----------------------------------------------------------\r\n\/\/-----------------[ Functions' Prototypes ]----------------\r\nvoid I2C_Master_Init(void);\r\nvoid I2C_Wait(void);\r\nvoid I2C_Start(void);\r\nvoid I2C_Stop(void);\r\nvoid I2C_Restart(void);\r\nvoid I2C_ACK(void);\r\nvoid I2C_NACK(void);\r\nunsigned char I2C_Read(void);\r\nunsigned char I2C_Write(unsigned char Data);\r\n\/\/----------------------------------------------------------\r\nvoid main()\r\n{\r\n  TRISD = 0x00;\r\n  PORTD = 0x00;\r\n  I2C_Master_Init();\r\n  while(1) \r\n  {\r\n    I2C_Start(); \/\/ I2C Start Sequence\r\n    I2C_Write(0x41); \/\/ I2C Slave Device Address 0x40 + Read\r\n    PORTD = I2C_Read(); \/\/ Read Data From Slave\r\n    I2C_Stop(); \/\/ I2C Stop Sequence\r\n    __delay_ms(100);\r\n  }\r\n}\r\n\/\/------------[ END OF MAIN ]--------------\r\n\/\/-----------------------------------------\r\nvoid I2C_Master_Init()\r\n{\r\n  SSPCON = 0x28;\r\n  SSPCON2 = 0x00;\r\n  SSPSTAT = 0x00;\r\n  SSPADD = ((_XTAL_FREQ\/4)\/I2C_BaudRate) - 1;\r\n  TRISC3 = 1;\r\n  TRISC4 = 1;\r\n}\r\nvoid I2C_Wait()\r\n{\r\n  while ((SSPSTAT &amp; 0x04) || (SSPCON2 &amp; 0x1F));\r\n}\r\nvoid I2C_Start()\r\n{\r\n  \/\/---[ Initiate I2C Start Condition Sequence ]---\r\n  I2C_Wait();\r\n  SEN = 1;\r\n}\r\nvoid I2C_Stop()\r\n{\r\n  \/\/---[ Initiate I2C Stop Condition Sequence ]---\r\n  I2C_Wait();\r\n  PEN = 1;\r\n}\r\nvoid I2C_Restart()\r\n{\r\n  \/\/---[ Initiate I2C Restart Condition Sequence ]---\r\n  I2C_Wait();\r\n  RSEN = 1;\r\n}\r\nvoid I2C_ACK(void)\r\n{\r\n  \/\/---[ Send ACK - For Master Receiver Mode ]---\r\n  I2C_Wait();\r\n  ACKDT = 0; \/\/ 0 -&gt; ACK, 1 -&gt; NACK\r\n  ACKEN = 1; \/\/ Send ACK Signal!\r\n}\r\nvoid I2C_NACK(void)\r\n{\r\n  \/\/---[ Send NACK - For Master Receiver Mode ]---\r\n  I2C_Wait();\r\n  ACKDT = 1; \/\/ 1 -&gt; NACK, 0 -&gt; ACK\r\n  ACKEN = 1; \/\/ Send NACK Signal!\r\n}\r\nunsigned char I2C_Write(unsigned char Data)\r\n{\r\n  \/\/---[ Send Byte, Return The ACK\/NACK ]---\r\n  I2C_Wait();\r\n  SSPBUF = Data;\r\n  I2C_Wait();\r\n  return ACKSTAT;\r\n}\r\nunsigned char I2C_Read()\r\n{\r\n  unsigned char Data;\r\n  I2C_Wait();\r\n  RCEN = 1;\r\n  I2C_Wait();\r\n  Data = SSPBUF;\r\n  I2C_NACK();\r\n  return Data;\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\"><strong>I2C Slave Transmitter Firmware (main.c)<\/strong><\/span><\/p>\n<pre class=\"lang:c decode:true\">\/*\r\n* File: main.c\r\n* Author: Khaled Magdy\r\n* I2C Slave Transmitter\r\n*\/\r\n#include &lt;xc.h&gt;\r\n#include \"config.h\"\r\n#define _XTAL_FREQ 4000000 \/\/ Fosc\r\n\/\/-----------[ Functions' Prototypes ]--------------\r\nvoid I2C_Slave_Init(unsigned char);\r\n\/\/==================================================\r\nvoid main(void) {\r\n\r\n  TRISB = 0xFF;\r\n  nRBPU = 0;\r\n  I2C_Slave_Init(0x40); \/\/ Initiate I2C Slave With Address = 64 or 0x40\r\n  while(1) \r\n  {\r\n\r\n  }\r\n  return;\r\n}\r\n\/\/----------------[ END OF MAIN ]-------------------\r\n\/\/==================================================\r\nvoid __interrupt() ISR(void)\r\n{\r\n  if(SSPIF)  \r\n  {\r\n    if(!D_nA &amp;&amp; R_nW)\r\n    {\r\n      char Dummy = SSPBUF;\r\n      SSPBUF = PORTB ;\r\n      CKP = 1;\r\n      while(BF);\r\n    }  \r\n    CKP = 1;\r\n    SSPIF = 0;\r\n}\r\n}\r\n\/\/---------------[ I2C Routines ]-------------------\r\nvoid I2C_Slave_Init(unsigned char Address)\r\n{\r\n  \/\/---[ Configures The I2C In Slave Mode]---\r\n  SSPADD = Address; \/\/ Set The I2C Slave Device Address\r\n  SSPSTAT = 0x80;\r\n  SSPCON = 0x36;\r\n  SSPCON2 = 0x01;\r\n  TRISC3 = 1; \/\/ SCL Set To Input\r\n  TRISC4 = 1; \/\/ SDA Set To Input\r\n  GIE = 1;    \/\/ Enable Interrupts\r\n  PEIE = 1;\r\nSSPIF = 0;\r\nSSPIE = 1;\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<h4 style=\"text-align: center;\"><span style=\"color: #ffffff; background-color: #453f3f;\"><strong>\u00a0 \u00a0 \u00a0 \u00a02. Simulation\u00a0 \u00a0 \u00a0 \u00a0<\/strong><\/span><\/h4>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3724\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C_LAB2_Animation.gif\" alt=\"I2C_LAB2_Animation\" width=\"1160\" height=\"628\" \/><\/p>\n<p>&nbsp;<\/p>\n<h4 style=\"text-align: center;\"><span style=\"color: #ffffff; background-color: #453f3f;\"><strong>\u00a0 \u00a0 \u00a0 \u00a03. Prototyping\u00a0 \u00a0 \u00a0 \u00a0<\/strong><\/span><\/h4>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Down below is the real-life running test for this LAB on real boards. It&#8217;s very easy to hook everything up in this LAB. And it might be challenging to get it to work in case you MCU has different hardware implementation that needs a little bit of tweaking in code to get it to work well.<\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 100%; text-align: center;\"><a href=\"https:\/\/www.youtube.com\/watch?v=BUiqn2Kr_1Y\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2053\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/Play-Video-On-YouTube.jpg\" alt=\"Play Video On YouTube\" width=\"560\" height=\"70\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/Play-Video-On-YouTube.jpg 560w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/Play-Video-On-YouTube-300x38.jpg 300w\" sizes=\"auto, (max-width: 560px) 100vw, 560px\" \/><\/a><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 100%; text-align: center;\"><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube-nocookie.com\/embed\/BUiqn2Kr_1Y\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p style=\"text-align: center;\"><a href=\"https:\/\/www.mediafire.com\/file\/q6luobuuwft7aml\/I2C_LAB2_Attachments.rar\/file\" target=\"_blank\" rel=\"noopener noreferrer\"><strong>Download I2C LAB1 Project (Code+Simulation)<\/strong><\/a><\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #7094ff;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a0Serial I<sup>2<\/sup>C EEPROM Interfacing &#8211; LAB3\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<p style=\"text-align: center;\"><a href=\"https:\/\/deepbluembedded.com\/reading-and-writing-serial-i2c-eeprom-with-pic\" target=\"_blank\" rel=\"noopener noreferrer\">Click Here To GoTo This Tutorial!<\/a><\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3 style=\"text-align: left;\"><span style=\"background-color: #7094ff;\"><strong><span style=\"color: #ffffff;\">\u00a0 \u00a0I<sup>2<\/sup>C Concluding Remarks\u00a0 \u00a0<\/span><\/strong><\/span><\/h3>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #ffffff; background-color: #333333;\"><strong><span style=\"font-size: 18pt; background-color: #333333;\">\u00a0 1\u00a0\u00a0<\/span><\/strong><\/span><\/p>\n<p><strong>Is This The Best I2C Driver?<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Well, obviously, not! It&#8217;s not the best I2C driver that you can possibly create. However, it just works! and gives you a real hands-on experience with the I2C Bus interfaces and how to set up and run an I2C master, salve, and all this stuff. The drivers shown in this article are the bare-minimum C-Code you&#8217;ll need to in order to get something to work. But, you&#8217;ll definitely need to perform some more modifications to meet your need and make your system more reliable.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The I2C module&#8217;s state must be checked before and after each and every single process. Some functions should actually return the status of the bus, ACK, NACK, etc. This is critical for many situations. Another thing to note is the bus collision, which happens sometimes, is actually checked for in the code above but it&#8217;s not handled. These exceptions of a collision, overflow, etc should also be considered and well-handled.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The use of while(condition); statements for waiting to check a specific condition until it&#8217;s met is NOT recommended at all. Almost in all situations, we call this &#8220;Blocking Code&#8221;. If something goes wrong on the I2C bus, which is very probable, maybe all your microcontroller using the blocking code style will FREEZE forever. Bad clock stretching implementations can easily lead to such situations or any bus contention issue.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">I had to disclaim the intent I had while creating this material so you don&#8217;t expect something that it&#8217;s actually not fit for the scope of these tutorials. And you can still adopt the examples and code to help you in a lot of situations and projects. And of course, I&#8217;ll be here to help if you need to. Just drop me a comment below.<\/span><\/p>\n<p><span style=\"color: #ffffff; background-color: #333333;\"><strong><span style=\"font-size: 18pt; background-color: #333333;\">\u00a0 2\u00a0\u00a0<\/span><\/strong><\/span><\/p>\n<p><strong>Briefly Describe The I2C Bus<\/strong><\/p>\n<ul>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Inter-Integrated Circuit (I2C) is a Synchronous Serial Communication Port (Protocol)<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Multi-Master Multi-Slave Bus. Only one conversation may occur at a time.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">I2C is a Two-wire interface (TWI).<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Bi-directional open-drain hardware pins.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Half-Duplex Communication. One way of data transfer at a time. Direction can be reversed but only after terminating the current stream and initiating a new start condition.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The data bits are only valid when the clock line is HIGH. Data must be stable only then.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">I2C bus allows for hot-swapping. This means I2C devices could be easily hooked to and out of the bus without the need to restart devices on the bus.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">I2C Bus supports arbitration and clock synchronization.<\/span><\/li>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">I2C supports clock stretching. This enables all slaves to hold the clock line low while servicing other interrupts until reading the incoming data, then it can release the SCL clock line and conversation continues.<\/span><\/li>\n<\/ul>\n<p><span style=\"color: #ffffff; background-color: #333333;\"><span style=\"font-size: 18pt; background-color: #333333;\">\u00a0 3\u00a0\u00a0<\/span><\/span><\/p>\n<p><strong>I2C Bus Standards<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Originally, the I2C-bus was limited to 100 kbit\/s operation. Over time there have been several additions to the specification so that there are now five operating speed categories. Standard-mode, Fast-mode (Fm), Fast-modeand High-speed mode (Hs-mode) devices are downward-compatible. Which means any device may be operated at lower bus speed. Ultra Fast-mode devices are not compatible with previous versions since the bus is unidirectional.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Bidirectional bus:<\/span><\/p>\n<ul>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>Standard-Mode<\/strong><b> (Sm)<\/b>, with a bit rate up to 100 kbit\/s<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><b><\/b><strong>Fast-Mode<\/strong><b> (Fm)<\/b>, with a bit rate up to 400 kbit\/s<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>Fast-Mode Plus<\/strong><b> (Fm+)<\/b>, with a bit rate up to 1 Mbit\/s<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>High-speed Mode<\/strong><b> (Hs-mode)<\/b>, with a bit rate up to 3.4 Mbit\/s.<\/span><\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Unidirectional bus:<\/span><\/p>\n<ul>\n<li style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"><strong>Ultra Fast-Mode<\/strong><b> (UFm)<\/b>, with a bit rate up to 5 Mbit\/s<\/span><\/li>\n<\/ul>\n<p><span style=\"color: #ffffff; background-color: #333333;\"><strong><span style=\"font-size: 18pt; background-color: #333333;\">\u00a0 4\u00a0\u00a0<\/span><\/strong><\/span><\/p>\n<p><strong>How Many Devices Can You Hook To The I2C Bus?<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Theoretically speaking, the limit for 7-Bit address mode is the addressable count of 7-bit and similarly for 10-Bit address mode. However, in practice, we&#8217;re limited by the total bus capacitance which deforms the clock and data signals.<\/span><\/p>\n<p><span style=\"color: #ffffff; background-color: #333333;\"><strong><span style=\"font-size: 18pt; background-color: #333333;\">\u00a0 5\u00a0\u00a0<\/span><\/strong><\/span><\/p>\n<p><strong>I2C Bus Conditions (Elements)<\/strong><\/p>\n<ul>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Start Condition (S)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Stop Condition (P)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Repeated Start (Restart) Condition (Sr)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Acknowledge ACK (A)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Not Acknowledge NACK (~A)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Address + R\/W<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Data Byte<\/span><\/li>\n<\/ul>\n<p><span style=\"color: #ffffff; background-color: #333333;\"><strong><span style=\"font-size: 18pt; background-color: #333333;\">\u00a0 6\u00a0\u00a0<\/span><\/strong><\/span><\/p>\n<p><strong>I2C Bus Arbitration<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Arbitration, like synchronization, refers to a portion of the protocol required only if more than one master is used in the system. Slaves are not involved in the arbitration procedure. A master may start a transfer only if the bus is free. Two masters may generate a START condition within the minimum hold time (tHD;STA) of the START condition which results in a valid START condition on the bus. Arbitration is then required to determine which master will complete its transmission.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Arbitration proceeds bit by bit. During every bit, while SCL is HIGH, each master checks to <\/span><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">see if the SDA level matches what it has sent. This process may take many bits. Two <\/span><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">masters can actually complete an entire transaction without error, as long as the transmissions are identical. The first time a master tries to send a HIGH but detects that the SDA level is LOW, the master knows that it has lost the arbitration and turns off its SDA output driver. The other master goes on to complete its transaction.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">No information is lost during the arbitration process. A master that loses the arbitration can generate clock pulses until the end of the byte in which it loses the arbitration and must restart its transaction when the bus is free. If a master also incorporates a slave function and it loses arbitration during the addressing stage, it is possible that the winning master is trying to address it. The losing master must, therefore, switch over immediately to its slave mode.<\/span><\/p>\n<p><strong>Consider The Following Example For 2 I<sup>2<\/sup>C Masters Arbitration<\/strong><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3692\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Bus-Arbitration-Example.png\" alt=\"I2C Bus Arbitration Example\" width=\"679\" height=\"371\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Bus-Arbitration-Example.png 864w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Bus-Arbitration-Example-300x164.png 300w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Bus-Arbitration-Example-768x420.png 768w\" sizes=\"auto, (max-width: 679px) 100vw, 679px\" \/><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> The moment there is a difference between the internal data level of the master generating DATA1 and the actual level on the SDA line, the DATA1 output is switched off. This does not affect the data transfer initiated by the winning master. Since control of the I<sup>2<\/sup>C-bus is decided solely on the address and data sent by competing masters, there is no central master, nor any order of priority on the bus. There is an undefined condition if the arbitration procedure is still in progress at the moment when one master sends a repeated START or a STOP condition while the other master is still sending data.<\/span><\/p>\n<p><span style=\"color: #ffffff; background-color: #333333;\"><strong><span style=\"font-size: 18pt; background-color: #333333;\">\u00a0 7\u00a0\u00a0<\/span><\/strong><\/span><\/p>\n<p><strong>I2C Clock Synchronization<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Two masters can begin transmitting on a free bus at the same time and there must be a method for deciding which takes control of the bus and complete its transmission. This is done by clock synchronization and arbitration. In single master systems, clock synchronization and arbitration are not needed.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Clock synchronization is performed using the wired-AND connection of I<sup>2<\/sup>C interfaces to the SCL line. This means that a HIGH to LOW transition on the SCL line causes the masters concerned to start counting off their LOW period and, once a master clock has gone LOW, it holds the SCL line in that state until the clock HIGH state is reached. However, if another clock is still within its LOW period, the LOW to HIGH transition of this clock may not change the state of the SCL line. The SCL line is therefore held LOW by the master with the longest LOW period. Masters with shorter LOW periods enter a HIGH wait-state during this time.<\/span><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3691\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Clock-Synchronization.png\" alt=\"I2C Clock Synchronization\" width=\"546\" height=\"320\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Clock-Synchronization.png 765w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Clock-Synchronization-300x176.png 300w\" sizes=\"auto, (max-width: 546px) 100vw, 546px\" \/><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\"> When all masters concerned have counted off their LOW period, the clock line is released and goes HIGH. There is then no difference between the master clocks and the state of the SCL line, and all the masters start counting their HIGH periods. The first master to complete its HIGH period pulls the SCL line LOW again. In this way, a synchronized SCL clock is generated with its LOW period determined by the master with the longest clock LOW period, and its HIGH period determined by the one with the shortest clock HIGH period.<\/span><\/p>\n<p><span style=\"color: #ffffff; background-color: #333333;\"><strong><span style=\"font-size: 18pt; background-color: #333333;\">\u00a0 8\u00a0\u00a0<\/span><\/strong><\/span><\/p>\n<p><strong>I2C Clock Stretching<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Clock stretching pauses a transaction by holding the SCL line LOW. The transaction cannot continue until the line is released HIGH again. Clock stretching is optional and in fact, most slave devices do not include an SCL driver so they are unable to stretch the clock.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">On the byte level, a device may be able to receive bytes of data at a fast rate, but needs more time to store a received byte or prepare another byte to be transmitted. Slaves can then hold the SCL line LOW after reception and acknowledgment of a byte to force the master into a wait state until the slave is ready for the next byte transfer in a type of handshake procedure.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">On the bit level, a device such as a microcontroller with or without limited hardware for the I<sup>2<\/sup>C-bus can slow down the bus clock by extending each clock LOW period. The speed of any master is adapted to the internal operating rate of this device.<\/span><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-3691\" src=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Clock-Synchronization.png\" alt=\"I2C Clock Synchronization\" width=\"546\" height=\"320\" srcset=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Clock-Synchronization.png 765w, https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Clock-Synchronization-300x176.png 300w\" sizes=\"auto, (max-width: 546px) 100vw, 546px\" \/><br \/>\n<span style=\"color: #ffffff; background-color: #333333;\"><span style=\"font-size: 18pt; background-color: #333333;\">\u00a0 9\u00a0\u00a0<\/span><\/span><\/p>\n<p><strong>I2C Bus Debugging<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Just make sure that you&#8217;ve got the right tools before starting to debug your I2C, You&#8217;ll need for this task a decent <a href=\"https:\/\/amzn.to\/2N9TXtI\" target=\"_blank\" rel=\"noopener noreferrer\">logic analyzer (on Amazon.com)<\/a> or even a DSO with decode feature enabled like my <a href=\"https:\/\/amzn.to\/2O68VRp\" target=\"_blank\" rel=\"noopener noreferrer\">Siglent SDS1104 (on Amazon.com)<\/a>. You can use the simulation tools available in proteus if you don&#8217;t have any of the hardware tools available.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Then start your debugging session by stepping through your code especially the suspicious parts of it. If you&#8217;ve got a <a href=\"https:\/\/amzn.to\/2Naf13r\" target=\"_blank\" rel=\"noopener noreferrer\">hardware debugger tool (on Amazon.com)<\/a> it would be great and highly recommended. If not, then you might use some LEDs, serial terminal, and a lot of artificial delay insertion.<\/span><\/p>\n<p><span style=\"color: #ffffff; background-color: #333333;\"><strong><span style=\"font-size: 18pt; background-color: #333333;\">\u00a0 10\u00a0\u00a0<\/span><\/strong><\/span><\/p>\n<p><strong>Tell Me A Nightmare For I2C Debugger<\/strong><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Well, there are many situations in which you&#8217;ll probably feel like in a real nightmare! But I&#8217;ll mention one of them as I&#8217;ve seen repeatedly happening with practitioners over and over again. Hook your DSO, logic analyzer, and all the stuff and get ready to see the I2C signal to get an idea on what&#8217;s really going on wrong. Power the system up! Et voila! Nothing happens<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">The master attempts to send data and suddenly the clock line goes DOWN forever and everything stops forever. It&#8217;s going to be a frustrating issue to fix. And most of the time it&#8217;s going to be one of the slaves that implements Clock Stretching but it never releases the clock line. I know your code does release the SCL line, but it&#8217;s probably not in the correct timing so your MCU may get stuck even before it&#8217;s able to release the clock line.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000;\">Just be careful when implementing this part of the I2C interface. And get to know when and how to release the clock line properly. And use maybe an LED to figure out where the CPU gets stuck! This issue arises when you&#8217;re using blocking check techniques while enabling clock stretching.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-family: arial, helvetica, sans-serif; color: #000000; font-size: 14pt;\">Finally, it&#8217;s done! You might not be able to imagine how much time and hard-working did it take me to craft these tutorials and make them available for beginners. Help me keep it up by sharing it on social networks! So, please <strong>SHARE IT<\/strong>! and good luck with your projects. Stay tuned for the next tutorials!<\/span><\/p>\n<p><span style=\"font-size: 14pt;\">Regards,<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p> &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"I2C Communication Protocol Tutorial\" class=\"read-more button\" href=\"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/#more-3665\" aria-label=\"Read more about I2C Communication Protocol Tutorial\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":3738,"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,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[28,30,27],"tags":[],"class_list":["post-3665","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-embedded-systems","category-embedded-tutorials","category-microchip-pic","generate-columns","tablet-grid-50","mobile-grid-100","grid-parent","grid-33","no-featured-image-padding"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>I2C Communication Protocol Tutorial I2C Bus With PIC Microcontroller<\/title>\n<meta name=\"description\" content=\"What is I2C communication? And how I2C works? And where I2C bus is used? TWI communication basics, bus specifications and standards\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"I2C Communication Protocol Tutorial I2C Bus With PIC Microcontroller\" \/>\n<meta property=\"og:description\" content=\"What is I2C communication? And how I2C works? And where I2C bus is used? TWI communication basics, bus specifications and standards\" \/>\n<meta property=\"og:url\" content=\"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/\" \/>\n<meta property=\"og:site_name\" content=\"DeepBlue\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/khaled.elrawy.359\/\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/khaled.elrawy.359\/\" \/>\n<meta property=\"article:published_time\" content=\"2019-09-11T14:27:34+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-08-17T20:52:34+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Tutorial-With-PIC-Microcontrollers-Thumbnail.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"720\" \/>\n\t<meta property=\"og:image:height\" content=\"327\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Khaled Magdy\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Khaled Magdy\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"62 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/i2c-communication-protocol-tutorial-pic\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/i2c-communication-protocol-tutorial-pic\\\/\"},\"author\":{\"name\":\"Khaled Magdy\",\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/#\\\/schema\\\/person\\\/30259d66cf68c6c681562dbe551b7867\"},\"headline\":\"I2C Communication Protocol Tutorial\",\"datePublished\":\"2019-09-11T14:27:34+00:00\",\"dateModified\":\"2023-08-17T20:52:34+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/i2c-communication-protocol-tutorial-pic\\\/\"},\"wordCount\":11032,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/#\\\/schema\\\/person\\\/30259d66cf68c6c681562dbe551b7867\"},\"image\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/i2c-communication-protocol-tutorial-pic\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/deepbluembedded.com\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/I2C-Tutorial-With-PIC-Microcontrollers-Thumbnail.jpg\",\"articleSection\":[\"Embedded Systems\",\"Embedded Tutorials\",\"Microchip PIC\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/deepbluembedded.com\\\/i2c-communication-protocol-tutorial-pic\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/i2c-communication-protocol-tutorial-pic\\\/\",\"url\":\"https:\\\/\\\/deepbluembedded.com\\\/i2c-communication-protocol-tutorial-pic\\\/\",\"name\":\"I2C Communication Protocol Tutorial I2C Bus With PIC Microcontroller\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/i2c-communication-protocol-tutorial-pic\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/i2c-communication-protocol-tutorial-pic\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/deepbluembedded.com\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/I2C-Tutorial-With-PIC-Microcontrollers-Thumbnail.jpg\",\"datePublished\":\"2019-09-11T14:27:34+00:00\",\"dateModified\":\"2023-08-17T20:52:34+00:00\",\"description\":\"What is I2C communication? And how I2C works? And where I2C bus is used? TWI communication basics, bus specifications and standards\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/i2c-communication-protocol-tutorial-pic\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/deepbluembedded.com\\\/i2c-communication-protocol-tutorial-pic\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/i2c-communication-protocol-tutorial-pic\\\/#primaryimage\",\"url\":\"https:\\\/\\\/deepbluembedded.com\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/I2C-Tutorial-With-PIC-Microcontrollers-Thumbnail.jpg\",\"contentUrl\":\"https:\\\/\\\/deepbluembedded.com\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/I2C-Tutorial-With-PIC-Microcontrollers-Thumbnail.jpg\",\"width\":720,\"height\":327,\"caption\":\"I2C Tutorial With PIC Microcontrollers Thumbnail\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/i2c-communication-protocol-tutorial-pic\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/deepbluembedded.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"I2C Communication Protocol Tutorial\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/#website\",\"url\":\"https:\\\/\\\/deepbluembedded.com\\\/\",\"name\":\"DeepBlueMbedded\",\"description\":\"Embedded Systems And Computer Engineering Tutorials &amp; Articles\",\"publisher\":{\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/#\\\/schema\\\/person\\\/30259d66cf68c6c681562dbe551b7867\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/deepbluembedded.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/deepbluembedded.com\\\/#\\\/schema\\\/person\\\/30259d66cf68c6c681562dbe551b7867\",\"name\":\"Khaled Magdy\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g\",\"caption\":\"Khaled Magdy\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g\"},\"description\":\"Principal Embedded Systems Engineer with years of experience in embedded software and hardware design. I work in the Automotive &amp; e-Mobility industry. However, I still do Hardware design and SW development for DSP, Control Systems, Robotics, AI\\\/ML, and other fields I'm passionate about. I love reading, writing, creating projects, and teaching. A reader by day and a writer by night, it's my lifestyle. I believe that the combination of brilliant minds, bold ideas, and a complete disregard for what is possible, can and will change the world! I will be there when it happens, will you?\",\"sameAs\":[\"https:\\\/\\\/deepbluembedded.com\",\"https:\\\/\\\/www.facebook.com\\\/khaled.elrawy.359\\\/\",\"https:\\\/\\\/www.instagram.com\\\/deepbluembedded\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/khaled-magdy-\\\/\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCzLSrNZD4rCjSCOVU9hknvA\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"I2C Communication Protocol Tutorial I2C Bus With PIC Microcontroller","description":"What is I2C communication? And how I2C works? And where I2C bus is used? TWI communication basics, bus specifications and standards","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/","og_locale":"en_US","og_type":"article","og_title":"I2C Communication Protocol Tutorial I2C Bus With PIC Microcontroller","og_description":"What is I2C communication? And how I2C works? And where I2C bus is used? TWI communication basics, bus specifications and standards","og_url":"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/","og_site_name":"DeepBlue","article_publisher":"https:\/\/www.facebook.com\/khaled.elrawy.359\/","article_author":"https:\/\/www.facebook.com\/khaled.elrawy.359\/","article_published_time":"2019-09-11T14:27:34+00:00","article_modified_time":"2023-08-17T20:52:34+00:00","og_image":[{"width":720,"height":327,"url":"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Tutorial-With-PIC-Microcontrollers-Thumbnail.jpg","type":"image\/jpeg"}],"author":"Khaled Magdy","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Khaled Magdy","Est. reading time":"62 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/#article","isPartOf":{"@id":"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/"},"author":{"name":"Khaled Magdy","@id":"https:\/\/deepbluembedded.com\/#\/schema\/person\/30259d66cf68c6c681562dbe551b7867"},"headline":"I2C Communication Protocol Tutorial","datePublished":"2019-09-11T14:27:34+00:00","dateModified":"2023-08-17T20:52:34+00:00","mainEntityOfPage":{"@id":"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/"},"wordCount":11032,"commentCount":0,"publisher":{"@id":"https:\/\/deepbluembedded.com\/#\/schema\/person\/30259d66cf68c6c681562dbe551b7867"},"image":{"@id":"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/#primaryimage"},"thumbnailUrl":"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Tutorial-With-PIC-Microcontrollers-Thumbnail.jpg","articleSection":["Embedded Systems","Embedded Tutorials","Microchip PIC"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/","url":"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/","name":"I2C Communication Protocol Tutorial I2C Bus With PIC Microcontroller","isPartOf":{"@id":"https:\/\/deepbluembedded.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/#primaryimage"},"image":{"@id":"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/#primaryimage"},"thumbnailUrl":"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Tutorial-With-PIC-Microcontrollers-Thumbnail.jpg","datePublished":"2019-09-11T14:27:34+00:00","dateModified":"2023-08-17T20:52:34+00:00","description":"What is I2C communication? And how I2C works? And where I2C bus is used? TWI communication basics, bus specifications and standards","breadcrumb":{"@id":"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/#primaryimage","url":"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Tutorial-With-PIC-Microcontrollers-Thumbnail.jpg","contentUrl":"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Tutorial-With-PIC-Microcontrollers-Thumbnail.jpg","width":720,"height":327,"caption":"I2C Tutorial With PIC Microcontrollers Thumbnail"},{"@type":"BreadcrumbList","@id":"https:\/\/deepbluembedded.com\/i2c-communication-protocol-tutorial-pic\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/deepbluembedded.com\/"},{"@type":"ListItem","position":2,"name":"I2C Communication Protocol Tutorial"}]},{"@type":"WebSite","@id":"https:\/\/deepbluembedded.com\/#website","url":"https:\/\/deepbluembedded.com\/","name":"DeepBlueMbedded","description":"Embedded Systems And Computer Engineering Tutorials &amp; Articles","publisher":{"@id":"https:\/\/deepbluembedded.com\/#\/schema\/person\/30259d66cf68c6c681562dbe551b7867"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/deepbluembedded.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/deepbluembedded.com\/#\/schema\/person\/30259d66cf68c6c681562dbe551b7867","name":"Khaled Magdy","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g","caption":"Khaled Magdy"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/a8b5dc7385ec807e129b584974394d27e41c9979f3a2d0fd785b552b73529032?s=96&r=g"},"description":"Principal Embedded Systems Engineer with years of experience in embedded software and hardware design. I work in the Automotive &amp; e-Mobility industry. However, I still do Hardware design and SW development for DSP, Control Systems, Robotics, AI\/ML, and other fields I'm passionate about. I love reading, writing, creating projects, and teaching. A reader by day and a writer by night, it's my lifestyle. I believe that the combination of brilliant minds, bold ideas, and a complete disregard for what is possible, can and will change the world! I will be there when it happens, will you?","sameAs":["https:\/\/deepbluembedded.com","https:\/\/www.facebook.com\/khaled.elrawy.359\/","https:\/\/www.instagram.com\/deepbluembedded\/","https:\/\/www.linkedin.com\/in\/khaled-magdy-\/","https:\/\/www.youtube.com\/channel\/UCzLSrNZD4rCjSCOVU9hknvA"]}]}},"jetpack_featured_media_url":"https:\/\/deepbluembedded.com\/wp-content\/uploads\/2019\/09\/I2C-Tutorial-With-PIC-Microcontrollers-Thumbnail.jpg","jetpack_shortlink":"https:\/\/wp.me\/p9SirL-X7","jetpack-related-posts":[{"id":2555,"url":"https:\/\/deepbluembedded.com\/embedded-systems-tutorials-final-episode\/","url_meta":{"origin":3665,"position":0},"title":"Embedded Systems Tutorials With PIC MCUs | Final Episode","author":"Khaled Magdy","date":"April 3, 2019","format":false,"excerpt":"Previous Tutorial End of The 1st Edition Next Tutorial Concluding The 1st Edition Of Embedded Systems Tutorials (With PIC MCUs) \u00a0 Congratulations to everyone who have been following my embedded systems tutorials up to this point. Up till now, you've approached reading ~100k words of tutorials. That's a lot of\u2026","rel":"","context":"In &quot;Embedded Systems&quot;","block_context":{"text":"Embedded Systems","link":"https:\/\/deepbluembedded.com\/embedded-systems\/"},"img":{"alt_text":"Embedded Systems Tutorials Edition1 End","src":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2019\/04\/Embedded-Systems-Tutorials-Edition1-End.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2019\/04\/Embedded-Systems-Tutorials-Edition1-End.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2019\/04\/Embedded-Systems-Tutorials-Edition1-End.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2019\/04\/Embedded-Systems-Tutorials-Edition1-End.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":1884,"url":"https:\/\/deepbluembedded.com\/creating-new-project-with-mplab\/","url_meta":{"origin":3665,"position":1},"title":"Creating New Project With MPLAB","author":"Khaled Magdy","date":"June 22, 2018","format":false,"excerpt":"In this tutorial, we'll learn how to create a new project in MPLAB and how to add the basic code files. Just stick with me through the following steps.","rel":"","context":"In &quot;Embedded Systems&quot;","block_context":{"text":"Embedded Systems","link":"https:\/\/deepbluembedded.com\/embedded-systems\/"},"img":{"alt_text":"Creating New Project With MPLAB IDE","src":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/Creating-New-Project-With-MPLAB-IDE.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/Creating-New-Project-With-MPLAB-IDE.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/Creating-New-Project-With-MPLAB-IDE.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2018\/06\/Creating-New-Project-With-MPLAB-IDE.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":2085,"url":"https:\/\/deepbluembedded.com\/how-to-write-isr-handlers\/","url_meta":{"origin":3665,"position":2},"title":"How To Write ISR Handlers","author":"Khaled Magdy","date":"July 15, 2018","format":false,"excerpt":"In this tutorial, we'll discuss a few guidelines to follow while writing ISR handlers. Which you can use as a guide for the upcoming tutorials. Let's see how to properly write ISR handlers!","rel":"","context":"In &quot;Embedded Systems&quot;","block_context":{"text":"Embedded Systems","link":"https:\/\/deepbluembedded.com\/embedded-systems\/"},"img":{"alt_text":"How To Write ISR Handlers - Embedded Systems Tutorials With PIC Microcontrollers","src":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/How-To-Write-ISR-Handlers-Embedded-Systems-Tutorials-With-PIC-Microcontrollers.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/How-To-Write-ISR-Handlers-Embedded-Systems-Tutorials-With-PIC-Microcontrollers.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/How-To-Write-ISR-Handlers-Embedded-Systems-Tutorials-With-PIC-Microcontrollers.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/How-To-Write-ISR-Handlers-Embedded-Systems-Tutorials-With-PIC-Microcontrollers.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":1983,"url":"https:\/\/deepbluembedded.com\/interfacing-7-segments-display-with-pic-microcontrollers\/","url_meta":{"origin":3665,"position":3},"title":"Interfacing 7-Segments Display With PIC Microcontrollers","author":"Khaled Magdy","date":"July 4, 2018","format":false,"excerpt":"In this tutorial, you'll learn how do 7-segments displays work, and how to interface 7-segments display with PIC microcontrollers. The 7-segments display needs a little bit of programming effort and it's pretty easy & straightforward. So let's get started!","rel":"","context":"In &quot;Electronics&quot;","block_context":{"text":"Electronics","link":"https:\/\/deepbluembedded.com\/electronics\/"},"img":{"alt_text":"How To Interface 7-Segments Display With Microcontrollers","src":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/How-To-Interface-7-Segments-Display-With-Microcontrollers.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/How-To-Interface-7-Segments-Display-With-Microcontrollers.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/How-To-Interface-7-Segments-Display-With-Microcontrollers.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2018\/07\/How-To-Interface-7-Segments-Display-With-Microcontrollers.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":6769,"url":"https:\/\/deepbluembedded.com\/stm32-i2c-scanner-hal-code-example\/","url_meta":{"origin":3665,"position":4},"title":"STM32 I2C Scanner HAL Code Example","author":"Khaled Magdy","date":"April 17, 2021","format":false,"excerpt":"Previous Tutorial Tutorial 45 Next Tutorial STM32 I2C Scanner Example STM32 Course Home Page ???? In this short tutorial, we'll be creating an STM32 I2C Scanner example project. To check for the connected slave devices on the I2C bus and report their addresses over UART to our PC. The I2C\u2026","rel":"","context":"In &quot;Embedded Systems&quot;","block_context":{"text":"Embedded Systems","link":"https:\/\/deepbluembedded.com\/embedded-systems\/"},"img":{"alt_text":"STM32 I2C Scanner HAL Example Code","src":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2021\/04\/STM32-I2C-Scanner-HAL-Example-Code.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2021\/04\/STM32-I2C-Scanner-HAL-Example-Code.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2021\/04\/STM32-I2C-Scanner-HAL-Example-Code.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2021\/04\/STM32-I2C-Scanner-HAL-Example-Code.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2021\/04\/STM32-I2C-Scanner-HAL-Example-Code.jpg?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":2563,"url":"https:\/\/deepbluembedded.com\/spi-tutorial-with-pic-microcontrollers\/","url_meta":{"origin":3665,"position":5},"title":"SPI Tutorial With PIC Microcontrollers | Serial Peripheral Interface","author":"Khaled Magdy","date":"February 12, 2019","format":false,"excerpt":"In this tutorial, we'll be discussing the SPI (serial peripheral interface) bus. How it works and how to establish serial communication between 2 PIC microcontrollers via SPI","rel":"","context":"In &quot;Electronics&quot;","block_context":{"text":"Electronics","link":"https:\/\/deepbluembedded.com\/electronics\/"},"img":{"alt_text":"SPI Tutorial - PIC Microcontrollers","src":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2019\/02\/SPI-Tutorial-PIC-Microcontrollers.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2019\/02\/SPI-Tutorial-PIC-Microcontrollers.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2019\/02\/SPI-Tutorial-PIC-Microcontrollers.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/deepbluembedded.com\/wp-content\/uploads\/2019\/02\/SPI-Tutorial-PIC-Microcontrollers.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/posts\/3665","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/comments?post=3665"}],"version-history":[{"count":59,"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/posts\/3665\/revisions"}],"predecessor-version":[{"id":4169,"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/posts\/3665\/revisions\/4169"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/media\/3738"}],"wp:attachment":[{"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/media?parent=3665"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/categories?post=3665"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/deepbluembedded.com\/wp-json\/wp\/v2\/tags?post=3665"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}