hhhsssmmm
Member level 1
Hello
I have tried to solve the problem my self but i fail. I can not get the slave pic to transmit a single byte to master
pic via I2C interface. I have however successfully completed I2C link when master send byte to slave...then it
works fine and i can get result on my LCD screen too. But can not get things to work the other way around from
SALVE to MASTER.
Right now im just getting garbage on my LCD screen when i run the two programs as below.
I use the following...
PIC i use is PIC18F4423 (MASTER) and PIC18F2420 (SLAVE)
Master @ 20Mhz ceramic clock
Slave @ 8MHz internal clock
compiler used C18
Please can someone look at my code below and help me please to solve this problem
Thank you
Haseeb
I have tried to solve the problem my self but i fail. I can not get the slave pic to transmit a single byte to master
pic via I2C interface. I have however successfully completed I2C link when master send byte to slave...then it
works fine and i can get result on my LCD screen too. But can not get things to work the other way around from
SALVE to MASTER.
Right now im just getting garbage on my LCD screen when i run the two programs as below.
I use the following...
PIC i use is PIC18F4423 (MASTER) and PIC18F2420 (SLAVE)
Master @ 20Mhz ceramic clock
Slave @ 8MHz internal clock
compiler used C18
Please can someone look at my code below and help me please to solve this problem
Thank you
Haseeb
Code:
MASTER CODE
--------------
//In main() function...
OpenI2C(); //INITIALLIZE & Configure I2C PORT
StartI2C(); //Generates a Start I2C condition
IdleI2C(); //Loops until I2C BUS is Idle
if(DataRdyI2C() == 0) //proceed if buffer is empty
{
//Sends Slave address
if(WriteI2C(0x69) == 0) //ACK not received from Slave
{
I2C_Error(); //Stop and rest I2C if link between PICs fail
}
IdleI2C(); //Loops until I2C BUS is Idle
}
BCD = ReadI2C(); //save the data read
NotAckI2C(); //Generates a Not Ack condition after reading data
StopI2C(); //Generates a Stop I2C condition
IdleI2C(); //Loops until I2C BUS is Idle
SendLCD(0x80,0); //activate LCD line 1
//print the data byte on LCD
SendLCD(BCD,1);
while(1); //loop forever
//My customized I2C functions...
void OpenI2C(void)
{
//Reseting MSSP registers
SSPCON1 = 0x00; // power on state
SSPCON2 = 0x00; // power on state
//Selecting & Configuring I2C Master mode
SSPCON1bits.SSPM3 = 1;
SSPCON1bits.SSPM2 = 0;
SSPCON1bits.SSPM1 = 0;
SSPCON1bits.SSPM0 = 0;
SSPSTATbits.SMP = 1; //Slew rate set to NORMAL speed @ 100kHz
SSPADD = 0x63; //setting baud rate 100kHz (NORMAL)...PIC running @ 20MHz
SSPSTATbits.CKE = 0; //Disable SMBus
PIR1bits.SSPIF = 0; //reset MSSP interrupt flag bit
SSPCON1bits.SSPEN = 1; //Enable I2C Master port
}//end of OpenI2C()
void NotAckI2C(void)
{
SSPCON2bits.ACKDT = 1; // set acknowledge bit for NOT ACK
SSPCON2bits.ACKEN = 1; // initiate bus acknowledge sequence
}//end of NotAckI2C()
void IdleI2C(void)
{
//Test and wait until I2C module is idle
while ( (SSPCON2 & 0x1F) | (SSPSTATbits.R_W) )
continue; //keep looping until idle
}//end of IdleI2C()
unsigned char DataRdyI2C(void)
{
if(SSPSTATbits.BF == 1) // test if buffer full bit is set
return 1; // data in SSPBUF register
else
return 0; // no data in SSPBUF register
}//end of DataRdyI2C()
unsigned char ReadI2C(void)
{
SSPCON2bits.RCEN = 1; // enable master for 1 byte reception
while (SSPSTATbits.BF == 0); // wait until byte received
while(PIR1bits.SSPIF == 0); //wait for interrupt
PIR1bits.SSPIF = 0; //reset MSSP interrupt flag bit
return SSPBUF; // return with read byte
}//end of ReadI2C()
unsigned char WriteI2C(unsigned char data_out)
{
SSPCON2bits.ACKSTAT = 1; //reset ACK bit flag
SSPBUF = data_out; // write single byte to SSPBUF
if(SSPCON1bits.WCOL == 1) // test if write collision occurred
{
SSPCON1bits.WCOL = 0; //Reset collision bit
while(SSPSTATbits.BF == 1); // wait until write cycle is complete
}
while(PIR1bits.SSPIF == 0); //wait for interrupt
PIR1bits.SSPIF = 0; //reset MSSP interrupt flag bit
if(SSPCON2bits.ACKSTAT == 0) //Was there an ACK sent from DS1307?
return 1; //DS1307 sent ACK
else
return 0; //No ACK was sent
}//end of WriteI2C()
void StartI2C(void)
{
SSPCON2bits.SEN = 1; //Initiate Start condition
while(PIR1bits.SSPIF == 0); //wait for interrupt
PIR1bits.SSPIF = 0; //reset MSSP interrupt flag bit
}//end of StartI2C()
void StopI2C(void)
{
SSPCON2bits.PEN = 1; //Generate Stop condition
while(PIR1bits.SSPIF == 0); //wait for interrupt
PIR1bits.SSPIF = 0; //reset MSSP interrupt flag bit
}//end of StopI2C()
void I2C_Error(void)
{
IdleI2C(); //Loops until I2C BUS is Idle
StopI2C(); //Generates a Stop I2C condition
IdleI2C(); //Loops until I2C BUS is Idle
}//end of I2C_Error()
SLAVE CODE
------------
//In main() function...
//Reseting MSSP registers
SSPCON1 = 0x00; // power on state
SSPCON2 = 0x00; // power on state
//I2C SLAVE mode, 7 bit address, with Start & Stop bits interrupts enabled
SSPCON1bits.SSPM3 = 1;
SSPCON1bits.SSPM2 = 1;
SSPCON1bits.SSPM1 = 1;
SSPCON1bits.SSPM0 = 0;
SSPSTATbits.SMP = 1; //Slew rate set to NORMAL speed @ 100kHz
SSPADD = 0x69; //SLAVE address is (7bit). LSB bit is set to 1 for read
SSPSTATbits.CKE = 0; //Disable SMBus
SSPCON1bits.CKP = 1; //Clock Released
SSPCON1bits.SSPEN = 1; //Enable I2C Master port
d0 = SSPBUF; //clears BF
SSPCON1bits.SSPOV = 0; //Clear Buffer Overflow
PIR1bits.SSPIF = 0; //reset MSSP interrupt flag bit
INTCONbits.INT0IF = 0; //Reset the INT0 External Interrupt Flag bit
INTCON = 0b10010000; //Enables all high priority interrupts
//Disables all low priority peripheral interrupts
//Disable the TMR0 overflow interrupt
//Enables the INT0 external interrupt
//Disables the RB port change interrupt
d0 = 'S'; //assigning the transmit byte
while(1);
//In ISR function....
void HighInterrupt (void)
{
if(PIR1bits.SSPIF == 1) //if MSSP interrupt
{
if(SSPSTATbits.R_W == 1) // Slave address varified
{
SSPBUF = d0; //TX data byte
SSPCON1bits.CKP = 1; //Release clock
d1 = SSPBUF; //empty buffer
}
PIR1bits.SSPIF = 0; //reset MSSP interrupt flag bit
}
}