Which C compiler are you using in MPlab? As far as I know the only free C compiler that comes with MPlab is the C18 compiler which you wouldn't be using with the 16F877A. Are you using CCS, HI-TECH C, other? Different compilers have different libraries for controlling I2C communication.
Once you figure out which compiler you are using and how to use thier specific I2C libraries the basic flow will go like this:
I2C Initialize;
I2C Start;
I2C Slave address:
I2C Register select;
I2C Write data;
I2C Stop;
Between each step you will likely have your code wait for the acknowledge signal which is a signal output by the slave basically saying "OK, I received the entire byte". The registers you write to and the data you write to them are device specific. You have to study the data sheet for your specific device to know what registers must be written to and when to control which functions.
i'm using hi-tech c.
i just wrote some code about i2c
void i2c_init()
{
TRISC3=1; // set SCL and SDA pins as inputs
TRISC4=1;
SSPCON = 0x38; // set I2C master mode
SSPCON2 = 0x00;
//SSPADD = 0x6; // 400kHz bus with 10MHz xtal - use 0x0C with 20MHz xtal
SSPADD = 10; // 100k at 4Mhz clock
CKE=1; // use I2C levels worked also with '0'
SMP=1; // disable slew rate control worked also with '0'
SSPIF=0; // clear SSPIF interrupt flag
BCLIF=0; // clear bus collision flag
}
/******************************************************************************************/
void i2c_waitForIdle()
{
while (( SSPCON2 & 0x1F ) | RW ) {}; // wait for idle and not writing
}
/******************************************************************************************/
void i2c_start()
{
i2c_waitForIdle();
SEN=1;
}
/******************************************************************************************/
void i2c_repStart()
{
i2c_waitForIdle();
RSEN=1;
}
/******************************************************************************************/
void i2c_stop()
{
i2c_waitForIdle();
PEN=1;
}
/******************************************************************************************/
int i2c_read( unsigned char ack )
{
unsigned char i2cReadData;
i2c_waitForIdle();
RCEN=1;
i2c_waitForIdle();
i2cReadData = SSPBUF;
i2c_waitForIdle();
if ( ack )
{
ACKDT=0;
}
else
{
ACKDT=1;
}
ACKEN=1; // send acknowledge sequence
return( i2cReadData );
}
/******************************************************************************************/
unsigned char i2c_write( unsigned char i2cWriteData )
{
i2c_waitForIdle();
SSPBUF = i2cWriteData;
return ( ACKSTAT ); // function returns '1' if transmission is acknowledged
}
/******************************************************************************************/
/******************************************************************************************
*************************** sla --- device slave ******************************************
*************************** address --- device address ************************************
*************************** *data --- data array ******************************************
*************************** num --- data length *******************************************
*******************************************************************************************/
void i2c_writeNByte(unsigned char sla, unsigned char address, unsigned char *data, unsigned char num)
{
unsigned int i;
for(i=0;i<num;i++)
{
i2c_start();
i2c_write(sla);
i2c_write(address+i);
i2c_write(*data++);
i2c_stop();
delays(5);
}
}
/******************************************************************************************/
void i2c_readNByte(unsigned char sla, unsigned char address, unsigned char *data, unsigned char num)
{
unsigned int i;
for(i=0;i<num;i++)
{
i2c_start();
i2c_write(sla);
i2c_write(address+i);
i2c_repStart();
i2c_write(sla+1);
*data++=i2c_read(0);
i2c_stop();
Delays(5);
}
}
are these alright??