Software I²C Library
The mikroBasic PRO for PIC 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.
Important :
- 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_Startis 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 RC3_bit |
dim Soft_I2C_Sda as sbit sfr external |
Soft I²C Data line. | dim Soft_I2C_Sda as sbit at RC4_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 TRISC3_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 TRISC4_bit |
Library Routines
Soft_I2C_Init
| Prototype |
sub procedure Soft_I2C_Init() |
|---|---|
| Returns |
Nothing. |
| Description |
Configures the software I²C module. |
| Requires |
Global variables :
|
| Example |
'Soft_I2C pinout definition dim Soft_I2C_Scl as sbit at RC3_bit dim Soft_I2C_Sda as sbit at RC4_bit dim Soft_I2C_Scl_Direction as sbit at TRISC3_bit dim Soft_I2C_Sda_Direction as sbit at TRISC4_bit 'End of Soft_I2C pinout definition ... Soft_I2C_Init() |
Soft_I2C_Start
| Prototype |
sub procedure Soft_I2C_Start() |
|---|---|
| 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 |
sub function Soft_I2C_Read(dim ack as word) as byte |
|---|---|
| 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 |
dim take as word ... ' Read data and send the not_acknowledge signal take = Soft_I2C_Read(0) |
Soft_I2C_Write
| Prototype |
sub function Soft_I2C_Write(dim _Data as byte) as byte |
|---|---|
| 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 |
dim data_, error as byte ... error = Soft_I2C_Write(data_) error = Soft_I2C_Write(0xA3) |
Soft_I2C_Stop
| Prototype |
sub procedure Soft_I2C_Stop() |
|---|---|
| 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 |
sub procedure Soft_I2C_Break() |
|---|---|
| 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. Note :
Interrupts should be disabled before using Software I²C routines again (see note at the top of this page).
|
| Requires | Nothing. |
| Example |
dim data1, error_, counter as byte
sub procedure interrupt()
if (INTCON.T0IF <> 0) then
if (counter >= 20) then
Soft_I2C_Break()
counter = 0 ' reset counter
end if
else
Inc(counter) ' increment counter
INTCON.T0IF = 0 ' Clear Timer0 overflow interrupt flag
end if
end sub
main:
counter = 0
OPTION_REG = 0x04 ' TMR0 prescaler set to 1:32
...
' try Soft_I2C_Init with blocking prevention mechanism
INTCON.GIE = 1 ' Global interrupt enable
INTCON.T0IE = 1 ' Enable Timer0 overflow interrupt
data1 = Soft_I2C_Init(error_)
INTCON.GIE = 0 ' Global interrupt disable
end.
|
Library Example
The example demonstrates Software I²C Library routines usage. The PIC 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.
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 RC3_bit
Soft_I2C_Sda as sbit at RC4_bit
Soft_I2C_Scl_Direction as sbit at TRISC3_bit
Soft_I2C_Sda_Direction as sbit at TRISC4_bit
' End Software I2C connections
' Lcd module connections
dim LCD_RS as sbit at RB4_bit
LCD_EN as sbit at RB5_bit
LCD_D4 as sbit at RB0_bit
LCD_D5 as sbit at RB1_bit
LCD_D6 as sbit at RB2_bit
LCD_D7 as sbit at RB3_bit
LCD_RS_Direction as sbit at TRISB4_bit
LCD_EN_Direction as sbit at TRISB5_bit
LCD_D4_Direction as sbit at TRISB0_bit
LCD_D5_Direction as sbit at TRISB1_bit
LCD_D6_Direction as sbit at TRISB2_bit
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) ' Print tens digit of month variable
Lcd_Chr(1,10, (_month mod 10) + 48) ' Print oness digit of month variable
Lcd_Chr(1, 15, year + 48) ' Print year vaiable + 8 (start from year 2008)
Lcd_Chr(2, 6, (hours / 10) + 48) ' Print tens digit of hours variable
Lcd_Chr(2, 7, (hours mod 10) + 48) ' Print oness digit of hours variable
Lcd_Chr(2, 9, (minutes / 10) + 48) ' Print tens digit of minutes variable
Lcd_Chr(2,10, (minutes mod 10) + 48) ' Print oness digit of minutes variable
Lcd_Chr(2,12, (seconds / 10) + 48) ' Print tens digit of seconds variable
Lcd_Chr(2,13, (seconds mod 10) + 48) ' Print oness digit of seconds variable
end sub
'------------------ Performs project-wide init
sub procedure Init_Main()
TRISB = 0
PORTB = 0xFF
TRISB = 0xFF
ANSEL = 0 ' Configure AN pins as digital I/O
ANSELH = 0
C1ON_bit = 0
C2ON_bit = 0
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_Chr(1,16,".")
Lcd_Out(2,1,"Time:")
Lcd_Chr(2,8,":")
Lcd_Chr(2,11,":")
Lcd_Out(1,12,"201") ' start from year 2010
end sub
'----------------- Main sub procedure
main:
Delay_ms(500)
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!




