1
\$\begingroup\$

Good evening, I was trying to start the communication with the I2C on my pic. I only set the bits in the control register in the code for now and the inizialization of both the pins and the PLL, and I found that the lower 4 bits( RCEN, PEN, RSEN and SEN) could not be written. Since I cannot write on the SEN bit, the clock does not start. Also, I am setting the register so the device operates as master.

Here is my code:

int main(void)
{
InitOsc();
InitPin();
InitTimer4();
InitTimer5();   


MCUinit();  //initialization MLX

//enable I2c
I2C1CONbits.I2CEN=1;    
I2C1CONbits.I2CSIDL=0; //continues operation in idle
I2C1CONbits.SCLREL=1; // releases clock
I2C1CONbits.IPMIEN=0;   //ipmi should be disabled when operating as master
I2C1CONbits.A10M=0; // slave address are 7-bits
I2C1CONbits.DISSLW=1;   //slew rate control bit enabled
I2C1CONbits.SMEN=0; //disables smbus imput threshold (!!)
I2C1CONbits.ACKDT=0;
I2C1CONbits.ACKEN=1;

// Apparently no effect from here on! If I set a breakpoint here and track
// the variables none of these are on even for a single clock cycle!
I2C1CONbits.RCEN=1;
I2C1CONbits.PEN=1;
I2C1CONbits.RSEN=1; 
I2C1CONbits.SEN=1;

return 0;
}

Is there anything I am doing wrong? I am quite a beginner with this microcontroller, so any explanation would be of use.

I tested the SCL channel with an oscilloscope and nothing at all comes out of that, just stays at a flat 0V signal.

Thank you!

\$\endgroup\$
3
  • \$\begingroup\$ Why the I2C1CONbits.ACKEN=1; line? That starts an acknowledge sequence. Your PIC's I2C module can't do anything else until that completes. \$\endgroup\$
    – brhans
    Oct 27 '14 at 15:54
  • \$\begingroup\$ Also you're not configuring the BRG, so what speed will clocks be being generated at? \$\endgroup\$
    – Majenko
    Oct 27 '14 at 16:26
  • \$\begingroup\$ I made a mistake, there is no need for the ACKEN bit, anyway I just put at the beginning the two line: I2C1CONbits.I2CEN=1; I2C1CONbits.SEN=1; nothing happens, so I think that the problem is not the order. As for the BRG, I can set it, but since the start SEN bit should be the one to start the communication I just thought that I would leave the default value until I resolved the problem. I set it, but still nothing. \$\endgroup\$
    – Giulia DL
    Oct 27 '14 at 21:57
1
\$\begingroup\$

Firstly, the PIC micro-controller's I2C module does not support command queuing (hence brhans' comment). You must verify that the last operation completed before starting the next operation.

e.x. (note that the register names for the interrupt flags will need to be rechecked for this PIC as this was adapted from another PIC's code)

//Pre clear the intterupt flag
IFS1bits.MI2C1IF = 0;

//Send the start condition
I2C1CONbits.SEN = 1;

//Wait for the start condition to complete
while (!IFS1bits.MI2C1IF);
IFS1bits.MI2C1IF = 0;

//Send the I2C address
I2C1TRN = I2C_ADDR;

//Wait for the send to complete and check that the node acknowledged
while (!IFS1bits.MI2C1IF);
IFS1bits.MI2C1IF = 0;

if (I2C1STATbits.ACKSTAT)
    return 0; //ERROR, node did not acknowledge!!!

...

Secondly, as Majenko correctly pointed out, you do not seem to configure the baud rate generator (I2C1BRG). It may be in an invalid state were the I2C module cannot successfully complete an operation.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.