Usando I2C en un dsPIC33E

1

Tengo un problema al utilizar I2C en un dsPIC33EP512MU810. Utilizo la biblioteca periférica para PIC24 y dsPIC33 para administrar los registros, pero también escribí algunas funciones. Estas son las funciones que utilizo 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í por la buena y antigua técnica de pasos de LED, donde enciendo un LED después de cada paso para ver cuándo se detiene. También eché un vistazo a las líneas SDA y SCL con un osciloscopio y solo puedo ver las condiciones de inicio. También revisé la configuración de mi hardware, por ejemplo. está todo conectado, no hay cortocircuitos o casi cortocircuitos y se comprueba 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 se me acabaron las ideas de lo que podría ser que hiciera mal aquí y por qué la bandera no se está levantando. Le agradecería que alguien me indicara la dirección correcta aquí

    
pregunta Erik Zan

1 respuesta

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 solucionó mi problema

    
respondido por el Erik Zan

Lea otras preguntas en las etiquetas