Software I²C Library
The mikroC PRO for AVR provides routines for implementing Software I²C communication. These routines are hardware independent and can be used with any MCU. The Software I²C library enables you to use MCU as Master in I²C communication. Multi-master mode is not supported.

- This library implements time-based activities, so interrupts need to be disabled when using Software I²C.
- All I²C Library functions are blocking-call functions (they are waiting for I²C clock line to become logical one).
- The pins used for the Software I²C communication should be connected to the pull-up resistors. Turning off the LEDs connected to these pins may also be required.
- Every Software I²C library routine has its own counterpart in Hardware I²C library, except
I2C_Repeated_Start
.Soft_I2C_Start
is used instead ofI2C_Repeated_Start
. - Working clock frequency of the Software I²C is 20kHz.
External dependencies of Software I²C Library
The following variables must be defined in all projects using Software I²C Library: | Description : | Example : |
---|---|---|
extern sbit Soft_I2C_Scl_Output; |
Soft I²C Clock output line. | sbit Soft_I2C_Scl_Output at PORTC0_bit; |
extern sbit Soft_I2C_Sda_Output; |
Soft I²C Data output line. | sbit Soft_I2C_Sda_Output at PORTC1_bit; |
extern sbit Soft_I2C_Scl_Input; |
Soft I²C Clock input line. | sbit Soft_I2C_Scl_Input at PINC0_bit; |
extern sbit Soft_I2C_Sda_Input; |
Soft I²C Data input line. | sbit Soft_I2C_Sda_Input at PINC1_bit; |
extern sbit Soft_I2C_Scl_Direction; |
Direction of the Soft I²C Clock pin. | sbit Soft_I2C_Scl_Direction at DDC0_bit; |
extern sbit Soft_I2C_Sda_Direction; |
Direction of the Soft I²C Data pin. | sbit Soft_I2C_Sda_Direction at DDC1_bit; |
Library Routines
Soft_I2C_Init
Prototype |
void Soft_I2C_Init(); |
---|---|
Returns |
Nothing. |
Description |
Configures the software I²C module. |
Requires |
Global variables :
|
Example |
// Software I2C connections sbit Soft_I2C_Scl_Output at PORTC0_bit; sbit Soft_I2C_Sda_Output at PORTC1_bit; sbit Soft_I2C_Scl_Input at PINC0_bit; sbit Soft_I2C_Sda_Input at PINC1_bit; sbit Soft_I2C_Scl_Direction at DDC0_bit; sbit Soft_I2C_Sda_Direction at DDC1_bit; // End Software I2C connections ... Soft_I2C_Init(); |
Soft_I2C_Start
Prototype |
void Soft_I2C_Start(void); |
---|---|
Returns |
Nothing. |
Description |
Determines if the I²C bus is free and issues START signal. |
Requires |
Software I²C must be configured before using this function. See Soft_I2C_Init routine. |
Example |
// Issue START signal Soft_I2C_Start(); |
Soft_I2C_Read
Prototype |
unsigned short Soft_I2C_Read(unsigned int ack); |
---|---|
Returns |
One byte from the Slave. |
Description |
Reads one byte from the slave. Parameters :
|
Requires |
Soft I²C must be configured before using this function. See Soft_I2C_Init routine. Also, START signal needs to be issued in order to use this function. See Soft_I2C_Start routine. |
Example |
unsigned short take; ... // Read data and send the not_acknowledge signal take = Soft_I2C_Read(0); |
Soft_I2C_Write
Prototype |
unsigned short Soft_I2C_Write(unsigned short data_); |
---|---|
Returns |
|
Description |
Sends data byte via the I²C bus. Parameters :
|
Requires |
Soft I²C must be configured before using this function. See Soft_I2C_Init routine. Also, START signal needs to be issued in order to use this function. See Soft_I2C_Start routine. |
Example |
unsigned short data_, error; ... error = Soft_I2C_Write(data_); error = Soft_I2C_Write(0xA3); |
Soft_I2C_Stop
Prototype |
void Soft_I2C_Stop(void); |
---|---|
Returns |
Nothing. |
Description |
Issues STOP signal. |
Requires |
Soft I²C must be configured before using this function. See Soft_I2C_Init routine. |
Example |
// Issue STOP signal Soft_I2C_Stop(); |
Soft_I2C_Break
Prototype |
void Soft_I2C_Break(void); |
---|---|
Returns |
Nothing. |
Description |
All Software I²C Library functions can block the program flow (see note at the top of this page). Calling this routine from interrupt will unblock the program execution. This mechanism is similar to WDT. ![]() |
Requires | Nothing. |
Example |
// Software I2C connections sbit Soft_I2C_Scl_Output at PORTC0_bit; sbit Soft_I2C_Sda_Output at PORTC1_bit; sbit Soft_I2C_Scl_Input at PINC0_bit; sbit Soft_I2C_Sda_Input at PINC1_bit; sbit Soft_I2C_Scl_Direction at DDC0_bit; sbit Soft_I2C_Sda_Direction at DDC1_bit; // End Software I2C connections char counter = 0; void Timer0Overflow_ISR() org 0x12 { if (counter >= 20) { Soft_I2C_Break(); counter = 0; // reset counter } else counter++; // increment counter } void main() { TOIE0_bit = 1; // Timer0 overflow interrupt enable TCCR0_bit = 5; // Start timer with 1024 prescaler SREG_I_bit = 0; // Interrupt disable ... // try Soft_I2C_Init with blocking prevention mechanism SREG_I_bit = 1; // Interrupt enable Soft_I2C_Init(); SREG_I_bit = 0; // Interrupt disable ... } |
Library Example
The example demonstrates Software I²C Library routines usage. The AVR MCU is connected (SCL, SDA pins) to PCF8583 RTC (real-time clock). Program reads date and time are read from the RTC and prints it on Lcd.
char seconds, minutes, hours, day, month, year; // Global date/time variables // Software I2C connections sbit Soft_I2C_Scl_Output at PORTC0_bit; sbit Soft_I2C_Sda_Output at PORTC1_bit; sbit Soft_I2C_Scl_Input at PINC0_bit; sbit Soft_I2C_Sda_Input at PINC1_bit; sbit Soft_I2C_Scl_Direction at DDC0_bit; sbit Soft_I2C_Sda_Direction at DDC1_bit; // End Software I2C connections // LCD module connections sbit LCD_RS at PORTD2_bit; sbit LCD_EN at PORTD3_bit; sbit LCD_D4 at PORTD4_bit; sbit LCD_D5 at PORTD5_bit; sbit LCD_D6 at PORTD6_bit; sbit LCD_D7 at PORTD7_bit; sbit LCD_RS_Direction at DDD2_bit; sbit LCD_EN_Direction at DDD3_bit; sbit LCD_D4_Direction at DDD4_bit; sbit LCD_D5_Direction at DDD5_bit; sbit LCD_D6_Direction at DDD6_bit; sbit LCD_D7_Direction at DDD7_bit; // End LCD module connections //--------------------- Reads time and date information from RTC (PCF8583) void Read_Time() { Soft_I2C_Start(); // Issue start signal Soft_I2C_Write(0xA0); // Address PCF8583, see PCF8583 datasheet Soft_I2C_Write(2); // Start from address 2 Soft_I2C_Start(); // Issue repeated start signal Soft_I2C_Write(0xA1); // Address PCF8583 for reading R/W=1 seconds = Soft_I2C_Read(1); // Read seconds byte minutes = Soft_I2C_Read(1); // Read minutes byte hours = Soft_I2C_Read(1); // Read hours byte day = Soft_I2C_Read(1); // Read year/day byte month = Soft_I2C_Read(0); // Read weekday/month byte Soft_I2C_Stop(); // Issue stop signal } //-------------------- Formats date and time void Transform_Time() { seconds = ((seconds & 0xF0) >> 4)*10 + (seconds & 0x0F); // Transform seconds minutes = ((minutes & 0xF0) >> 4)*10 + (minutes & 0x0F); // Transform months hours = ((hours & 0xF0) >> 4)*10 + (hours & 0x0F); // Transform hours year = (day & 0xC0) >> 6; // Transform year day = ((day & 0x30) >> 4)*10 + (day & 0x0F); // Transform day month = ((month & 0x10) >> 4)*10 + (month & 0x0F); // Transform month } //-------------------- Output values to LCD void Display_Time() { Lcd_Chr(1, 6, (day / 10) + 48); // Print tens digit of day variable Lcd_Chr(1, 7, (day % 10) + 48); // Print oness digit of day variable Lcd_Chr(1, 9, (month / 10) + 48); Lcd_Chr(1,10, (month % 10) + 48); Lcd_Chr(1,15, year + 56); // Print year vaiable + 8 (start from year 2008) Lcd_Chr(2, 6, (hours / 10) + 48); Lcd_Chr(2, 7, (hours % 10) + 48); Lcd_Chr(2, 9, (minutes / 10) + 48); Lcd_Chr(2,10, (minutes % 10) + 48); Lcd_Chr(2,12, (seconds / 10) + 48); Lcd_Chr(2,13, (seconds % 10) + 48); } //------------------ Performs project-wide init void Init_Main() { Soft_I2C_Init(); // Initialize Soft I2C communication Lcd_Init(); // Initialize LCD Lcd_Cmd(_LCD_CLEAR); // Clear LCD display Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off Lcd_Out(1,1,"Date:"); // Prepare and output static text on LCD Lcd_Chr(1,8,':'); Lcd_Chr(1,11,':'); Lcd_Out(2,1,"Time:"); Lcd_Chr(2,8,':'); Lcd_Chr(2,11,':'); Lcd_Out(1,12,"200"); } //----------------- Main procedure void main() { Init_Main(); // Perform initialization while (1) { // Endless loop Read_Time(); // Read time from RTC(PCF8583) Transform_Time(); // Format date and time Display_Time(); // Prepare and display on LCD Delay_ms(1000); // Wait 1 second } }
What do you think about this topic ? Send us feedback!