I guess you mentioned '16f877' not '18f877'? If that's true there is a bug in '16f877' hardware which you have to implement an 'i2c_stop()' function in standart CCS i2c functions. Below is the edited functions I used for 'eeprom' read and writes with '16f877', modify these functions for your own needs and give them a try. I recomend using a real hardware for the tests as 'proteus' in not very reliable for this kind of tasks!
void write_ext_eeprom(long int address, BYTE data, int dev_adr)
{
short int status;
i2c_start();
i2c_write(0xa0|((dev_adr&0x03)<<1));
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
do {
i2c_start();
status=i2c_write(0xa0|((dev_adr&0x03)<<1));
i2c_stop();
} while(status==1);
}
BYTE read_ext_eeprom(long int address, int dev_adr) {
BYTE data;
i2c_start();
i2c_write(0xa0|((dev_adr&0x03)<<1));
i2c_write(address>>8);
i2c_write(address);
i2c_start();
i2c_write(0xa1|((dev_adr&0x03)<<1));
data=i2c_read(0);
i2c_stop();
return(data);
}
'dev_adr' is the device address which you set by connecting the appropriate eeprom pins to GND or VDD. You can get rid of that if you don't need it. The important part here is the 'i2c_stop()' function in the 'write_ext_eeprom' function in the 'do...while' loop. That's the part to fix the bug in '16f877' hardware!
Regards...