Software I²C Library

The mikroBasic PRO for ARM 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 :

External dependencies of Software I²C Library

Stellaris

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 GPIO_PORTD_DATA3_bit
dim Soft_I2C_Sda as sbit sfr external Soft I²C Data line. dim Soft_I2C_Sda as sbit at GPIO_PORTD_DATA4_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 GPIO_PORTD_DIR3_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 GPIO_PORTD_DIR4_bit

STM32

The following variables must be defined in all projects using Software I²C Library: Description : Example :
dim Soft_I2C_Scl_Input as sbit sfr external Soft I²C Clock Input line. dim Soft_I2C_Scl_Input as sbit at GPIOD_IDR.B3
dim Soft_I2C_Sda_Input as sbit sfr external Soft I²C Data Input line. dim Soft_I2C_Sda_Input as sbit at GPIOD_IDR.B4
dim Soft_I2C_Scl_Output as sbit sfr external Soft I²C Clock Output pin. dim Soft_I2C_Scl_Output as sbit at GPIOD_ODR.B3
dim Soft_I2C_Sda_Output as sbit sfr external Soft I²C Data Output pin. dim Soft_I2C_Sda_Output as sbit at GPIOD_ODR.B4

Library Routines

Soft_I2C_Init

Prototype

sub procedure Soft_I2C_Init()

Description

Configures the software I²C module.

Parameters

None.

Returns

Nothing.

Requires

External dependencies of the library from the top of the page must be defined before using this function.

Example

Stellaris

' Software I2C connections
dim Soft_I2C_Scl           as sbit at GPIO_PORTD_DATA3_bit
    Soft_I2C_Sda           as sbit at GPIO_PORTD_DATA4_bit
    Soft_I2C_Scl_Direction as sbit at GPIO_PORTD_DIR3_bit
    Soft_I2C_Sda_Direction as sbit at GPIO_PORTD_DIR4_bit
' End Software I2C connections
...
Soft_I2C_Init()

STM32

' Software I2C connections
dim Soft_I2C_Scl_Output   as sbit at GPIOD_ODR.B3
    Soft_I2C_Sda_Output   as sbit at GPIOD_ODR.B4
    Soft_I2C_Scl_Input    as sbit at GPIOD_IDR.B3
    Soft_I2C_Sda_Input    as sbit at GPIOD_IDR.B4
' 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
  • ack: acknowledge signal parameter. If the ack==0 not acknowledge signal will be sent after reading, otherwise the acknowledge signal will be sent.
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
  • data_: data to be sent
Returns
  • 0 if there were no errors.
  • 1 if write collision was detected on the I²C bus.
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

          
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 dARM MCU is connected (SCL, SDA pins) to PCF8583 RTC (real-time clock). Program sends date/time to RTC.

Stellaris

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 GPIO_PORTD_DATA3_bit
    Soft_I2C_Sda           as sbit at GPIO_PORTD_DATA4_bit
    Soft_I2C_Scl_Direction as sbit at GPIO_PORTD_DIR3_bit
    Soft_I2C_Sda_Direction as sbit at GPIO_PORTD_DIR4_bit
' End Software I2C connections

' LCD module connections
dim LCD_RS as sbit at GPIO_PORTA_DATA2_bit
dim LCD_EN as sbit at GPIO_PORTA_DATA3_bit
dim LCD_D4 as sbit at GPIO_PORTA_DATA4_bit
dim LCD_D5 as sbit at GPIO_PORTA_DATA5_bit
dim LCD_D6 as sbit at GPIO_PORTA_DATA6_bit
dim LCD_D7 as sbit at GPIO_PORTA_DATA7_bit

dim LCD_RS_Direction as sbit at GPIO_PORTA_DIR2_bit
dim LCD_EN_Direction as sbit at GPIO_PORTA_DIR3_bit
dim LCD_D4_Direction as sbit at GPIO_PORTA_DIR4_bit
dim LCD_D5_Direction as sbit at GPIO_PORTA_DIR5_bit
dim LCD_D6_Direction as sbit at GPIO_PORTA_DIR6_bit
dim LCD_D7_Direction as sbit at GPIO_PORTA_DIR7_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           + 49)  ' Print year vaiable + 1 (start from year 2011)

  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()
  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,"201")
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.

STM32

program RTC_Read

dim seconds, minutes, hours, day, month_, year as byte    ' Global date/time variables

' Software I2C connections
dim Soft_I2C_Scl_Output   as sbit at GPIOD_ODR.B3
    Soft_I2C_Sda_Output   as sbit at GPIOD_ODR.B4
    Soft_I2C_Scl_Input    as sbit at GPIOD_IDR.B3
    Soft_I2C_Sda_Input    as sbit at GPIOD_IDR.B4
' End Software I2C connections

' LCD module connections
dim LCD_RS as sbit at GPIOD_ODR.B10
dim LCD_EN as sbit at GPIOD_ODR.B11
dim LCD_D4 as sbit at GPIOD_ODR.B12
dim LCD_D5 as sbit at GPIOD_ODR.B13
dim LCD_D6 as sbit at GPIOD_ODR.B14
dim LCD_D7 as sbit at GPIOD_ODR.B15
' 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           + 49)  ' Print year vaiable + 1 (start from year 2011)

  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()
  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,"201")
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.
Copyright (c) 2002-2012 mikroElektronika. All rights reserved.
What do you think about this topic ? Send us feedback!
Want more examples and libraries? 
Find them on LibStock - A place for the code