I2C COMMUNICATION WITH PIC MICROCONTROLLERI²C stands for Inter-Integrated Circuit. It is a short distance serial interface that requires only two bus lines for bi-directional data transfer. It is used for attaching lower speed peripheral ICs to microcontrollers in short distance communication. Low speed peripherals include external EEPROMs, digital sensors, lcd, etc.

I2C communication PROTOCOL 

I²Cprotocol was invented by Philips semiconductors in 1980’s, to provide easy on-board communications between a CPU and various peripheral chips.I²C protocol uses 2 signal lines, a serial data line (SDA) and a serial clock line (SCL). Any number of slaves and any number of masters can be connected onto these 2 signals.

SDA line:        Any data sent from one device to another goes through the SDA line.
SCL line:        It provides the necessary synchronization clock for the data transfer.

Data is sent either direction on the serial data line (SDA) by the master or slave.Only a Master can start a data transfer and Slaves respond to the Master. It is possible to have multiple Masters on a common bus, but only one could be active at a time. The SCL clock line is always driven by the master. I2C COMMUNICATION

Both SCL and SDA lines are open drain drivers and are connected to a positive supply voltage through pull-up resistors. I²Cdevices can only pull the line low, they cannot drive it high. When no device is pulling on the line, it will float high through the pull-up resistor. This is the reasonof why pull-up resistors are important in I²C.


Each I²C command initiated by master device starts with a START condition and ends with a STOP condition. For both conditions SCL has to be high. After the Start condition the bus is considered busy and can be used by another master only after a Stop condition is detected.

Start condition:A high to low transition of SDA.
Stop condition: Alow to high transition of SDA.

i2c start and stop bits condition

I2C  communication DEVICE ADDRESSING

Each slave connected to the bus is software addressable by a unique 7-bit or 10-bit.

7-bit Device Addressing:

After the Start condition,the first byte sent is known as Control byte. The first seven bits of the control byte make up the slave address.

7 bit device addressing

  • The first four bits are fixed.
  • The next three bits are set by hardware address pins (A0, A1, and A2) which allow the user to modify the I²C address. It allows up to eight devices to operate on the I²C bus.
  • The eighth bit (LSB) is a data direction bit (R/W)
  • ‘0’ in LSB indicates that the Master will writeinformation to a selected slave
  • ‘1’ in LSB indicates that the Master will read data from the slave
  • When the receiver gets its address, it has to generate the Acknowledge signal. During this state the transmitter should release the SDA bus to allow the receiver to derive it. When receiver drives the SDA signal low it acknowledges that the address byte has been received.If the receiver does not drive SDA low, the condition is a no-acknowledge (NACK) and the operation is aborted

Acknowledge              0 volts

No Acknowledge        High volts.

When a control byte is sent,each device/slave in the system compares the first seven receiving bits with its address. If the address gets matched, the device considers itself addressed by the master. Now, it will behave as slave-receiver or slave-transmitter depending upon the value of the R/W bit.

10-bit Device Addressing:

Every I²C device must have built-in 7 bits address. So according to this, there would be only 128 different I²C device types in the world. But there are much more different I²C devices and there is a high probability that 2 devices have the same address on I²C bus. To overcome this problem, devices often have multiple built-in addresses that we can selectthrough external configuration pins on the device. To extend the range of available devices address, the I²C specification deduces a 10-bits addressing scheme.

i2c communication 10 bit device addressing

  • Instead of one, thetwo address words are used for device addressing.
  • The first address word contains conventional code as “11110” on MSBsto aware the slaves on the bus of 10-bits device address. After that it contains two MSBs of 10-bit address and Rd/Wr bit.
  • The second address word contains 8 least significant bits (LSBs) of 10-bit address. So this addition of bits ensures the backward compatibility with 7-bit addressing scheme.

I2C communication DATA TRANSFER:

The byte put on the SDA line must be 8-bits long. The data is sent on the SDA line.The most significant bit (MSB) is sent first and the SCL line produces a synchronization clock. The data on the SDA line is considered valid when SCL is high. The high or low state of the data line can only be change when the clock signal on the SCL line is LOW.

If the slave is not in a position to receive or transmit another complete byte of data it can hold the SCL line low to force the master into a wait state. Data transfer continues when the slave is ready for another byte of data and releases the clock line.To terminate the data transfer, a stop condition is generated by the master. And if master still wishes to communicate on the bus it can generate another slave address along with repeated start condition without generating first stop condition.

