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