Inter IC Communication or I2C is a two wire serial communication bus used to connect a variety of external peripheral with a microcontroller. Most common are EEPROMs, RTC, Port Expanders etc. Most leading MCUs comes with at least one dedicated I2C host adaptor built in. But some times we need more than one I2C interface or we need I2C lines on some other i/o pins than those allotted to the hardware I2C, in that case we need to go with a solution called SoftI2C. In SoftI2C the I2C signals are handled in software, the advantage is that any two i/o line of the MCU can be used for communication. The drawback is that it need more CPU cycles are wasted in generating the signal thus less time slice is available to the application.
In this article we will present our open source, flexible and easy to use SoftI2C library. This library can be used to connect any I2C slave device with an AVR (and latter PIC MCU) MCU. Some limitations of the library are :-
- No Multimaster support.
- No clock stretching support.
But you can connect multiple number of I2C Slaves on the same bus.
![]() |
I2C Master/Slave Connection |
The Soft I2C Library for AVR
The soft I2C library for AVR comes in two files.
The configuration section lets you choose the I/O lines used for SDA and SCL. You can edit the i2csoft.h file's I/O Configuration area to do that. The library can be compiled for almost any AVR device like ATmega8,ATmega168,ATmega328 etc.
API Reference.
SoftI2CInit() Description: |
SoftI2CStart() Description: |
SoftI2CStop() Description: |
SoftI2CWriteByte() Description: |
SoftI2CReadByte() Description: |
In next tutorial I will show you how to interface a I2C EEPROM, Temperature Sensor, RTC, Port Expander etc using our Soft I2C library.
Download
Help Us!
We try to publish beginner friendly tutorials for latest subjects in embedded system as fast as we can. If you like these tutorials and they have helped you solve problems, please help us in return. You can donate any amount as you like securely using a Credit or Debit Card or Paypal.
We would be very thankful for your kind help.
By
Avinash Gupta
Facebook,
Follow on Twitter.
www.AvinashGupta.com
me@avinashgupta.com



can u tell us the basics of developing codes for three axis accelerometer as early as possible…….
while((SCLPIN & (1<<SCL))==0);
why this is nececery in write byte section in code??
This software is like other ones? With intended errors?
It’s an rhetorical question, you don’t need to answer.
continuous reading bytes from a slave (e.g. PCF8583 RTC) does not work because of a software-bug in the library:
After performing the read-ack. the AVR does not release the SDA-wire.
Therefore an additional
” SOFT_I2C_SDA_HIGH;” is necessary after the reading routine finished:
uint8_t SoftI2CReadByte(uint8_t ack)
{
uint8_t data=0×00;
uint8_t i;
for(i=0;i<8;i++)
{
SOFT_I2C_SCL_LOW;
H_DEL;
SOFT_I2C_SCL_HIGH;
H_DEL;
while((SCLPIN & (1<<SCL))==0);
if(SDAPIN &(1<>i);
}
SOFT_I2C_SCL_LOW;
Q_DEL; //Soft_I2C_Put_Ack
if(ack)
{
//H_DEL;
SOFT_I2C_SDA_LOW;
}
else
{
SOFT_I2C_SDA_HIGH;
}
H_DEL;
SOFT_I2C_SCL_HIGH;
H_DEL;
SOFT_I2C_SCL_LOW;
H_DEL;
SOFT_I2C_SDA_HIGH; // was missing!!
return data;
}
I was expecting that. I never test this soft but i want to use it. Henry plese can you confirm if it works with the new modifications.
I testet the lib with PIC(MPLab) and AVR(WinAVR) together with a I2C Realtime Clock and it works.
But I dont like the waitstates
therefore better generate a waitstate timer-interrupt and process the bitbanging in a “statemachine”
hey henry thanks for your comment, it saves my lots more time