MSP430 MPU9250 MPU6050 I2C: Nach dem Senden der Adresse NACK

Ich habe ein Problem mit dem Lesen von meiner MPU6050/MPU9250. Beide sind mit AD0 mit Masse verbunden, also sollten beide die Adresse haben 0x68. Bei beiden Sensoren tritt das gleiche Verhalten auf. Ich teste sie einzeln . Ich habe kürzlich den mpu9250 gekauft, bei dem ich keine Daten lesen konnte. In einem anderen Projekt konnte ich Daten von mpu6050 mit einem stm32 lesen.

Wenn ich diesen Code auf dem MSP430FR5969-Launchpad-Evaluierungskit mit P1.6 als SDA und P1.7 als SCK verwendet habe, werden nach dem Setzen der Startbedingung für die I2C-Kommunikation mit UCB0CTLW0 |= UCTR + UCTXSTT;dem ´TXIEFG0´-Flag und dem ´NACKIE´-Flag gesetzt.

Danach 0x75wird in den Schreibpuffer in ISR geschrieben, aber nie ausgesendet.

Ich habe 4 Stunden im Internet gesucht, aber niemand scheint dieses Problem jemals entdeckt zu haben. Was sind mögliche Gründe?

Nach der Initialisierung sehen meine Register so aus:registriert

Register2

#include "driverlib.h"
#include "MPU9250_reg.h"

/* Slave address */
// b110100X with X = 0 (ADO is connected to ground)=> 0x68
#define SLAVE_ADDRESS 0x68
#define SLAVE_ADDRESS_READ  0x11010001
#define SLAVE_ADDRESS_WRITE ((SLAVE_ADDRESS << 1)|0x00)

volatile uint8_t a;
volatile uint8_t byte_counter;
int main(void) {

    WDT_A_hold(WDT_A_BASE);

    // Configure Pins for I2C
       //Set P1.6 and P1.7 as Secondary Module Function Input.
       /*

       * Select Port 1
       * Set Pin 6, 7 to input Secondary Module Function, (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).
       */
       GPIO_setAsPeripheralModuleFunctionInputPin(
           GPIO_PORT_P1,
           GPIO_PIN6 + GPIO_PIN7,
           GPIO_SECONDARY_MODULE_FUNCTION
       );

           EUSCI_B_I2C_initMasterParam param = {0};
           param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
           param.i2cClk = CS_getSMCLK();
           param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_100KBPS;
           param.byteCounterThreshold = 0;
           param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
           EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, &param);

           PMM_unlockLPM5();
           __bis_SR_register(GIE);


           //Specify slave address
           EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE,
                       SLAVE_ADDRESS_WRITE
                       );

           //Set Master in transmit mode
           EUSCI_B_I2C_setMode(EUSCI_B0_BASE,
                       EUSCI_B_I2C_TRANSMIT_MODE
                       );

           //Enable I2C Module to start operations
           EUSCI_B_I2C_enable(EUSCI_B0_BASE);

           // ensure it not busy
           while(UCB0STATW & UCBBUSY){}

           // send a Stop condition
           UCB0CTLW0 |= UCTXSTP;
           while(!(UCB0CTLW0 & UCTXSTP)){}

           EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
           byte_counter = 1;
           UCB0CTLW0 |= UCTR + UCTXSTT;
           // after this step the UCTXIEF0 and the UCNACKIFG flag are set

    while(1)
    {
        _nop();
    }
}


#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_B0_VECTOR)))
#endif
void USCIB0_ISR(void)
{
    switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
    {
        case USCI_NONE:             // No interrupts break;
            break;
        case USCI_I2C_UCALIFG:      // Arbitration lost
            break;
        case USCI_I2C_UCNACKIFG:    // NAK received (master only)
            break;
        case USCI_I2C_UCSTTIFG:     // START condition detected with own address (slave mode only)
            break;
        case USCI_I2C_UCSTPIFG:     // STOP condition detected (master & slave mode)
            break;
        case USCI_I2C_UCRXIFG3:     // RXIFG3
            break;
        case USCI_I2C_UCTXIFG3:     // TXIFG3
            break;
        case USCI_I2C_UCRXIFG2:     // RXIFG2
            break;
        case USCI_I2C_UCTXIFG2:     // TXIFG2
            break;
        case USCI_I2C_UCRXIFG1:     // RXIFG1
            break;
        case USCI_I2C_UCTXIFG1:     // TXIFG1
            break;
        case USCI_I2C_UCRXIFG0:     // RXIFG0
            // will never be reached cause there a NACK after sending the slave address
            // would be used for receiving
            while(1){}
            break;
        case USCI_I2C_UCTXIFG0:     // TXIFG0
            if(byte_counter == 1)
            {
                // won't be send cause there the NACK before?
                UCB0TXBUF = 0x75;
                byte_counter--;
            }
            else if(byte_counter == 0)
            {
                // clear and disable interrupt
                EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
                EUSCI_B_I2C_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

                // change to receive mode
                UCB0CTLW0 &= ~(UCTR);

                // enable receive interrupt
                EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);


                // send start signal with READ
                //Specify slave address
                EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE,
                            SLAVE_ADDRESS_READ
                            );
                UCB0CTLW0 |= UCTXSTT;
            }
            else
            {
                // not aloud
                while(1){}
            }
            break;
        case USCI_I2C_UCBCNTIFG:    // Byte count limit reached (UCBxTBCNT)
            break;
        case USCI_I2C_UCCLTOIFG:    // Clock low timeout - clock held low too long
            break;
        case USCI_I2C_UCBIT9IFG:    // Generated on 9th bit of a transmit (for debugging)
            break;
        default:
            break;
    }
}

Antworten (2)

I2C-Geräte sollten unterschiedliche Adressen haben. Verbinden Sie den A0 eines Geräts über einen Pull-up-Widerstand mit Vcc, sodass er die Adresse 0x69 hat.

Hey, danke für deine Antwort. Ich habe meine Frage korrigiert. Ich teste immer nur einzeln. Ich habe beide benutzt, um zu sehen, ob einer kaputt ist. Ich konnte mit einem stm32 von MPU6050 lesen, aber ich bin nicht mit dem msp430.
Wie testest du sie einzeln? trennst du den nicht genutzten vom Bus?

Die Slave-Adresse ist 0x68 (1101000), aber der Code verwendet die Adresse 0xD0 (11010000), was gar nicht möglich ist, da normale I²C-Slave-Adressen nur 7 Bit haben.

Und es gibt keinen Grund, die Slave-Adresse vor dem erneuten Start neu einzustellen.

(Anscheinend haben Sie die I²C-Adresse mit dem ersten I²C-Byte verwechselt, das die sieben Bits der Adresse mit dem Lese-/Schreibbit kombiniert.)