I²C Library

The I²C full master MSSP module is available with a number of PIC MCU models. mikroC PRO for PIC provides library which supports the master I²C mode.


  Important :

Library Routines

Generic Routines

I2Cx_Init

Prototype

void I2Cx_Init(const unsigned long clock);

// for PIC18F K42 and K83 family

void I2Cx_Init();

Returns

Nothing.

Description

Initializes I²C with desired clock (refer to device data sheet for correct values in respect with Fosc). Needs to be called before using other functions of I²C Library.

You don’t need to configure ports manually for using the module; library will take care of the initialization.

  Note :
  • Calculation of the I²C baud rate value is carried out by the compiler, as it would produce a relatively large code if performed on the library level.
    Therefore, compiler needs to know the value of the parameter in the compile time. That is why this parameter needs to be a constant, and not a variable.
  • For PIC18F K42 and K83 family the I²C speed is fixed to 100 kHz and pins used for the I²C should be set as open-drain in ODCONx register, please consult the appropriate datasheet.
  • I²C routines require you to specify the module you want to use. To select the desired I²C, simply change the letter x in the prototype for a number from 1 to 2.
  • Number of I²C modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.
Requires

Library requires MSSP module.

Example
I2C1_Init(100000);
// for PIC18F K42 and K83 family I2C1_Init();

I2Cx_Start

Prototype

unsigned short I2Cx_Start(void);

Returns

If there is no error, function returns 0.

Description

Determines if I²C bus is free and issues START signal.

  Note :
  • I²C routines require you to specify the module you want to use. To select the desired I²C, simply change the letter x in the prototype for a number from 1 to 2.
  • Number of I²C modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.
Requires

I²C must be configured before using this function. See I2Cx_Init.

Example
I2C1_Start();

I2Cx_Repeated_Start

Prototype

void I2Cx_Repeated_Start(void);

Returns

Nothing.

Description

Issues repeated START signal.

  Note :
  • I²C routines require you to specify the module you want to use. To select the desired I²C, simply change the letter x in the prototype for a number from 1 to 2.
  • Number of I²C modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.
Requires

I²C must be configured before using this function. See I2Cx_Init.

Example
I2C1_Repeated_Start();

I2Cx_Is_Idle

Prototype

unsigned short I2Cx_Is_Idle(void);

Returns

Returns 1 if I²C bus is free, otherwise returns 0.

Description

Tests if I²C bus is free.

  Note :
  • I²C routines require you to specify the module you want to use. To select the desired I²C, simply change the letter x in the prototype for a number from 1 to 2.
  • Number of I²C modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.
Requires

I²C must be configured before using this function. See I2Cx_Init.

Example
if (I2C1_Is_Idle()) {...}

I2Cx_Rd

Prototype

unsigned short I2Cx_Rd(unsigned short ack);

// for PIC18F K42 and K83 family

unsigned short I2Cx_Rd(char slave_address, char *ptrdata, unsigned short count, unsigned short END_mode);

Returns

Returns one byte from the slave.

Description

PIC12F/16F/18F

  • Reads one byte from the slave, and sends not acknowledge signal if parameter ack is 0, otherwise it sends acknowledge.

PIC18F K42 and K83 family

  • slave_address: slave address.
  • ptrdata: pointer to the received data.
  • count: number of bytes to be received.
  • END_mode: mode in which the I²C module will be set after the reading. Available modes :
    Value Description
    _I2C_END_MODE_RESTART I²C bus will issue a restart.
    _I2C_END_MODE_STOP I²C bus will issue a stop.

  Note :
  • I²C routines require you to specify the module you want to use. To select the desired I²C, simply change the letter x in the prototype for a number from 1 to 2.
  • Number of I²C modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.
Requires

I²C must be configured before using this function. See I2Cx_Init.

Also, START signal needs to be issued in order to use this function. See I2Cx_Start (not valid for PIC18F K42 and K83 family).

Example

Read data and send not acknowledge signal:

unsigned short take;
...
take = I2C1_Rd(0);

I2Cx_Wr

Prototype

unsigned short I2Cx_Wr(unsigned short data_);

// for PIC18F K42 and K83 family

unsigned short I2Cx_Wr(char slave_address, char *ptrdata, unsigned short count, unsigned short END_mode);

Returns

Returns 0 if there were no errors.

Description

PIC12F/16F/18F

  • Sends data byte (parameter data_) via I²C bus.

PIC18F K42 and K83 family

  • slave_address: slave address.
  • ptrdata: pointer to the data to be transmitted.
  • count: number of bytes to be transmitted.
  • END_mode: mode in which the I²C module will be set after the writing. Available modes :
    Value Description
    _I2C_END_MODE_RESTART I²C bus will issue a restart.
    _I2C_END_MODE_STOP I²C bus will issue a stop.

  Note :
  • I²C routines require you to specify the module you want to use. To select the desired I²C, simply change the letter x in the prototype for a number from 1 to 2.
  • Number of I²C modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.
Requires

I²C must be configured before using this function. See I2Cx_Init.

Also, START signal needs to be issued in order to use this function. See I2Cx_Start (not valid for PIC18F K42 and K83 family).

Example
I2C1_Write(0xA3);

I2Cx_Stop

Prototype

void I2Cx_Stop(void);

Returns

Nothing.

Description

Issues STOP signal.

  Note :
  • I²C routines require you to specify the module you want to use. To select the desired I²C, simply change the letter x in the prototype for a number from 1 to 2.
  • Number of I²C modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.
Requires

I²C must be configured before using this function. See I2Cx_Init.

Example
I2C1_Stop();

I2Cx_SetTimeoutCallback

Prototype

void I2Cx_SetTimeoutCallback(unsigned long timeout, void (*i2c1_timeout)(char));

Returns

Nothing.

Description

This function checks for a I²C timeout condition in a user defined time period, after which it jumps to a callback function if this condition is met.
Different I²C operations can cause a timeout (read, write, start and repeated start) so user may test which one caused it, as in the example below.

Parameters :
  • timeout: Represents a number of while loops in which the I²C timeout condition is checked.
    Depending on the architecture (PIC16, PIC16ENH or PIC18) the generated code (i.e. the execution time) may vary for the same value of this parameter.

  • i2c_timeout: pointer to the callback function. Callback function must be written according to this function prototype :
    void I2C1_TimeoutCallback(char errorCode) {
    
    }	
    
Requires
  • I²C must be configured before using this function. See I2Cx_Init.
  • I²C routines require you to specify the module you want to use. To select the desired I²C, simply change the letter x in the prototype for a number from 1 to 2.
  • Number of I²C modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.
Example
// define callback function
void I2C1_TimeoutCallback(char errorCode) {

   if (errorCode == _I2C_TIMEOUT_RD) {
     // do something if timeout is caused during read
   }
   
   if (errorCode == _I2C_TIMEOUT_WR) {
     // do something if timeout is caused during write
   }
   
   if (errorCode == _I2C_TIMEOUT_START) {
     // do something if timeout is caused during start
   } 
   
   if (errorCode == _I2C_TIMEOUT_REPEATED_START) {
     // do something if timeout is caused during repeated start            
   }
}	

// initialize I2C module
I2C1_Init(100000);

// set timeout period and callback function
I2C1_SetTimeoutCallback(1000, I2C1_TimeoutCallback);

I2C_Set_Active

Prototype

void I2C_Set_Active(unsigned short (*start_ptr)(), void (*restart_ptr)(), unsigned short (*read_ptr)(unsigned short), unsigned short(*write_ptr)(unsigned short), void (*stop_ptr)(), unsigned short(*is_idle_ptr)());

// for PIC18F K42 and K83 family

void I2C_Set_Active(unsigned short (*read_ptr)(char, char *, unsigned short, unsigned short), unsigned short(*write_ptr)(char, char *, unsigned short, unsigned short), unsigned short(*is_idle_ptr)());

Description

Sets the active I²C module which will be used by the I²C routines.

Parameters
Returns

Nothing.

Requires
  • I²C must be configured before using this function. See I2Cx_Init.
Example
I2C_Set_Active(&I2C1_Start, &I2C1_Repeated_Start, &I2C1_Wr, &I2C1_Wr, &I2C1_Stop, &I2C1_Is_Idle); // Sets the I2C1 module active
Notes

Number of I²C modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

I2C_Start

Prototype

unsigned short I2C_Start(void);

Returns

If there is no error, function returns 0.

Description

Determines if I²C bus is free and issues START signal.

This is a generic routine which uses the active I²C module previously activated by the I2C_Set_Active routine.

Requires

I²C must be configured before using this function. See I2Cx_Init.

Example
I2C_Start();

I2C_Restart

Prototype

void I2C_Restart(void);

Returns

Nothing.

Description

Issues repeated START signal.

This is a generic routine which uses the active I²C module previously activated by the I2C_Set_Active routine.

Requires

I²C must be configured before using this function. See I2Cx_Init.

Example
I2C_Restart();

I2C_Is_Idle

Prototype

unsigned short I2C_Is_Idle(void);

Returns

Returns 1 if I²C bus is free, otherwise returns 0.

Description

Tests if I²C bus is free.

This is a generic routine which uses the active I²C module previously activated by the I2C_Set_Active routine.

Requires

I²C must be configured before using this function. See I2Cx_Init.

Example
if (I2C_Is_Idle()) {...}

I2C_Rd

Prototype

unsigned short I2C_Rd(unsigned short ack);

// for PIC18F K42 and K83 family

