Verwenden von I2C auf einem dsPIC33E

Ich habe ein Problem mit I2C auf einem dsPIC33EP512MU810 . Ich verwende die Peripheriebibliothek für PIC24 und dsPIC33, um die Register zu verwalten, habe aber auch einige Funktionen selbst geschrieben. Hier sind die Funktionen, die ich für I2C verwende

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

Wenn ich die Write-Funktion verwende, stoppt die Funktion direkt nach dem Senden der Startbedingung, weil das Flag nie gesetzt wird. Ich habe es mit der guten alten LED-Stufentechnik gemessen, bei der ich nach jedem Schritt eine LED anzünde, um zu sehen, wann sie aufhört. Ich habe mir auch die SDA- und SCL-Leitung mit einem Oszilloskop angesehen und kann nur Startbedingungen sehen. Ich habe auch mein Hardware-Setup überprüft, zB ist alles angeschlossen, keine Kurzschlüsse oder fast Kurzschlüsse und überprüft, ob ich andere Geräte verwenden kann, um mit dem IC zu kommunizieren, mit dem ich mit dem dsPIC33 sprechen möchte. Ich habe auch überprüft, ob ich die richtigen Pins verwende. Ich verwende die ASD1/RD9 und ASCL1/RD10, was bedeutet, dass ich in den Konfigurationsbits 'ALTI2C1 = ON' setzen muss.

Aber jetzt gehen mir die Ideen aus, was es sein könnte, dass ich hier falsch mache und warum die Fahne nicht aufgeht. Ich wäre dankbar, wenn mich hier jemand in die richtige Richtung weisen könnte

Allgemeiner Hinweis für die EP-Serie - überprüfen Sie die Errata. Es gibt einige erhebliche Probleme mit dem I2C-Peripheriegerät der EP-Serie, die Problemumgehungen in der Firmware erfordern. Das EP-Silizium hat sich gegenüber der FJ-Serie stark verändert ...

Antworten (1)

Ich glaube, ich habe die Antwort gefunden. In der Initialisierungsfunktion habe ich den I2C-Interrupt eingeschaltet, obwohl ich kein ISR habe. Das Setzen von IEC1bits.MI2C1IE löste mein Problem nicht