0
\$\begingroup\$

I am trying to read accelerometer MMA8652 data with MSP430G2553. I am using TI sample program that was written for temperature sensor. I have change my slave address to default 0x1D for accelerometer, as well add UCB0TXBUF to transmit 0x01 register address to read it from accelerometer.

I2C signals

Actually I have add two lines to sample code:

UCB0I2CSA = 0xFF;                         // Set slave address 1D
UCB0TXBUF = 0x01;                         // which register to read from slave

I am expecting to read accelerometer register 0x01 for MSB of x value.

Could someone advice me how to do repeated start condition? As well it looks like it sends more data than I need or UCB0TXBUF byte is not send.

My code is here:

//  MSP430G2xx3 Demo - USCI_B0 I2C Master to TMP100, Set P1.0 if Temp > 28C
//
//  Description: I2C interface to TMP100 temperature sensor in 9-bit mode.
//  Timer_A CCR0 interrupt is used to wake up and read the two bytes of
//  the TMP100 temperature register every 62ms. If the temperature is greater
//  than 28C, P1.0 is set, else reset. CPU is operated in LPM0. I2C speed
//  is ~100kHz.
//  ACLK = n/a, MCLK = SMCLK = TACLK = BRCLK = default DCO = ~1.2MHz
//
//         /|\           /|\ /|\
//          |   TMP100   10k 10k     MSP430G2xx3
//          |   -------   |   |   -------------------
//          +--|Vcc SDA|<-|---+->|P1.7/UCB0SDA    XIN|-
//          |  |       |  |      |                   |
//          +--|A1,A0  |  |      |               XOUT|-
//             |       |  |      |                   |
//          +--|Vss SCL|<-+------|P1.6/UCB0SCL   P1.0|---> LED
//         \|/  -------          |                   |
//
//  D. Dang
//  Texas Instruments Inc.
//  February 2011
//   Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************
#include <msp430.h>

unsigned int RxByteCtr;
unsigned int RxWord;

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P1SEL |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
  P1SEL2|= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
  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;
  UCB0I2CSA = 0x1D;                         // Set slave address 1D
  UCB0TXBUF = 0x01;                         // which register to read from slave
  UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
  IE2 |= UCB0RXIE;                          // Enable RX interrupt
  TACTL = TASSEL_2 + MC_2;                  // SMCLK, contmode

  while (1)
  {
    RxByteCtr = 2;                          // Load RX byte counter
    UCB0CTL1 |= UCTXSTT;                    // I2C start condition
    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0, enable interrupts
                                            // Remain in LPM0 until all data
                                            // is RX'd

//    if (RxWord < 0x1d00)                    // >28C?
//      P1OUT &= ~0x01;                       // No, P1.0 = 0
//    else
//      P1OUT |= 0x01;                        // Yes, P1.0 = 1

    __disable_interrupt();
    TACCTL0 |= CCIE;                        // TACCR0 interrupt enabled
    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0, enable interrupts
                                            // Remain in LPM0 until TACCR0
                                            // interrupt occurs
    TACCTL0 &= ~CCIE;                       // TACCR0 interrupt disabled
  }
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void TA0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TA0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  __bic_SR_register_on_exit(CPUOFF);        // Exit LPM0
}

// The USCIAB0TX_ISR is structured such that it can be used to receive any
// 2+ number of bytes by pre-loading RxByteCtr with the byte count.
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void)
#else
#error Compiler not supported!
#endif
{
  RxByteCtr--;                              // Decrement RX byte counter

  if (RxByteCtr)
  {
    RxWord = (unsigned int)UCB0RXBUF << 8;  // Get received byte
    if (RxByteCtr == 1)                     // Only one byte left?
      UCB0CTL1 |= UCTXSTP;                  // Generate I2C stop condition
  }
  else
  {
    RxWord |= UCB0RXBUF;                    // Get final received byte,
                                            // Combine MSB and LSB
    __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
  }
}
\$\endgroup\$

migrated from stackoverflow.com Jul 24 '17 at 9:07

This question came from our site for professional and enthusiast programmers.

  • \$\begingroup\$ Do you know that your oscilloscope has a screenshot function that doesn't require you to make a photo in an insane resolution? Anyway, what kind of address is 0xFF supposed to be? And why are you writing to TXBUF when the module is still in reset, and when you have configured it for receiving? And how should anybody know what the correct access sequence would be without a link to the datasheet? \$\endgroup\$ – CL. Jun 14 '17 at 18:45
  • \$\begingroup\$ Thank you for your comment. I know how to save scope traces to file, don't worry, but when you don't have flash drive it is ok to take photos. datasheet is here [link]cache.freescale.com/files/sensors/doc/data_sheet/… Talking about address I have change it only for testing. Normally I am using 0x1D, but tried 0xFF just to make sure it doesn't make any difference. Scope traces looks the same \$\endgroup\$ – Audrius M Jun 14 '17 at 19:34
  • \$\begingroup\$ The datasheet shows that a register read requires both an I²C write and I²C read. There is no TI example program that shows how to do a repeated I²C start condition. \$\endgroup\$ – CL. Jun 14 '17 at 19:52
  • \$\begingroup\$ understood, but still why oscilloscope doesn't show even when I am sending first part of data before repeated start? \$\endgroup\$ – Audrius M Jun 14 '17 at 20:40
  • \$\begingroup\$ Without a valid address, the address byte will not be ACKed. \$\endgroup\$ – CL. Jun 14 '17 at 20:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy