Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

I2C slave code in hardware.

Status
Not open for further replies.

Pommie

Well-Known Member
Most Helpful Member
Has anyone managed to get this to work on a pic? I'm using a 16F1823 and it all works except for sending bytes back to the master. As soon as I release the clock line (CKP=1) the master receives the 8 (wrong) bytes it asks for. It's as though the clock doesn't get stretched on subsequent bytes.

Here's my main code,
Code:
    SSPADD=0x80;        //Slave address
    SSPSTAT = 0x80;  
    SSPCON = 0x36;    //As a slave device
    SSPCON2 = 0x01;
    SSPCON3=0x10;
    status = WaitID;
 
    while(1){
        if(SSP1IF){             //byte received??
            SSP1IF=0;
            if(!SSPSTATbits.D_nA)   //if Address (0x80) then reset state
                status=WaitID;
            switch (status){
                case WaitID:
                    if(R_nW){                   //is it a read operation?
                        status=WriteBytes;      //if master reading, we're writing
                        SSP1BUF=buff[index++&7];//write first byte
                        CKP=1;                  //once this line executes all bytes are read by master
                    }else{
                        status=WaitAdd;
                        dummy=SSP1BUF;          //is ID so discard
                        CKP=1;
                    }
                    break;
                case WaitAdd:
                    index=SSP1BUF;              //store address
                    status=ReadBytes;
                    CKP=1;
                    break;
                case WriteBytes:
                    if(ACKSTAT){            //if no ACK
                        status=WaitID;      //start again
                    }else{                  //if master ACKed then more bytes required
                        SSP1BUF=buff[index++&7];
                        CKP=1;                      
                    }
                    break;
                case ReadBytes:
                    buff[index++&7]=SSPBUF; //store values
                    CKP=1;
                    break;
            }
            //lastly check for errors and deal with them
            if ((SSPCONbits.SSPOV) || (SSPCONbits.WCOL)){
                dummy = SSPBUF;         // Read the previous value to clear the buffer
                SSPCONbits.SSPOV = 0;   // Clear the overflow flag
                SSPCONbits.WCOL = 0;    // Clear the collision bit
                SSPCONbits.CKP = 1;     //release clock line
            }
        }
    }
The master writes 8 bytes and these end up in the buffer (buff). It then attempts to read them back but get's nonsense.
I can single step through the above code and it works exactly as it should until the line CKP=1 with remark //once this line executes all bytes are read by master, even though the slave is paused. Anyone managed to do this? Any suggestions?

Thanks,

Mike.
edit, removed superfluous code.
 
Hi Mike When I worked in tec support for a living , we sometimes said , " Leave them for a bit they may sort their own problem out... " :) well done getting slave HW to work ... waiting for the ACK seems to be the difficult thing .
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top