Software I²C Library
The mikroBasic PRO for dsPIC30/33 and PIC24 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 Software 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 : |
---|---|---|
dim Soft_I2C_Scl as sbit sfr external |
Soft I²C Clock line. | dim Soft_I2C_Scl as sbit at RF3_bit |
dim Soft_I2C_Sda as sbit sfr external |
Soft I²C Data line. | dim Soft_I2C_Sda as sbit at RF2_bit |
dim Soft_I2C_Scl_Direction as sbit sfr external |
Direction of the Soft I²C Clock pin. | dim Soft_I2C_Scl_Direction as sbit at TRISF3_bit |
dim Soft_I2C_Sda_Direction as sbit sfr external |
Direction of the Soft I²C Data pin. | dim Soft_I2C_Sda_Direction as sbit at TRISF2_bit |
Library Routines
Soft_I2C_Init
Prototype |
sub procedure Soft_I2C_Init() |
---|---|
Description |
Configures the software I²C module. |
Parameters |
None. |
Returns |
Nothing. |
Requires |
Global variables :
|
Example |
' Software I2C connections dim Soft_I2C_Scl as sbit at RF3_bit Soft_I2C_Sda as sbit at RF2_bit Soft_I2C_Scl_Direction as sbit at TRISF3_bit Soft_I2C_Sda_Direction as sbit at TRISF2_bit ' End Software I2C connections ... Soft_I2C_Init() |
Notes |
None. |
Soft_I2C_Start
Prototype |
sub procedure Soft_I2C_Start() |
---|---|
Description |
Determines if the I²C bus is free and issues START signal. |
Parameters |
None. |
Returns |
Nothing. |
Requires |
Software I²C must be configured before using this function. See Soft_I2C_Init routine. |
Example |
' Issue START signal Soft_I2C_Start() |
Notes |
None. |
Soft_I2C_Read
Prototype |
sub function Soft_I2C_Read(dim ack as word) as byte |
---|---|
Description |
Reads one byte from the slave. |
Parameters |
|
Returns |
One byte from the Slave. |
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 |
dim take as byte ... ' Read data and send the not_acknowledge signal take = Soft_I2C_Read(0) |
Notes |
None. |
Soft_I2C_Write
Prototype |
sub function Soft_I2C_Write(dim data_ as byte) as byte |
---|---|
Description |
Sends data byte via the I²C bus. |
Parameters |
|
Returns |
|
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 |
dim data_, error as byte ... error = Soft_I2C_Write(data_) error = Soft_I2C_Write($A3) |
Notes |
None. |
Soft_I2C_Stop
Prototype |
sub procedure Soft_I2C_Stop() |
---|---|
Description |
Issues STOP signal. |
Parameters |
None. |
Returns |
Nothing. |
Requires |
Soft I²C must be configured before using this function. See Soft_I2C_Init routine. |
Example |
' Issue STOP signal Soft_I2C_Stop() |
Notes |
None. |
Soft_I2C_Break
Prototype |
sub procedure Soft_I2C_Break() |
---|---|
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. |
Parameters |
None. |
Returns |
Nothing. |
Requires | Nothing. |
Example |
dim data1, error, counter as byte sub procedure Timer1Int() org IVT_ADDR_T1INTERRUPT counter = 0 if (counter >= 20) Soft_I2C_Break() counter = 0 ' reset counter else Inc(counter) ' increment counter end if T1IF_bit = 0 ' Clear Timer1 overflow interrupt flag end sub main: ... ' try Soft_I2C_Init with blocking prevention mechanism IPC0 = IPC0 or 0x1000 ' Interrupt priority level = 1 T1IE_bit = 1 ' Enable Timer1 interrupts T1CON = 0x8030 ' Timer1 ON, internal clock FCY, prescaler 1:256 Soft_I2C_Init() T1IE_bit = 0 ' Disable Timer1 interrupts end. |
Notes |
Interrupts should be disabled before using Software I²C routines again (see note at the top of this page). |
Library Example
The example demonstrates use of the Software I²C Library. The dsPIC30/33 or PIC24 MCU is connected (SCL, SDA pins) to PCF8583 RTC (real-time clock). Program sends date/time to RTC.
program RTC_Read dim seconds, minutes, hours, day, month_, year as byte ' Global date/time variables ' Software I2C connections dim Soft_I2C_Scl as sbit at RF3_bit Soft_I2C_Sda as sbit at RF2_bit Soft_I2C_Scl_Direction as sbit at TRISF3_bit Soft_I2C_Sda_Direction as sbit at TRISF2_bit ' End Software I2C connections ' LCD module connections dim LCD_RS as sbit at LATD0_bit dim LCD_EN as sbit at LATD1_bit dim LCD_D4 as sbit at LATB0_bit dim LCD_D5 as sbit at LATB1_bit dim LCD_D6 as sbit at LATB2_bit dim LCD_D7 as sbit at LATB3_bit dim LCD_RS_Direction as sbit at TRISD0_bit dim LCD_EN_Direction as sbit at TRISD1_bit dim LCD_D4_Direction as sbit at TRISB0_bit dim LCD_D5_Direction as sbit at TRISB1_bit dim LCD_D6_Direction as sbit at TRISB2_bit dim LCD_D7_Direction as sbit at TRISB3_bit ' End LCD module connections '--------------------- Reads time and date information from RTC (PCF8583) sub procedure 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} end sub '-------------------- Formats date and time sub procedure Transform_Time() seconds = ((seconds and 0xF0) >> 4)*10 + (seconds and 0x0F) ' Transform seconds minutes = ((minutes and 0xF0) >> 4)*10 + (minutes and 0x0F) ' Transform months hours = ((hours and 0xF0) >> 4)*10 + (hours and 0x0F) ' Transform hours year = (day and 0xC0) >> 6 ' Transform year day = ((day and 0x30) >> 4)*10 + (day and 0x0F) ' Transform day month_ = ((month_ and 0x10) >> 4)*10 + (month_ and 0x0F) ' Transform month end sub '-------------------- Output values to LCD sub procedure Display_Time() Lcd_Chr(1, 6, (day / 10) + 48) ' Print tens digit of day variable Lcd_Chr(1, 7, (day mod 10) + 48) ' Print oness digit of day variable Lcd_Chr(1, 9, (month_ / 10) + 48) Lcd_Chr(1,10, (month_ mod 10) + 48) Lcd_Chr(1,15, year + 57) ' Print year vaiable + 9 (start from year 2009) Lcd_Chr(2, 6, (hours / 10) + 48) Lcd_Chr(2, 7, (hours mod 10) + 48) Lcd_Chr(2, 9, (minutes / 10) + 48) Lcd_Chr(2,10, (minutes mod 10) + 48) Lcd_Chr(2,12, (seconds / 10) + 48) Lcd_Chr(2,13, (seconds mod 10) + 48) end sub '------------------ Performs project-wide init sub procedure Init_Main() ADPCFG = 0xFFFF ' initialize AN pins as digital 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") end sub '----------------- Main procedure main: Delay_ms(1000) Init_Main() ' Perform initialization while TRUE ' Endless loop Read_Time() ' Read time from RTC(PCF8583) Transform_Time() ' Format date and time Display_Time() ' Prepare and display on LCD wend end.
What do you think about this topic ? Send us feedback!