¿No puede escribir datos en la eeprom 24c256?

Estoy usando el microcontrolador Pic24fj128ga202 y eeprom 24c256 e ISL1208 RTC que se conecta a través del bus I2c. El problema es que puedo leer y escribir los datos en eeprom y RTC, pero en otras placas (con el mismo diseño) no puedo leer ni escribir los datos a través del bus i2c. He publicado mi código y mi esquema también amablemente, alguien se dirige a mí, ¿cuál es el problema? No tengo osciloscopio para comprobar esto.

#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;
}

imagen I2c

Sin profundizar demasiado, sospecho que las resistencias pullup (R41 y R42) tienen un valor demasiado alto (la capacitancia total del circuito es algo que no puedo saber). Intente reemplazarlos con 4.7k o quizás 2.2k

Respuestas (2)

El cálculo del pull-up máximo a 400kHz es:

R metro a X = 300 norte s C b tu s ; reordenando, obtenemos:

C b tu s ( metro a X ) = 300 norte s 10 k Ω para su caso, dando 30pF.

Las capacitancias de los pines de la EEPROM y el RTC son probablemente del orden de 10pF; agregue la capacitancia del pin del PIC y ya se está acercando a 30pF, poniendo el diseño en un borde peludo (para usar el término común), donde puede o no funcionar correctamente, que es precisamente lo que está experimentando.

No es difícil obtener 10 pF o más de capacitancia parásita, y esto violaría el requisito del tamaño máximo de pull-up, lo que conduciría a datos I2C corruptos.

Si reemplaza estas piezas con 4.7k, se le permiten casi 64pF de capacitancia de bus, lo que muy probablemente resolverá el problema.

Como se señaló, si reduce la velocidad del autobús y funciona correctamente, ese es un indicador claro de que este es el problema.

gracias @ Peter smith. Estoy deseando solucionar el problema... y, a veces, el microcontrolador se reinicia. ¿Hay algún problema con esto?
Que el controlador se reinicie depende de muchas cosas, incluso si las fallas de comunicación no controladas tienen algún efecto secundario. No he leído los detalles del controlador.

Debido a que está funcionando como desea en otra placa, asumiré que los problemas provienen del hardware (incluso si un mal software puede empeorarlo). Puedo ver 2 razones para esto:

  • Uno de los pines de su IC no está conectado correctamente. Realice pruebas de continuidad con un multímetro entre pines de diferentes circuitos integrados para verificar que estén correctamente conectados entre sí
  • Por alguna razón, uno de sus parámetros eléctricos está fuera de los límites de las hojas de datos. Esto puede hacer que algunas placas funcionen, mientras que otras no.
+1 Además de abiertos, los cortos también son una posibilidad.