unsigned short I2C_Rd(char slave_address, char *ptrdata, unsigned short count, unsigned short END_mode);

Returns

Returns one byte from the slave.

Description

PIC12F/16F/18F

  • Reads one byte from the slave, and sends not acknowledge signal if parameter ack is 0, otherwise it sends acknowledge.

PIC18F K42 and K83 family

  • slave_address: slave address.
  • ptrdata: pointer to the received data.
  • count: number of bytes to be received.
  • END_mode: mode in which the I²C module will be set after the reading. Available modes :
    Value Description
    _I2C_END_MODE_RESTART I²C bus will issue a restart.
    _I2C_END_MODE_STOP I²C bus will issue a stop.

This is a generic routine which uses the active I²C module previously activated by the I2C_Set_Active routine.

Requires

I²C must be configured before using this function. See I2Cx_Init.

Also, START signal needs to be issued in order to use this function. See I2C_Start (not valid for PIC18F K42 and K83 family).

Example

Read data and send not acknowledge signal:

unsigned char take;
...
I2C_Set_Active(&I2C1_Start, &I2C1_Restart, &I2C1_Read, &I2C1_Write, &I2C1_Stop, &I2C1_Is_Idle); // Sets the I2C1 module active

// Read data and send the not_acknowledge signal
take = I2C_Read(_I2C_NACK);

I2C_Wr

Prototype

unsigned short I2C_Wr(unsigned short data_);

// for PIC18F K42 and K83 family

unsigned short I2C_Wr(char slave_address, char *ptrdata, unsigned short count, unsigned short END_mode);

Returns

Returns 0 if there were no errors.

Description

PIC12F/16F/18F

  • Sends data byte (parameter data_) via I²C bus.

PIC18F K42 and K83 family

  • slave_address: slave address.
  • ptrdata: pointer to the data to be transmitted.
  • count: number of bytes to be transmitted.
  • END_mode: mode in which the I²C module will be set after the writing. Available modes :
    Value Description
    _I2C_END_MODE_RESTART I²C bus will issue a restart.
    _I2C_END_MODE_STOP I²C bus will issue a stop.

This is a generic routine which uses the active I²C module previously activated by the I2C_Set_Active routine.

Requires

I²C must be configured before using this function. See I2Cx_Init.

Also, START signal needs to be issued in order to use this function. See I2C_Start (not valid for PIC18F K42 and K83 family).

Example
unsigned char data_;
unsigned error
...

I2C_Set_Active(&I2C1_Start, &I2C1_Restart, &I2C1_Read, &I2C1_Write, &I2C1_Stop, &I2C1_Is_Idle); // Sets the I2C1 module active

error = I2C_Write(data_);
error = I2C_Write(0xA3);

I2C_Stop

Prototype

void I2C_Stop(void);

Returns

Nothing.

Description

Issues STOP signal.

This is a generic routine which uses the active I²C module previously activated by the I2C_Set_Active routine.

Requires

I²C must be configured before using this function. See I2Cx_Init.

Example
I2C_Set_Active(&I2C1_Start, &I2C1_Restart, &I2C1_Read, &I2C1_Write, &I2C1_Stop, &I2C1_Is_Idle); // Sets the I2C1 module active
// Issue STOP signal
I2C_Stop();
Notes

None.

Library Example

This code demonstrates use of I²C library. PIC MCU is connected (SCL, SDA pins) to 24c02 EEPROM. Program sends data to EEPROM (data is written at address 2). Then, we read data via I²C from EEPROM and send its value to PORTB, to check if the cycle was successful (see the figure below how to interface 24c02 to PIC).

Copy Code To ClipboardCopy Code To Clipboard
void main(){
  ANSEL  = 0;                // Configure AN pins as digital I/O
  ANSELH = 0;
  PORTB = 0;
  TRISB = 0;                 // Configure PORTB as output

  I2C1_Init(100000);         // initialize I2C communication
  I2C1_Start();              // issue I2C start signal
  I2C1_Wr(0xA2);             // send byte via I2C  (device address + W)
  I2C1_Wr(2);                // send byte (address of EEPROM location)
  I2C1_Wr(0xAA);             // send data (data to be written)
  I2C1_Stop();               // issue I2C stop signal

  Delay_100ms();

  I2C1_Start();              // issue I2C start signal
  I2C1_Wr(0xA2);             // send byte via I2C  (device address + W)
  I2C1_Wr(2);                // send byte (data address)
  I2C1_Repeated_Start();     // issue I2C signal repeated start
  I2C1_Wr(0xA3);             // send byte (device address + R)
  PORTB = I2C1_Rd(0u);       // Read the data (NO acknowledge)
  I2C1_Stop();               // issue I2C stop signal
}

HW Connection

Interfacing 24c02 to PIC via I²C

Interfacing 24c02 to PIC via I²C

Copyright (c) 2002-2019 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