Any help figuring out how to get i2c working with the MPU6050 would be appreciated.
or some tutorials to follow for the msp430F55 series.
What's the best way to debug serial communication, just print the data to console to see if it's valid?
I don't know how exactly I set the R/W bit and I think that after I send the address to the MPU6050 I don't do a start condition again and send the register I want to read. Basically what would be the program flow to read from a register.
Send the address byte with R enabled then send start condition with the register Byte then enable RX flags?
#include <msp430.h> unsigned char RX_Data[6]; unsigned char TX_Data[2]; unsigned char RX_ByteCtr; unsigned char TX_ByteCtr; unsigned char * PTxData; unsigned char * PRxData; int xAccel; int yAccel; int zAccel; unsigned char slaveAddress = 0x68; // Set slave address for MPU-6050 // 0x68 for ADD pin=0 // 0x69 for ADD pin=1 // MPU-6050 register address const unsigned char ACCEL_XOUT_H = 0x3B; // MPU-6050 register address const unsigned char ACCEL_XOUT_L = 0x3C; // MPU-6050 register address const unsigned char ACCEL_YOUT_H = 0x3D; // MPU-6050 register address const unsigned char ACCEL_YOUT_L = 0x3E; // MPU-6050 register address const unsigned char ACCEL_ZOUT_H = 0x3F; // MPU-6050 register address const unsigned char ACCEL_ZOUT_L = 0x40; // MPU-6050 register address void i2cInit(void); void i2cWrite(unsigned char); void i2cRead(unsigned char); int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT // Set clock speed (default = 1 MHz) // set up I2C pins P3SEL |= 0x03; // Assign I2C pins to USCI_B0 PTxData = (unsigned char*)TX_Data; PRxData = (unsigned char*)RX_Data; // Initialize the I2C state machine i2cInit(); // Wake up the MPU-6050 slaveAddress = 0x68; // MPU-6050 address TX_Data[1] = 0x75; // WhoAmI TX_ByteCtr = 1; i2cWrite(slaveAddress); i2cRead(slaveAddress); while (1) { // Point to the ACCEL_ZOUT_H register in the MPU-6050 slaveAddress = 0x68; // MPU-6050 address TX_Data[0] = 0x3C; TX_Data[1] = 0x3B;// register address TX_ByteCtr = 2; i2cWrite(slaveAddress); // Read the two bytes of data and store them in zAccel slaveAddress = 0x68; // MPU-6050 address RX_ByteCtr = 6; i2cRead(slaveAddress); xAccel = RX_Data[5] << 8; // MSB xAccel |= RX_Data[4]; // LSB yAccel = RX_Data[3] << 8; // MSB yAccel |= RX_Data[2]; // LSB zAccel = RX_Data[1] << 8; // MSB zAccel |= RX_Data[0]; // LSB // do something with the data __no_operation(); // Set breakpoint >>here<< and read } } //********************************************************************************************* void i2cInit(void) { // set up I2C module UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz UCB0BR1 = 0; UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation } //********************************************************************************************* void i2cWrite(unsigned char address) { __disable_interrupt(); UCB0I2CSA = address; // Load slave address UCB0IE |= UCTXIE; // Enable TX interrupt while(UCB0CTL1 & UCTXSTP); // Ensure stop condition sent UCB0CTL1 |= UCTR + UCTXSTT; // TX mode and START condition __bis_SR_register(GIE); // sleep until UCB0TXIFG is set ... } //********************************************************************************************* void i2cRead(unsigned char address) { __disable_interrupt(); UCB0I2CSA = address; // Load slave address UCB0IE |= UCRXIE; // Enable RX interrupt while(UCB0CTL1 & UCTXSTP); // Ensure stop condition sent UCB0CTL1 &= ~UCTR; // RX mode UCB0CTL1 |= UCTXSTT; // Start Condition __bis_SR_register(GIE); // sleep until UCB0RXIFG is set ... } /**********************************************************************************************/ // USCIAB0TX_ISR #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = USCI_B0_VECTOR __interrupt void USCI_B0_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void) #else #error Compiler not supported! #endif { switch(__even_in_range(UCB0IV,12)) { case 0: break; // Vector 0: No interrupts case 2: break; // Vector 2: ALIFG case 4: break; // Vector 4: NACKIFG case 6: break; // Vector 6: STTIFG case 8: break; // Vector 8: STPIFG case 10: // Vector 10: RXIFG RX_ByteCtr--; // Decrement RX byte counter if (RX_ByteCtr) { *PRxData++ = UCB0RXBUF; // Move RX data to address PRxData if (RX_ByteCtr == 1) // Only one byte left? UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition } else { *PRxData = UCB0RXBUF; // Move final RX data to PRxData; } break; case 12: // Vector 12: TXIFG if (TX_ByteCtr) // Check TX byte counter { UCB0TXBUF = *PTxData++; // Load TX buffer TX_ByteCtr--; // Decrement TX byte counter } else { // UCB0CTL1 |= UCTXSTP; // I2C stop condition UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag } break; default: break; } }