# PIC24 - testing I2C module dead/alive

I got PIC24FJ192GB106 (64 pin package) and I cannot get the I2C module working at all. What is the easiest and most straight forward way of testing, whether the module is OK?

I am using I2C1 module, (SCL1 - pin 44, SDA1 - pin 43).

BRG register = 39; // 100 kHz for Fosc = 8 MHz

// Control register
I2C1CONbits.I2CEN = 1;
I2C1CONbits.I2CSIDL = 0;
I2C1CONbits.SCLREL = 1;
I2C1CONbits.IPMIEN = 0;
I2C1CONbits.A10M = 0;
I2C1CONbits.DISSLW = 1;
I2C1CONbits.SMEN = 0;
I2C1CONbits.GCEN = 0;
I2C1CONbits.STREN = 0;
I2C1CONbits.ACKDT = 0;
I2C1CONbits.ACKEN = 0;
I2C1CONbits.RCEN = 0;
I2C1CONbits.PEN = 0;
I2C1CONbits.RSEN = 0;
I2C1CONbits.SEN = 0;

// starting the module
I2C1CONbits.I2CEN = 1;

// setting the START CONDITION
I2C1CONbits.SEN = 1;


There is no response. The Start Condition is not executed. The I2C pheripheral is on NON-remappable pins. Whole TrisD register (pin 43 = D9, pin 44 = D10) is set as input (after reset). The pins has pull-ups (3.3 V, 4.7 kOhm). I have also tried to set corresponding bit in ODCD to 1 (digital pin), and 0 (open drain).

Have I missed something? Microcontroller is working fine (UART, PWM, reference clock, ADC, ...).

I would appriciate any guidance.

• Try it by hand ...youtube.com/watch?v=8ZYMrcHm91s – Spoon Feb 4 '15 at 12:35
• I2C1CONbits.PEN doesn't initiate a start condition - that's for a stop. Use SEN for a start. – brhans Feb 4 '15 at 14:06
• Thank you, mistake is corrected but the problem remains – Martin G Feb 4 '15 at 20:51
• Does your I2C1CON.BCL bit ever get set? – brhans Feb 4 '15 at 21:36

Go the hard way.

Write the test routine for sending start or stop bits and put it in a while loop.

Your main code will look like this.

main
{
initialize i2c();//Configure the I2C module in this function
while(1)
{
i2c_send(); //Learn how the I2C transmits data and send the data   accordingly.
}

}


Now take an oscilloscope and observe the wave forms.

If have not messed up with configurations or initializations you will see the magic waves.

• That is the first thing I have tried. I already coded my own functions for filling I2C1TMR (transmission register) and checking, whether data are send and conditions executed. – Martin G Feb 4 '15 at 12:14

If you are using XC16, you can #include <i2c.h> and try using the OpenI2C1() library call to do the dirty work of configuring the peripheral instead of writing directly to the SFR.

Here is code I use to open I2C1 as a master:

#include <i2c.h>

u16Clk = 39; // specified by OP

OpenI2C1(
I2C1_ON &
I2C1_IDLE_CON &
I2C1_STR_EN &
I2C1_SLW_DIS &
I2C1_GCALL_DIS &
I2C1_SM_EN &
I2C1_IPMI_DIS,
u16Clk
);


Once it's open, you can see if it works by sending a start, sending an arbitrary (non-reserved address), then send a stop (while scoping the lines).

StartI2C1();
MasterWriteI2C1(data);
MasterWaitForIntrI2C1();
StopI2C1();


Thank you for all the answers.

The module is definitely dead. The code works for I2C2 module just fine.