dsPIC33C I2C SW Library
dsPIC33C I2C SW Library
dsPIC33C I2C SW Library
1.0 OVERVIEW
This library provides a software implementation of an I2C interface for dsPIC33C using standard I/Os.
This library supports both Master and Slave modes. The performance and resources needed are
listed in Table 1. The software I2C Master code is blocking, which means that the Master I2C proce-
dures consume all CPU time when executed. The software I2C Master task should be implemented
as a low priority process interrupted by other high priority tasks in the application.
For the software I2C Slave, one edge processing takes about 67 instruction cycles. In this case, when
the nested interrupts are disabled, other interrupts may be delayed by 67 cycles.
Note: This software library should be used with the physical I2Cx pins (SCLx and SDAx)
without enabling the respective I2Cx module. Configure the Port pins multiplexed
with the I2Cx module to use I/O pins for Software I2C implementation.
2.1 Files
The files in the table below must be added to the application project to implement the Master I2C
interface:
File Description
i2c_master.h This header contains I/O definitions/selection and timing/clock speed settings
used for the Master I2C interface. This file also includes prototypes of Master
I2C functions.
i2c_master.c This source file contains Master I2C function implementations.
The library package includes demo projects.
The demo project located in the master_demo folder shows how to use the Master I2C library func-
tions to access EEPROM 24FC256. The files related to this demo are:
File Description
i2c_master_eeprom_24fc256.h This header contains prototypes of functions to access
24FC256 EEPROM.
i2c_master_eeprom_24fc256.c This C source file contains functions implementations to
access 24FC256 EEPROM.
master_demo_main.c The main demonstration source file. It contains code to initial-
ize the I2C interface and write and read values to and from the
24FC256 EEPROM.
The signals can be generated to write a byte by using the following function calls:
I2CM_Start();
I2CM_Write(0xA0);
I2CM_Write(address>>8);
I2CM_Write(address&0x00FF);
I2CM_Write(data);
I2CM_Stop();
I2CM_Write(0xA0);
I2CM_Write(address>>8);
I2CM_Write(address&0x00FF);
I2CM_Start();
I2CM_Write(0xA1); // READ
I2CM_Stop();
File Description
i2c_slave.h This header contains I/O definitions/selection used for the Slave I2C interface.
Also, this file includes prototypes of Slave I2C functions.
i2c_slave.c This C source file contains Slave I2C functions implementations.
The library package includes demo projects.
The demo project located in the slave_demo folder shows how to use the Slave I2C library functions
to emulate EEPROM 24FC256. The files related to this demo are:
File Description
i2c_slave_eeprom_24fc256.h This C source file contains I2C callback functions implementations
to emulate 24FC256 EEPROM.
slave_demo_main.c The main demonstration source file. The code in this file initializes
I2C Slave interface and runs I2C task.
// current state
I2C_STATE state = STATE_DEV_ADDRESS;
// This callback function is called every time when I2C start is detected
void I2CS_Start(){
state = STATE_DEV_ADDRESS; // after start the device address byte will be transmitted
}
// This callback function is called every time when data from I2C master are received
short I2CS_Read(unsigned char data){
switch(state){
case STATE_DEV_ADDRESS:
if((data >> 1) == EEPROM_DEV_ADDRESS){ // bits from #7 to #1 are device address
if(data&1){ // if bit #0 is set (=1) it indicates that the next data go from
// slave to master
state = STATE_DATA_WRITE;
return 2; // ACK to master (bit #0 = 0), master reads data on next transaction
//(bit #1 = 1)
}else{ // if bit #0 is cleared (=0) it indicates that the next data go from master
to slave
state = STATE_ADDRESS_HIGH_BYTE;
return 0; // ACK to master
}
}
return 1; // NACK to master if device address doesn't match EEPROM_DEV_ADDRESS
case STATE_ADDRESS_HIGH_BYTE:
state = STATE_ADDRESS_LOW_BYTE;
eeprom_address = (data<<8);
return 0; // ACK to master
case STATE_ADDRESS_LOW_BYTE:
state = STATE_DATA_READ;
eeprom_address |= data;
return 0; // ACK to master
case STATE_DATA_READ:
state = STATE_DEV_ADDRESS;
if(eeprom_address >= EEPROM_SIZE){
return 1; // NACK to master, the memory address is wrong
}
eeprom_data[eeprom_address] = data; // store the data received
return 0; // ACK to master
default:
state = STATE_DEV_ADDRESS;
return 1; // NACK to master / unknown state
}
// This callback function is called every time when data must be sent to I2C master
unsigned char I2CS_Write(short prev_ack){
void main()
{
I2CS_Init();
while(1){
I2CS_Task();
}
}