void main(void) {
uint8_t data = 'A',d = '0';
uint16_t addr = 0x0001;
init_uart1(9600);
init_I2C();
write_uart("hello\r\n");
__delay_ms(100);
write_uart("start...\r\n");
__delay_ms(100);
if(!write_eeprom(data,addr))
write_uart("write failed..\r\n");
else
{
write_uart("write successful.. \r\n");
d = read_eeprom(addr);
}
if(!d)
write_uart("read failed..\r\n");
else{
write_uart("read succeeded.. \r\n");
write_uart("data is: ");
write_uart(d);
write_uart("\r\n");
}
return;
}
void init_I2C()
{
TRISCbits.TRISC3 = 1; //Set SCL as input
TRISCbits.TRISC4 = 1; //Set SDA as input
while(!I2C_data)
{
I2C_clock = 0;
scl = 0;
NOP();
NOP();
scl = 1;
}
SSPSTATbits.SMP = 1; //Slew rate disabled
SSPSTATbits.CKE = 0; //Enable SMbus
SSPCONbits.SSPM3 = 1; //Set PIC for master mode
SSPCONbits.SSPM2 = 0;
SSPCONbits.SSPM1 = 0;
SSPCONbits.SSPM0 = 0;
SSPCON2bits.RCEN = 1;
SSPEN = 1; //Enable SDA and SCL pins
SSPIF = 0;
SSPADD = 0x09; //400khz for SCL FOSC/(4*(SSPADD+1))
}
void init_uart1(const long int baudRate)
{
unsigned int x=0;
RCSTAbits.SPEN = 1; //Serial port enabled
RCSTAbits.RX9 = 0; //Eight bit reception
RCSTAbits.CREN = 1; //Continuous receive enable bit
RCSTAbits.ADDEN = 0; //Disable address detection
TXSTAbits.TXEN = 1; //Transmit enable
TXSTAbits.TX9 = 0; //Eight bit transmission
TXSTAbits.BRGH = 1; //High speed transfer rate baud rate >= 9600
TXSTAbits.SYNC = 0; //Asynchronous mode
TRISCbits.TRISC6 = 1; //TX set to output
TRISCbits.TRISC7 = 1; //RX set to input
RCIE = 1; //enable receive interrupt
GIE = 1;
PEIE = 1;
x = (_XTAL_FREQ/(16*baudRate))-1;
SPBRG = x;
}
void strt_I2C()
{
SSPCON2bits.SEN = 1; //Send start bit
while(!SSPIF) //Wait for start condition to finish
write_uart("SSPIF not setting after STRT\r\n");
SSPIF = 0; //Clear FLAG
}
void i2c_restart(void)
{
RSEN=1; //Initiate restart condition
while(!SSPIF) //Wait till completion of event
write_uart("Wait for SSPIF after RSTRT \r\n");
SSPIF = 0;
}
void I2C_idle()
{
while ( ( SSPCON2 & 0x1F ) || ( SSPSTAT & 0x04 ) )
write_uart("I2C NOT IDLE \r\n");
}
unsigned char r_I2C()
{
RCEN = 1; //Enable master to receive
while(!SSPIF) //Wait for byte to be received
write_uart("Wait for read SSPIF \r\n");
SSPIF = 0; //Clear Flag
RCEN = 0;
return SSPBUF;
}
void i2c_ack(void)
{
ACKDT=0; //Set as acknowledgment
ACKEN=1; //Initiate acknowledgment signal
while(!SSPIF) //Wait till completion of event
write_uart("Wait for SSPIF after ACK \r\n");
SSPIF = 0;
}
void i2c_nack(void)
{
ACKDT=1; //Set as negative acknowledgment
ACKEN=1; //Initiate negative acknowledgment signal
while(!SSPIF) //Wait till completion of event
write_uart("Wait for SSPIF after NACK \r\n");
SSPIF = 0;
}
void stp_I2C()
{
PEN = 1;
while(!SSPIF)
write_uart("Wait for SSPIF after STP \r\n");
SSPIF = 0;
}
unsigned char write_eeprom(unsigned char data,uint16_t address)
{
uint8_t MSB=0,LSB=0;
MSB = address>>8;
LSB = 0x00FF & address;
I2C_idle(); //Check if I2C bus is busy
//i2c_restart(); //Send start bit
__delay_ms(100);
if(!sendCode(0xA0)) //Send address of slave and r/w bit
return 0;
sendByte(MSB); //Send MSB memory address of slave to write to
__delay_ms(100);
sendByte(LSB); //Send LSB memory address of slave to write to
__delay_ms(100);
sendByte(data); //Send data to memory of slave, wait for Ack
__delay_ms(100);
stp_I2C();
return 1;
}
unsigned char read_eeprom(uint16_t address)
{
unsigned char data = ' ';
uint8_t MSB = 0,LSB = 0;
MSB = address>>8;
LSB = address & 0x00FF;
//Read Randomly from slave EEPROM
I2C_idle(); //Check if I2C bus is busy
__delay_ms(20);
if(!sendCode(0xA0)) //Send slave address(control byte) =
//'control code' + 'slave address:A2+A1+A0' + 'R/W' =
//1010' + '000' + '0'
return 0;
sendByte(MSB); //LSB of slave memory address
__delay_ms(10);
sendByte(LSB); //MSB of slave memory address
__delay_ms(10);
i2c_restart(); //Resend start bit
__delay_ms(10);
sendByte(0xA1); //Send slave address =
//'control code' + 'slave address:A2+A1+A0' + 'R/W' =
//1010' + '000' + '1'
data = r_I2C(); //read data from slave to SSPBUF
i2c_nack(); //Send NACK after a read cycle
__delay_ms(20);
stp_I2C(); //Send stop bit to slave for end of read cycle
__delay_ms(10);
return(data);
}
unsigned char sendCode(unsigned char code)
{
unsigned char n = 50;
strt_I2C();
if(sendByte(code))
{
return 1;
}
while(n != 0)
{
i2c_restart();
if(sendByte(code))
{
return 1;
}
n--;
}
return 0;
}
unsigned char sendByte(unsigned char data)
{
SSPBUF = data;
while(!SSPIF);
SSPIF = 0;
return(!SSPCON2bits.ACKSTAT);
}
void write_uart(unsigned char *data)
{
int len=0,i = 0;
len = strlen(data);
//if(TXIF) //Check TX interrupt, if set TXREG is empty
//{
while(i < (len)){
while(!TXIF);
TXREG = data[i];
i++;
}
//}
}
unsigned char read_uart()
{
if(RCSTAbits.OERR || RCSTAbits.FERR) //Check for overrun or frame error
{
RCSTAbits.CREN = 0; //Reset CREN if either error occurs
RCSTAbits.CREN = 1;
}
while(!RCIF); //Stay here till a byte is received
return RCREG;
}