I am working with PIC24FJ192GB106 (64 pin package), and the I2C module is driving me crazy.

here is the code:

int counter = 1;
address = 0b01110000; // ADD7 = 0111000 ; W = 0;
cmd1 = 0xFF;
cmd2 = 0xFF;

I2C1CONbits.I2CEN = 0; // turn off the I2C1 module
I2C1CON = 0x1000; // default settings of I2C1 module
I2C1BRG = 39; // set the baud-rate generator -> 100 kHz SCL, Fosc = 8 MHz
I2C1CONbits.I2CEN = 1; // start the I2C1 module

IFS1bits.MI2C1IF = 0; // clear interrupt flag (just to make sure)


I2C1CONbits.SEN = 1; // initiates Start condition
while (I2C1CONbits.SEN == 1 ){counter++;}; // wait until Start condition is executed

I2C1TRN = address; // send data
while (I2C1STATbits.TRSTAT == 1 ){counter++;}; // wait while data is being send + ignore ACK from slave

I2C1TRN = cmd1; // send data
while (I2C1STATbits.TRSTAT == 1 ){counter++;}; // wait while data is being send + ignore ACK from slave

I2C1TRN = cmd2; // send data
while (I2C1STATbits.TRSTAT == 1 ){counter++;}; // wait while data is being send + ignore ACK from slave

I2C1CONbits.PEN = 1; // initiates Stop condition
while (I2C1CONbits.PEN == 1 ){counter++;}; // wait until Stop condition is executed

TRISE = counter; // show counter on LEDs

From (*) and on NON-OF THE CODE IS EXECUTED. There is no response on pins (measured by oscilloscope). The I2C1 is located on not-remappable pins SCL1 - pin 44, SDA1 - pin 43. Pull-up of 4.7 kOhm (3.3 V) are hooked up. I have also tried to set corresponding bits in ODCD to 1 (digital pin), and 0 (open drain). TRISD is set to input (0xFF) (but I have also tried output option).

I suspect that none of the bits SEN, PEN and register I2C1TRN is set, because the "counter" remains the same value. Considerring that the PIC has 8MHZ clock and I2C only 100 kHz, there has to be time for at least one counter++, while waiting.

Is there anything, that I can do? (Except changing the PIC). Have I missed something? What other options of debugging do I have?

P.S. The PIC is otherwise fine. Other modules (PWM, ADC, UART) work perfectly. Internal oscillator is (remarkably) precise (measured on oscilloscope on reference clock pin). All other pins work (portE register).

P.S. 2

here are my settings for the PIC24

OSCCONbits.COSC = 0b111; // current oscillator selection bits // '111' FastRC Oscillator with Postscaler(FRCDIV)
OSCCONbits.NOSC = 0b111; // new oscillator selection bits
OSCCONbits.CLKLOCK = 1;// if FCKSM (config word) is disabled (then FCSM is disabled) the NO EFFECT   //OSCCONbits.IOLOCK -> lock function
OSCCONbits.LOCK = 1; // PPL Lock Status bit // when OSCCON.COSC = any non PPL clock mode then NO EFFECT   //OSCCONbits.CF -> to be READ in case FCSM has detected a failure (FCSM is disabled anyway)
OSCCONbits.LPOSCEN = 0; // Primary Oscillator Sleep Enable bit // [0] - Primary Osc continues during sleep mode
OSCCONbits.SOSCEN = 0; // Secondary Oscillator Enable bit // [0] - 32kHz Secondary Osc is disabled
OSCCONbits.OSWEN = 0; // Oscillator Switch Enable bit // [1]-changes from OSCCON.COSC to OSCCON.NOSC/[0]-nothing

CLKDIVbits.ROI = 0; // Recover on Interrupt bit // [0] - Interrupts have no effect on the DOZEN bit
CLKDIVbits.DOZE = 0b000; // CPU Peripheral Clock Ratio Select bits // [000] - 1:1
CLKDIVbits.DOZEN = 0; // DOZE Enable bit // [0] - CPU peripheral clock ratio is set to 1:1
CLKDIVbits.RCDIV = 0b000; // FRC Postscaler Select bits // [000] - 1:1

Ok, if you are having problems with I2C, and you have already tried everything that I mentioned above. THE THE I2C MODULE IS DEAD.

Really, the above code works perfectly with I2C2 module.

Hopefully someone will find the above code usefull.


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.