Basics of I2C Communication | Hardware, Data Transfer, Configuration - JohnHau/mis GitHub Wiki
In this article, we will learn about what I2C communication protocol is, its hardware, how data is transferred and different configurations in which it operates.
Introduction to I2C Communication I2C communication is the short form for inter-integrated circuits. It is a communication protocol developed by Philips Semiconductors for the transfer of data between a central processor and multiple ICs on the same circuit board using just two common wires.
Owing to its simplicity, it is widely adopted for communication between microcontrollers and sensor arrays, displays, IoT devices, EEPROMs etc.
This is a type of synchronous serial communication protocol. It means that data bits are transferred one by one at regular intervals of time set by a reference clock line.
Features The following are some of the important features of I2C communication protocol:
Only two common bus lines (wires) are required to control any device/IC on the I2C network No need of prior agreement on data transfer rate like in UART communication. So the data transfer speed can be adjusted whenever required Simple mechanism for validation of data transferred Uses 7-bit addressing system to target a specific device/IC on the I2C bus I2C networks are easy to scale. New devices can simply be connected to the two common I2C bus lines
Hardware The physical I2C Bus I2C Bus (Interface wires) consists of just two wires and are named as Serial Clock Line (SCL) and Serial Data Line (SDA). The data to be transferred is sent through the SDA wire and is synchronized with the clock signal from SCL. All the devices/ICs on the I2C network are connected to the same SCL and SDA lines as shown below:
Both the I2C bus lines (SDA, SCL) are operated as open drain drivers. It means that any device/IC on the I2C network can drive SDA and SCL low, but they cannot drive them high. So, a pull up resistor is used for each bus line, to keep them high (at positive voltage) by default.
The reason for using an open-drain system is that there will be no chances of shorting, which might happen when one device tries to pull the line high and some other device tries to pull the line low.
Master and Slave Devices The devices connected to the I2C bus are categorized as either masters or slaves. At any instant of time only a single master stays active on the I2C bus. It controls the SCL clock line and decides what operation is to be done on the SDA data line.
All the devices that respond to instructions from this master device are slaves. For differentiating between multiple slave devices connected to the same I2C bus, each slave device is physically assigned a permanent 7-bit address.
When a master device wants to transfer data to or from a slave device, it specifies this particular slave device address on the SDA line and then proceeds with the transfer. So effectively communication takes place between the master device and a particular slave device.
All the other slave devices doesn’t respond unless their address is specified by the master device on the SDA line.
Data Transfer Protocol The following protocol (set of rules) is followed by master device and slave devices for the transfer of data between them.
Data is transferred between the master device and slave devices through a single SDA data line, via patterned sequences of 0’s and 1’s (bits). Each sequence of 0’s and 1’s is termed as a transaction and the data in each transaction is structured as below:
Start Condition Whenever a master device/IC decides to start a transaction, it switches the SDA line from high voltage level to a low voltage level before the SCL line switches from high to low.
Once a start condition is sent by the master device, all the slave devices get active even if they are in sleep mode, and wait for the address bits.
Address Block It comprises of 7 bits and are filled with the address of slave device to/from which the master device needs send/receive data. All the slave devices on the I2C bus compare these address bits with their address.
Read/Write Bit This bit specifies the direction of data transfer. If the master device/IC need to send data to a slave device, this bit is set to ‘0’. If the master IC needs to receive data from the slave device, it is set to ‘1’.
ACK/NACK Bit It stands for Acknowledged/Not-Acknowledged bit. If the physical address of any slave device coincides with the address broadcasted by the master device, the value of this bit is set to ‘0’ by the slave device. Otherwise it remains at logic ‘1’ (default).
Data Block It comprises of 8 bits and they are set by the sender, with the data bits it needs to transfer to the receiver. This block is followed by an ACK/NACK bit and is set to ‘0’ by the receiver if it successfully receives data. Otherwise it stays at logic ‘1’.
This combination of data block followed by ACK/NACK bit is repeated until the data is completely transferred.
Stop Condition After required data blocks are transferred through the SDA line, the master device switches the SDA line from low voltage level to high voltage level before the SCL line switches from high to low.
NOTE: Logic ‘0’ or setting a bit to ‘0’ is equivalent to applying low voltage on the SDA line and vice versa.
How I2C Communication Practically Works? An I2C communication/transaction is initiated by a master device either to send data to a slave device or to receive data from it. Let us learn about working of both the scenarios in detail.
Sending Data to a Slave Device The following sequence of operations take place when a master device tries to send data to a particular slave device through I2C bus:
The master device sends the start condition The master device sends the 7 address bits which corresponds to the slave device to be targeted The master device sets the Read/Write bit to ‘0’, which signifies a write Now two scenarios are possible: If no slave device matches with the address sent by the master device, the next ACK/NACK bit stays at ‘1’ (default). This signals the master device that the slave device identification is unsuccessful. The master clock will end the current transaction by sending a Stop condition or a new Start condition If a slave device exists with the same address as the one specified by the master device, the slave device sets the ACK/NACK bit to ‘0’, which signals the master device that a slave device is successfully targeted If a slave device is successfully targeted, the master device now sends 8 bits of data which is only considered and received by the targeted slave device. This data means nothing to the remaining slave devices If the data is successfully received by the slave device, it sets the ACK/NACK bit to ‘0’, which signals the master device to continue The previous two steps are repeated until all the data is transferred After all the data is sent to the slave device, the master device sends the Stop condition which signals all the slave devices that the current transaction has ended The below figure represents the overall data bits sent on the SDA line and the device that controls each of them:
Reading Data from a Slave Device The sequence of operations remain the same as in previous scenario except for the following:
The master device sets the Read/Write bit to ‘1’ instead of ‘0’ which signals the targeted slave device that the master device is expecting data from it The 8 bits corresponding to the data block are sent by the slave device and the ACK/NACK bit is set by the master device Once the required data is received by the master device, it sends a NACK bit. Then the slave device stops sending data and releases the SDA line If the master device to read data from specific internal location of a slave device, it first sends the location data to the slave device using the steps in previous scenario. It then starts the process of reading data with a repeated start condition.
The below figure represents the overall data bits sent on the SDA line and the device that controls each of them:
Concept of clock stretching Let say the master device started a transaction and sent address bits of a particular slave device followed by a Read bit of ‘1’. The specific slave device needs to send an ACK bit, immediately followed by data.
But if the slave device needs some time to fetch and send data to master device, during this gap, the master device will think that the slave device is sending some data.
To prevent this, the slave device holds the SCL clock line low until it is ready to transfer data bits. By doing this, the slave device signals the master device to wait for data bits until the clock line is released.
That’s it for this article. Take a look at the below projects to get an idea on how I2C communication is practically implemented, between microcontrollers/Arduinos and different sensors:
RFID Based Car Parking System
Interfacing Arduino With a Motion Processor Unit
Interfacing Arduino With Real-Time Clock