Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

I2C slave pic transmit problems

Status
Not open for further replies.

hhhsssmmm

Member level 1
Joined
May 14, 2009
Messages
37
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,732
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



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               

    }

}
 

Hi..

Haseeb..I too is getting the same problem with I2C communication between two Controllers. If you have the solution then please guide me accordingly.
 

have a look at this code - it uses the microchip header i2c.h
Code:
// read from I2C device address
// initially send tx_data (length tx_length), restart and read rx_length bytes into rs_data
int readI2C(int address, unsigned char *tx_data, int tx_length, unsigned char * rx_data, int rx_length)
{
   int i;
   unsigned int i2c_data_wait= 11152;
   //printf("\n\rread I2C %#x ", address);
   writeI2C(address,tx_data, tx_length, 0);		// send address and register number etc
   RestartI2C();     							// send RESTART ready for a read!
   while(I2CCONbits.RSEN );						// wait for restart complete 
   if(MasterWriteI2C(address+1)<0)return -1;	/* Write Slave address and set master for read */   
   if(MastergetsI2C(rx_length, rx_data, i2c_data_wait)!=0)return -1;	// read data from slave
   // uart2_puts("\n\rread  ");
   // for(i=0;i<rx_length;i++) { printHex(rx_data[i],uart2_putchar); uart2_putchar(' ');}
   StopI2C();									/* send stop */  
   while(I2CCONbits.PEN);						/* Wait till stop sequence is completed */
   CloseI2C();									// close I2C device
   return 0;
}
 

Hello friend,
Please tell me the meaning of Collision detection in arbtration of I2C.Thanks




Regards
Amit
 

Hello friend,
Please tell me the meaning of Collision detection in arbtration of I2C.Thanks

Regards
Amit

have a look at section 24.6.3 Bus arbitration and bus collision of
ww1.microchip.com/downloads/en/DeviceDoc/61116D.pdf
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top