void I2cInit(){
I2cDataTris=1; //Make data input
I2cClockTris=1; //and clock
while(!I2cData){ //if something holding line low
I2cClock=0; //then pulse clock line
I2cClockTris=0;
NOP();
NOP();
I2cClockTris=1;
}
SSPADD=80; //8000/100;
SSPSTAT=8; //I2C Master clock = Fosc/(4*SSPADD)
SSPCON1=0x28;
SSP1IF=0;
SSP1CON1bits.SSPEN=1;
}
#define I2cClock PORTCbits.RC3
#define I2cData PORTCbits.RC4
#define I2cClockTris TRISCbits.TRISC3
#define I2cDataTris TRISCbits.TRISC4
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "Configuration.h"
#define _XTAL_FREQ 16000000
#define I2C_clock PORTCbits.RC3
#define I2C_data PORTCbits.RC4
#define scl TRISCbits.TRISC3
#define sda TRISCbits.TRISC4
void init_I2C();
void init_uart1(const long int baudRate);
bit w_I2C(unsigned char d);
unsigned char r_I2C(unsigned char d);
void I2C_idle();
void strt_I2C();
void i2c_restart(void);
void i2c_ack(void);
void i2c_nack(void);
void stp_I2C();
void write_uart(unsigned char *data);
unsigned char read_uart();
void main(void) {
unsigned char data = 'A';
init_uart1(9600);
init_I2C();
write_uart("hello\r\n");
__delay_ms(100);
write_uart("start...\r\n");
__delay_ms(100);
I2C_idle(); //Check if I2C bus is busy
strt_I2C(); //Send start bit
__delay_ms(100);
w_I2C(0xA0); //Send address of slave and r/w bit
__delay_ms(100);
w_I2C(0x00); //Send MSB memory address of slave to write to
__delay_ms(100);
w_I2C(0x01); //Send LSB memory address of slave to write to
__delay_ms(100);
w_I2C(0x41); //Send data to memory of slave, wait for Ack
__delay_ms(100);
stp_I2C();
__delay_ms(100);
//Read Randomly from slave EEPROM
I2C_idle(); //Check if I2C bus is busy
strt_I2C(); //Send Start bit to initiate read from slave EEPROM
__delay_ms(100);
w_I2C(0xA0); //Send slave address(control byte) =
//'control code' + 'slave address:A2+A1+A0' + 'R/W' =
//1010' + '000' + '0'
__delay_ms(100);
w_I2C(0x00); //LSB of slave memory address
__delay_ms(100);
w_I2C(0x01); //MSB of slave memory address
__delay_ms(100);
i2c_restart(); //Resend start bit
__delay_ms(100);
w_I2C(0xA1); ////Send slave address =
//'control code' + 'slave address:A2+A1+A0' + 'R/W' =
//1010' + '000' + '1'
__delay_ms(50);
data = r_I2C(0); //read data from slave with a dummy value to SSPBUF
__delay_ms(50);
data = r_I2C(0); //read data from slave with a dummy value to SSPBUF
__delay_ms(50);
i2c_nack(); //Send NACK after a read cycle
__delay_ms(50);
stp_I2C(); //Send stop bit to slave for end of read cycle
__delay_ms(50);
write_uart(data);
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 = 1; //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
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");
}
bit w_I2C(unsigned char d)
{
SSPBUF;
L1:
SSPBUF = d; //Write data to send to slave
while(!SSPIF)
write_uart("Wait for write SSPIF \r\n");
while(SSPCON2bits.ACKSTAT) //Wait for data to send
{
write_uart("Wait for slave ACK \r\n");
i2c_restart();
__delay_ms(100);
goto L1;
}
SSPCON2bits.ACKSTAT = 1;
SSPIF = 0; //Clear Flag
return SSPCON2bits.ACKSTAT;
}
unsigned char r_I2C(unsigned char d)
{
SSPBUF = d;
RCEN = 1; //Enable master to receive
while(!BF) //Wait for byte to be received
write_uart("Wait for BF \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;
}
void write_uart(unsigned char *data)
{
int len=0,i = 0;
len = strlen(data);
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;
}
uint8 I2cWriteByte(int Address,unsigned char Dat){
if(!I2cSendId((uint8)(0xa0))) //EEPROM ID and address 0
return(0);
I2cSendByte((uint8)(Address>>8));
I2cSendByte((uint8)(Address&255));
I2cSendByte(Dat);
I2cStop();
return(1);
}
uint8 I2cReadByte(long Address){
uint8 temp;
if(!I2cSendId((uint8)(0xa0))) //EEPROM ID
return(0);
I2cSendByte((uint8)(Address>>8));
I2cSendByte((uint8)(Address&255));
I2cReStart();
I2cSendByte((uint8)(0xa1));
temp=I2cReceiveByte();
I2cNack();
I2cStop();
return(temp);
}
unsigned char I2cSendId(unsigned char ID){
unsigned char count;
I2cStart();
if(I2cSendByte(ID))
return(1);
count=50;
do{
I2cReStart();
if(I2cSendByte(ID))
return(1);
}while(--count!=0);
return(0);
}
void WaitSSP(){
while(SSP1IF==0);
SSP1IF=0;
}
void I2cStart(){
SSP1CON2bits.SEN=1;
WaitSSP();
}
void I2cStop(){
SSP1CON2bits.PEN=1;
WaitSSP();
}
void I2cReStart(){
SSP1CON2bits.RSEN=1;
WaitSSP();
}
void I2cNack(){
SSP1CON2bits.ACKDT=1;
SSP1CON2bits.ACKEN=1;
WaitSSP();
}
void I2cAck(){
SSP1CON2bits.ACKDT=0;
SSP1CON2bits.ACKEN=1;
WaitSSP();
}
uint8 I2cSendByte(unsigned char data){
SSPBUF=data;
WaitSSP();
return((uint8)!SSP1CON2bits.ACKSTAT);
}
uint8 I2cReceiveByte(){
SSP1CON2bits.RCEN=1;
WaitSSP();
return(SSPBUF);
}
bit w_I2C(unsigned char d)
{
SSPBUF;
L1:
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;
}
void write_uart_byte(unsigned char data)
{
int len=0,i = 0;
while(!TXIF);
TXREG = data;
}
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?