0
\$\begingroup\$

I am using Pic24fj128ga202 microcontroller and 24c256 eeprom and ISL1208 RTC which is interfaced through I2c bus. The problem is i can able to read and write the data in eeprom and RTC ,but on some other boards (with same design ) i can't read or write the data through i2c bus. I have posted my code and schematic also kindly anyone address me what is the problem? I don't have oscilloscope to check this.

#include <stdio.h>
#include "C:\Program Files\Microchip\xc16\v1.24\support\PIC24F\h\p24FJ128GA202.h"
#include "uart.h"
// calculate baud rate of I2C
#define Fosc      32000000
#define Fcy       (Fosc/2)
#define Fsck      400000
#define I2C_BRG  ((Fcy/2/Fsck)-1)

int main()
{
    InitProcessor();
    Delayms();
    while(1)
    {
        I2c_Write(0xA0,1,'A');
        Delayms(5000);
        uart1tx(I2C_read(0xA0,1));
    }
}

void InitProcessor(void)
{
    // Oscillator    8mhz no pll
    OSCCON = 0x0011;
    CLKDIV = 0x0000; 

    // Configure Digital pins
    ANSA = 0x0003;
    ANSB = 0x0000;

    //  Assign  IO values for Ports
    PORTA = 0x0000;
    TRISA = 0x001B;
    TRISB = 0x468f;                   // 7 as receive and 8 as transmitter
    //PORTB = 0x0000;


    // Interrupt Bits 
    INTCON1 = 0x0000;                                               // Disable  Interrupts
    INTCON2 = 0x0000;

    // Init I2C
    I2C2CONL = 0x8000;
    I2C2CONH = 0x0000;
    I2C2STAT = 0x0000;
    I2C2BRG = I2C_BRG;
    //I2C2BRG = 79;

    Delayms(1000);
    Init_rtc();
}

void Init_rtc()
{
    I2c_Write(0xde, 0x07, 0x10);
    I2c_Write(0xde, 0x06, 0x00);
    Delayms(20);
}

void I2c_Write(unsigned char DeviceAddress,unsigned int Addr,unsigned char i2c_value)
{
    unsigned char i2c_exit=1,i2c_write=0;
    int I2creg = 0;
    IFS3 &= ~0x0004;
    I2C2CONL |= 0x0001;
    I2cTimer = 0;
    while(i2c_exit)
    {
        if(I2cTimer > 30){                                              // Exit routine
            i2c_exit = 0;
        }
        if(IFS3& 0x0004)
        {
            IFS3 &= ~0x0004;
            I2cTimer = 0;
            if(i2c_write == 0)
            {
                I2C2TRN = (DeviceAddress & 0xfe);
                if(DeviceAddress == 0xde)
                    i2c_write = 1;
            }
            else if(i2c_write == 1)
                I2C2TRN = Addr >> 8;
            else if(i2c_write == 2)
                I2C2TRN = Addr & 0xFF;
            else if(i2c_write == 3)
                I2C2TRN = i2c_value;
            else if(i2c_write == 4)
                I2C2CONL |= 0x04;
            else
            {
                i2c_write = 100;
                i2c_exit = 0;
            }
            i2c_write++;
        }
    }
    Delayms(5);
}

/* Function to Read and return a data through I2C  */
unsigned char I2C_read(unsigned char DeviceAddress,unsigned int Addr)
{   unsigned char db, ReadState=0,I2CFlag;
    ReadState = 0;
    IFS3 &= ~0x0004;                                                        // Master I2C interrupt flag
    I2CFlag = 1;
    I2C2CONL |= 0x0001;         // SEN = 1;
    I2cTimer = 0;
    while(I2CFlag){
        if(I2cTimer > 30){                                              // Exit routine
            I2CFlag = 0;

            //ModemDiagnostics(64,1);
        }
        //uart1tx('r');
        if(IFS3 & 0x0004)
        {       
            I2cTimer = 0;
            IFS3 &= ~0x0004;
            if(ReadState == 0)
            {
                I2C2TRN = (DeviceAddress & 0xfe);
                if(DeviceAddress == 0xde)
                    ReadState = 1;
            }
            else if(ReadState == 1)
                I2C2TRN = Addr >> 8;
            else if(ReadState == 2)
                I2C2TRN = Addr & 0xff;
            else if(ReadState == 3)I2C2CONL |= 0x0002;  
            else if(ReadState == 4)I2C2TRN = (DeviceAddress | 0x01);
            else if(ReadState == 5){
                I2C2CONL |= 0x0008;                             // RCEN = 1, Enable data receive
                db = I2C2RCV;
            }
            else if(ReadState == 6){
                db = I2C2RCV;                                                       // Read Data
                I2C2CONL |= 0x0020;                                                 // ACKDT = 1, Set Acknowledge bit (No Acknowledge)
                Delayms(5);
                I2C2CONL |= 0x0010;                                                 // ACKEN = 1
            }
            else if(ReadState == 7)I2C2CONL |= 0x04;                                // PEN = 1, Stop enable bit forI2C
            else{ReadState = 100; I2CFlag = 0;}                                     
            ReadState++;
        }
    }
    if(db)
        return db;
    else
        return 0;
}

I2c image

\$\endgroup\$
  • \$\begingroup\$ Without digging too much, I suspect that the pullup resistors (R41 and R42) are too high a value (the total capacitance of the circuit is something I cannot know). Try replacing them with 4.7k or perhaps 2.2k \$\endgroup\$ – Peter Smith Aug 19 '16 at 10:47
3
\$\begingroup\$

The calculation of the maximum pull-up at 400kHz is:

\$R_{max}\$ = \$ \frac {300ns} {C_{bus}}\$; rearranging, we get:

\$C_{bus(max)}\$ = \$ \frac {300ns} {10k\Omega}\$ for your case, yielding 30pF.

The pin capacitances of the EEPROM and RTC are both probably of the order of 10pF; add the pin capacitance of the PIC and you are approaching 30pF already, putting the design on a hairy edge (to use the common term), where it may or may not operate properly, which is precisely what you are experiencing.

It is not difficult to get 10pF or more of stray capacitance, and this would violate the requirement for the maximum pull-up size, leading to corrupted I2C data.

If you replace these parts with 4.7k, you are allowed almost 64pF of bus capacitance which will very likely solve the issue.

As noted, if you reduce the bus speed and it operates properly, that is a clear indicator this is the issue.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ thank you @ Peter smith .i am looking forward to address the issue.. and sometimes micro-controller restarts is there any problem by this? \$\endgroup\$ – Pradeep kumark Aug 20 '16 at 6:18
  • \$\begingroup\$ Whether the controller restarts depends on many things, including whether unhandled communication failures have some side effect. I have not read the details of the controller. \$\endgroup\$ – Peter Smith Aug 20 '16 at 17:27
1
\$\begingroup\$

Because it is working as you want in another board, I will assume the problems comes from the hardware (even if a bad software can make it worse). I can see 2 reasons for this:

  • One of the pins of your IC is not properly connected. Do continuity tests with a multimeter between pins of different ICs to check they are properly connected together
  • For some reason, one of your electrical parameter is out of the limits of the Datasheets. This may lead some boards to work, whereas others would not.
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ +1 As well as opens, shorts are also a possibility \$\endgroup\$ – Spehro Pefhany Aug 19 '16 at 12:55

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.