For I2C bus, clock speedcan be chosen between

  • 100 Kbps in standard mode
  • 400 Kbps in fast mode
  • Up to 3.4 Mbps in high-speed mode

I2C communication interfacing  with PIC MICROCONTROLLER:

Microcontrollers are known as standalone chips as they have internal memory and processor embedded. The memory stores the code and other temporary variables for the execution of program. Despite of that memory, we can use a non-volatile memory (permanent data storing) which is mainly the I2C device with microcontrollers. Now we will interface that I2C device with Pic microcontroller PIC16F877A .We can use the I2C library in MikroC for Pic MCU but only if Pic MCU is behaving as master not as slave.

I2C communication Library

I2C program library

For initialization:         I²C module is initialized on the RC3 (SCL) and RC4 (SDA) by I2C1_Init(100000);

Some MCUs have multiple I²C modules. In order to use the desired I²C library routine, we simply change the number 1 in the prototype with the appropriate module number, i.e. I2C1_Init(100000);

I2C1_Init:                              Initializes I²C with desired clock.It needs to be called before using other functions of I²C Library.

I2C1_Start:                            Determines if I²C bus is free and issues START signal.

I2C1_Repeated_Start:          Issues repeated START signal.

I2C1_Is_Idle:                         Tests if I²C bus is free.

I2C1_Rd:                                         Reads one byte from the slave and sends not acknowledge signal if parameter ack is 0, otherwise it sends acknowledge.

I2C1_Wr:                               Sends data byte (parameter data) via I²C bus.

I2C1_Stop:                             Issues STOP signal.

I2C communication with pic microcontroller circuit diagram overview

i2c communication with pic microcontroller

Here we are using 24C64 EEPROM (an I2C device) as a slave. In this tutorial we will examine how to write and read data from I2C device and show the output on some LCD or LEDs. In Proteus we need to connect I2C Debugger. SCL and SDA of I2C Debugger should be connected in parallel to SCL and SDA of 24C64. I2C Debugger can be found where CRO can be found in Proteus.

SDA: RC4 (Master) to 5 (Slave)

SCL: RC3 (Master) to 6 (Slave)

To display the output: LEDs are connected on PORT B.

We write 00000001 to the first memory location, 00000010 to secondand 000000100 to third and then so on sequentially up to 10000000. Then it is read sequentially and output (write) through PORTB.

CODE of I2C communication with PIC microcontroller

voidwrite_EEPROM(unsigned int address, unsigned intdat)


unsignedint temp;

  I2C1_Start();            // issue I2C start signal

  I2C1_Wr(0xA0);           // send byte via I2C (device address + W)

temp = address >> 8;     //saving higher order address to temp

  I2C1_Wr(temp);           //sending higher order address

  I2C1_Wr(address);        //sending lower order address

  I2C1_Wr(dat);            // send data (data to be written)

  I2C1_Stop();             // issue I2C stop signal



unsignedintread_EEPROM(unsigned int address)


unsignedint temp;

  I2C1_Start();            // issue I2C start signal



  I2C1_Wr(temp);           //sending higher order address

  I2C1_Wr(address);        //sending lower order address

  I2C1_Repeated_Start();   // issue I2C signal repeated start

  I2C1_Wr(0xA1);           // send byte (device address + R)

temp = I2C1_Rd(0u);      // Read the data (NO acknowledge)


return temp;


void main()


unsignedint a, i;

TRISB  = 0;             // To make it output port

   PORTB = 0;              // To make it output port

   CMCON = 0x07;           // To turn off comparators

   ADCON1 = 0x06;          // To turn off analog to digital converters






write_EEPROM(i, a);


        a = a<<1;




         PORTB = read_EEPROM(i);





Check simulation:

I2C vs SPI

The drawback of SPI is the number of pins required.SPI bus requires four lines in connecting a single master to a single slave. Along with this, each additional slave requires one additional chip select pin on the master. The increase of pin connections makes it undesirable in situations where lots of devices must be slaved to one master. SPI only allows one master on the bus, but it does support an arbitrary number of slaves. By reading the whole article one can easily understands that I2C can compensate all these drawbacks of SPI.


  1. Hi Bilal i am new to pic and i am using pic16f877a uc. I have a doubt is the I2C library in Built in Mickro ide or we should install it separately. If it should be installed separately can you please assist

Leave a Comment