Hi, I am learning to use I2C protocol and currently stuck with alternative solution. These are the details regarding what i am doing: 1) Using PIC 18F4580 AS master and PIC 18F4550 as slave. 2) I receive acknowledgments when i am debugging on the master side. 3) on the client side i do not receive any data from the master . 4) here by giving the code of master: #include<p18f4580.h> #include "typedefs.h" #pragma udata unsigned char value=0; int i=0,fail_flag=0; void delay(void); void Trxmt(void); void Recv(void); void i2c_fail(void); void WaitMSSP(void); #pragma code void main() { //Oscillator configuration Settings OSCCONbits.IRCF2=1; //4Mhz OSCCONbits.IRCF1=1; OSCCONbits.IRCF0=0; OSCCONbits.SCS1=1; //Internal oscillator block selected OSCCONbits.SCS0=1; //data direction register //RC3, RC4 are inputs for PORTC TRISCbits.TRISC3=1; //SCL Serial Clock TRISCbits.TRISC4=1; //SDA Serial Data TRISDbits.TRISD2=0; //LED ouput to indicate failure PORTDbits.RD2 = 0; SSPCON1bits.SSPM3=1; // I2C Master Mode Settings SSPCON1bits.SSPM2=0; SSPCON1bits.SSPM1=0; SSPCON1bits.SSPM0=0; SSPCON1bits.SSPEN=1; // Enables the serial port,config SDA & SCL pins as serial port pins SSPSTATbits.SMP=1; //Slew rate 100khz std speed mode( Slew Rate control (SMP) 100kHz mode and input levels are I2C SSPSTAT=0b10000000; SSPCON2=0x0000; //initailly i2c is in idle mode SSPADD=0x28; //Configure Baud Rate value=0; Trxmt(); //Recv(); } void Trxmt(void) { //To send start command to slave----------------------------------------------------// SSPCON2bits.SEN=1; //Initiate Start condition on SDA and SCL pins. SSPCON2bits.ACKSTAT=1; //to check set as slave not received from slave if(TRISCbits.TRISC3==1 && TRISCbits.TRISC4==1) SSPADD=0x28; //reload value for baud rate generator while(SSPSTATbits.S!=1) //check for start cmd { } SSPADD=0x28; //reload value for baud rate generator WaitMSSP(); value=1; //end of start command----------------------------------------------------------------/ //------address to send--------------------- ------------------------------------------/ SSPBUF = 0x10; //slave address WaitMSSP(); value=2; while(SSPCON2bits.ACKSTAT!=0) { } if(SSPCON2bits.ACKSTAT==1) i2c_fail(); value=3; //------address has been sent---------------------------------------------------------------// // begin to send data---------------------------------------------------------------------// SSPBUF = 0x66; WaitMSSP(); value=4; PIR1bits.SSPIF=0; while(SSPCON2bits.ACKSTAT!=0) { } if(SSPCON2bits.ACKSTAT==1) i2c_fail(); value=5; //-------data sent------begin stop ---------------------------------------------------------------------// //if(fail_flag!=1) { value =6; SSPCON2bits.PEN=1; //Initiate Stop condition on SDA and SCL pins. WaitMSSP(); } } void WaitMSSP(void) { while(PIR1bits.SSPIF!=1) { // wait for it to be set before any operation } SSPADD=0x28; PIR1bits.SSPIF=0; } void i2c_fail(void) { fail_flag=1; PORTDbits.RD2=0; SSPCON2bits.PEN=1; //Initiate Stop condition on SDA and SCL pins. while(PIR1bits.SSPIF!=1)// wait for it to be set before any operation { } PIR1bits.SSPIF=0; PORTDbits.RD2 = 1; for(i=0;i<10;i++) { } PORTDbits.RD2 = 0; value=7; } void Recv(void) { SSPCON2bits.RCEN=1; while(SSPSTATbits.BF!=1) { } } 5)here is the code for the slave: #include<p18f4550.h> #include "typedefs.h" #define SS PORTAbits.RA2 #pragma udata unsigned char value=0; unsigned char valuebef=0; unsigned char zom=0; unsigned char recvslaveval=0; int i=0; void InterruptHandlerHigh (void); void Setup(void); void delay(void); void Trxmt(void); void Recv(void); #pragma code void main() { Setup(); } void Setup(void) { //Oscillator configuration Settings OSCCONbits.IRCF2=1; //4Mhz OSCCONbits.IRCF1=1; OSCCONbits.IRCF0=0; OSCCONbits.SCS1=1; //Internal oscillator block selected OSCCONbits.SCS0=1; //data direction register TRISBbits.TRISB1=1; //SCL Serial Clock TRISBbits.TRISB0=1; //SDA Serial Data SSPSTATbits.BF=0; //To make sure that bf is not set before trxm SSPCON1bits.SSPOV=0; SSPSTATbits.SMP=0; //This bit must be clear in I2C SSPSTATbits.CKE=0; //This bit must be clear in I2C SSPADD=0x10; // addr where in last byte is 0 to indicate write // I2C SLAVE Mode Settings SSPCON1=0; SSPCON1bits.SSPM3=0; SSPCON1bits.SSPM2=1; SSPCON1bits.SSPM1=1; SSPCON1bits.SSPM0=0; SSPCON1bits.SSPEN=1; // Enables the serial port,config SDA & SCL pins as serial port pins SSPCON1bits.CKP=1; // //SSPCON2bits.GCEN=1; //General addr call for device SSPSTATbits.SMP=1; //Slew rate 100khz std speed mode SSPCON2=0x0000; //initiate acknowledge sequence PIR1bits.SSPIF = 0; PIE1bits.SSPIE = 1; INTCONbits.PEIE = 1; INTCONbits.GIE = 1; TRISDbits.TRISD2=0; //LED ouput to indicate failure PORTDbits.RD2 = 0; Recv(); //Trxmt(); } void Recv(void) { SSPCON2bits.SEN=1; //Initiate Start condition on SDA and SCL pins. SSPCON1bits.CKP =1; SSPCON2bits.ACKEN=1; //initiate acknowledge sequence value=1; while(PIR1bits.SSPIF!=1) { PORTDbits.RD2 = 1; // wait for it to be set before any operation } if(PIR1bits.SSPIF) { PIR1bits.SSPIF=0; PORTDbits.RD2 = 1; } // while(SSPSTATbits.BF!=1) //{ //} for(i=0;i<500;i++) { // do nothing } if (SSPSTATbits.R_W == 0) { value=SSPBUF; } //while(PIR1bits.SSPIF!=1) //{ // wait for it to be set before any operation //} PIR1bits.SSPIF=0; if(SSPSTATbits.BF==0) value=2; else value=3; /*while(SSPSTATbits.BF!=1) { }*/ // begin to send slave addr // while(PIR1bits.SSPIF!=1) // { // // wait for it to be set before any operation // } // PIR1bits.SSPIF=0; value=SSPBUF; } void Trxmt(void) { } PS: have gone through the data sheets of PIC 18F4580 & 18F4550 AND also the examples given by Pic for I2C USING EEPROM AS SLAVE. But my current problem is i need to use another microcontroller as slave. Basically Micro controller to microcontroller communication using I2C, Any help will be greatly appreciated. Hoping For a response. Regards, Risha
microcontroller to microcontroller one as slave & other as master using I2C
Started by ●September 5, 2007