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 0x75
wird 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:
#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, ¶m);
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;
}
}
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.
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.)
verzweifeln
Lior Bilia