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 wait(100); I2C1CON = 0x1000; // default settings of I2C1 module wait(100); I2C1BRG = 39; // set the baud-rate generator -> 100 kHz SCL, Fosc = 8 MHz wait(100); I2C1CONbits.I2CEN = 1; // start the I2C1 module wait(100); 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