Usando I2C en un dsPIC33E

Tengo un problema al usar I2C en un dsPIC33EP512MU810. Utilizo la biblioteca periférica para PIC24 y dsPIC33 para administrar los registros, pero también escribí algunas funciones. Aquí están las funciones que uso para I2C

#include <xc.h>
#include <stdint.h>
#include "I2C1.h"
#include <i2c.h> 
#include <libpic30.h> 
#include "common.h"

void Open_I2C1(void)
{
    // Configre SCA/SDA pin as open-drain. This may change from device to device.
    //Refer the datasheet for more information.
    ODCDbits.ODCD9 = 0;
    ODCDbits.ODCD10 = 0;
    OpenI2C1((I2C2_ON & I2C2_IDLE_CON & I2C2_CLK_HLD & I2C2_IPMI_DIS &
             I2C2_7BIT_ADD & I2C2_SLW_EN & I2C2_SM_DIS &
             I2C2_GCALL_DIS & I2C2_STR_DIS &
             I2C2_NACK & I2C2_ACK_DIS & I2C2_RCV_DIS &
             I2C2_STOP_DIS & I2C2_RESTART_DIS &
             I2C2_START_DIS), 0x4E);

    IdleI2C1();

    I2C1CONbits.I2CEN = 1;
    IEC1bits.MI2C1IE = 1;
    IFS1bits.MI2C1IF = 0;

}

void WriteByte_I2C1(unsigned char WriteAddressIC, unsigned char WriteAddressRegister, uint8_t MSByte, uint8_t LSByte)
{
    ResetVariables_I2C1();

    Start_I2C1();
    while(!IFS1bits.MI2C1IF);
    IFS1bits.MI2C1IF=0;

    //Write Slave address and set master for transmission
    MasterWriteI2C1(WriteAddressIC);
    WaitFlag_I2C1();
    WaitForACK_I2C1();  

    MasterWriteI2C1(WriteAddressRegister);
    WaitFlag_I2C1();
    WaitForACK_I2C1();

    MasterWriteI2C1(MSByte);  
    WaitFlag_I2C1();   
    WaitForACK_I2C1();

    MasterWriteI2C1(LSByte);  
    WaitFlag_I2C1();   
    WaitForACK_I2C1();

    ResetVariables_I2C1();  
    StopI2C1();   
    WaitFlag_I2C1();  
    WaitForACK_I2C1();   
    IdleI2C1();

}

uint16_t ReadByte_I2C1 (unsigned char ReadAddressIC, unsigned char RegisterAddress)
{
    uint8_t Byte = 0x00;
    uint16_t result = 0x0000;
    ResetVariables_I2C1();
    Start_I2C1();
    while((!IFS1bits.MI2C1IF)) {

    }

    //Write Slave address and set master for transmission
    MasterWriteI2C1(ReadAddressIC);      
    WaitFlag_I2C1();
    WaitForACK_I2C1();

    MasterWriteI2C1(RegisterAddress);
    WaitFlag_I2C1();
    WaitForACK_I2C1();

    ResetVariables_I2C1();
    RestartI2C1();
    WaitFlag_I2C1();

    MasterWriteI2C1(ReadAddressIC + 1);
    WaitFlag_I2C1();
    WaitForACK_I2C1();
    ResetVariables_I2C1();


    I2C1CONbits.RCEN = 1;
    while(I2C1CONbits.RCEN)
    {
        LATCbits.LATC2 ^= 1;
    }
    I2C1STATbits.I2COV = 0;
    Byte = I2C1RCV;
    result = Byte<<8;
    WaitFlag_I2C1();


    I2C1CONbits.RCEN = 1;
    while(I2C1CONbits.RCEN)
    {
        LATCbits.LATC2 ^= 1;
    }
    I2C1STATbits.I2COV = 0;
    Byte = I2C1RCV;
    result |= Byte;
    WaitFlag_I2C1();

    ResetVariables_I2C1();
    NotAckI2C1();
    WaitFlag_I2C1();
    ResetVariables_I2C1();
    StopI2C1();
    WaitFlag_I2C1();
    IdleI2C1();

    return Byte;

}

void ResetVariables_I2C1(void)
{
    I2C1CONbits.ACKEN=0;
    I2C1CONbits.PEN=0;
    I2C1CONbits.RCEN=0;
    I2C1CONbits.RSEN=0;
    I2C1CONbits.SEN=0;
}

void WaitFlag_I2C1(void)
{
    while(!IFS1bits.MI2C1IF);
    LATCbits.LATC2 ^=1;  // wait for flag to be high
    IFS1bits.MI2C1IF=0;
}
void WaitForACK_I2C1(void)
{
    while(I2C1STATbits.ACKSTAT); // wait for ack receive from slave
    LATCbits.LATC2 ^=1; 
}
void Start_I2C1(void){
    I2C1CONbits.SEN = 1; 
}

Cuando uso la función de escritura, la función se detiene justo después de enviar la condición de inicio porque la bandera nunca se establece. Lo medí con la buena y antigua técnica de paso de LED en la que enciendo un LED después de cada paso para ver cuándo se detiene. También eché un vistazo a la línea SDA y SCL con un osciloscopio y solo puedo ver las condiciones de inicio. También verifiqué la configuración de mi hardware, por ejemplo, si todo está conectado, no hay cortocircuitos o casi cortocircuitos y verifiqué si puedo usar otros dispositivos para comunicarme con el IC con el que quiero hablar con el dsPIC33. También verifiqué si uso los pines correctos. Uso ASD1/RD9 y ASCL1/RD10, lo que significa que tengo que configurar 'ALTI2C1 = ON' en los bits de configuración.

Pero ahora me quedé sin ideas de qué podría ser lo que hice mal aquí y por qué la bandera no se levanta. Estaría agradecido si alguien pudiera señalarme en la dirección correcta aquí

Consejo general para la serie EP: verifique la fe de erratas. Hay algunos errores significativos con el periférico I2C en la serie EP que necesitan soluciones en el firmware. El silicio EP cambió mucho con respecto a la serie FJ...

Respuestas (1)

Creo que encontré la respuesta. En la función de inicialización encendí la interrupción I2C, aunque no tengo un ISR. No configurar IEC1bits.MI2C1IE resolvió mi problema