The Reading Problems of MMA8451QR1

For questions and comments on programming in general. And for any items that don't fit into the forums below.

Moderators: Benj, Mods

Post Reply
whatry109
Posts: 3
Joined: Tue Apr 11, 2017 9:32 am
Contact:

The Reading Problems of MMA8451QR1

Post by whatry109 »

Recently I am using MMA8451QR1,I found a phenonmence:
When the right side-up and X=0,Y=0, the value that Z axle read is 40H. According to the datasheet of MMA8451QR1: it’s different form the stadand value.
I would like to ask that:
1).What do the values that X,Y,Z read out belong to ? How to handle them?
The mode that following program set is rapid read mode while X,Z,Y just read one byte.

Code: Select all

#include <msp430.h>
#include "MMA8451Q_register.h"
unsigned char reg[2];
int temp1, temp2, temp3, temp4, temp5, temp6;
void delay(int value)
{
      volatile unsigned int i;
      i = value;                  // SW Delay
      do
          i--;
      while (i != 0);
}
int readiic(unsigned char address)
{
    //   unsigned char temp;
    UCB0CTL1 |= UCTR + UCTXSTT;    // I2C TX, start condition: start and write slave adress
      while (!(IFG2 & UCB0TXIFG))
          ;    // Over the process of waiting for writing address
    //  IFG2 &= ~UCB0TXIFG;
    UCB0TXBUF = address;
    while (!(IFG2 & UCB0TXIFG))
          ;  //  Over the process of waiting for writing address
    //   IFG2 &= ~UCB0TXIFG;
    UCB0CTL1 &= ~UCTR; // set to be read mode
    UCB0CTL1 |= UCTXSTT; // restart + r + SLAVE ADRESS
    while (!(IFG2 & UCB0RXIFG))
          ; //  Over the process of waiting for writing address      if here I wrote it as:   while (!(IFG2 & UCB0TXIFG)),UCB0TXIFG is 0,the program cannot operate
    //   IFG2 &= ~UCB0RXIFG;
    /*   reg[0] = UCB0RXBUF;
     while (!(IFG2 & UCB0RXIFG))
       ; //  over the process of waiting receive data
     //  IFG2 &= ~UCB0RXIFG;
     reg[1] = UCB0RXBUF;
     while (!(IFG2 & UCB0RXIFG))  */
      temp1 = UCB0RXBUF;
      while (!(IFG2 & UCB0RXIFG))
          ;
    temp2 = UCB0RXBUF;
      while (!(IFG2 & UCB0RXIFG))
          ;
    UCB0CTL1 |= UCTXSTP;  // Nack + stop communicate
    return temp2;
}
void write(unsigned char regAddr, unsigned char value)
{
      UCB0CTL1 |= UCTR + UCTXSTT;               // I2C TX, start condition
      while (!(IFG2 & UCB0TXIFG))
          ;                               //  WAIT send over
    // IFG2 &= ~UCB0TXIFG;
    UCB0TXBUF = regAddr;           // Write the register address
    while (!(IFG2 & UCB0TXIFG))
          ;                         //  WAIT send over
    IFG2 &= ~UCB0TXIFG;
    UCB0TXBUF = value;
      while (!(IFG2 & UCB0TXIFG))
          ;
      IFG2 &= ~UCB0TXIFG;
    UCB0CTL1 |= UCTXSTP;  //  Transmit STOP
    delay(100);
}
void main(void)
{
    WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
    P6DIR |= BIT4;
// 0000 0110
      P3SEL |= 0x06;                     // Assign I2C pins to USCI_B0   P3_1,P3_2
      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 = 0x1C;                         // SA0=0 , Slave Address is 1CH
      UCB0CTL1 &= ~UCSWRST;                    // Clear SW reset, resume operation
    P2DIR |= BIT3;   //set P2_3 to be output
    P2OUT |= BIT3;  // P2_3 ,  enable blue VCC,Raising reset pin,make it at the normal state
    P3SEL |= BIT4 + BIT5;  // set P3_4 ,P3_5 to have special function;
    DCOCTL = 0;                          // Select lowest DCOx and MODx settings
      BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
      DCOCTL = CALDCO_1MHZ;
      UCA0CTL1 |= UCSWRST;
      UCA0CTL1 |= UCSSEL_2;   // SMCLK
      UCA0BR0 = 8;    //clock 1MHZ,the baud rate is 115200  refer to datasheet
      UCA0BR1 = 0;
      UCA0MCTL |= UCBRS2 + UCBRS0;   // 5
      UCA0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation  
      IE2 |= UCA0RXIE;
      __enable_interrupt();
    while (1)
      {
          int k;
          P6OUT ^= BIT4;
          delay(20000);
          MMA8451Q_INIT();
          UCA0TXBUF = temp3;
          while (UCA0STAT & UCBUSY)
              ;
          for(k=0;k<=30;k++)
          delay(6000);
        UCA0TXBUF = temp4;
          while (UCA0STAT & UCBUSY)
              ;
          for(k=0;k<=30;k++)
          delay(6000);
          UCA0TXBUF = temp5;
          while (UCA0STAT & UCBUSY)
              ;
          for(k=0;k<=30;k++)
          delay(6000);
          UCA0TXBUF = temp6;
          while (UCA0STAT & UCBUSY)
              ;
          for(k=0;k<=30;k++)
          delay(6000);
      }
}
void MMA8451Q_INIT(void)
{
    write(CTRL_REG1, 0X03);    // Acceleration sensor activation patterns+ Fast Read Mode(Single Byte Data)
      temp3 = readiic(WHO_AM_I);         // the data read out should be 0X1A(DEVICE ID)
      delay(20);
      temp4 = readiic(OUT_X_MSB);       // read X speed dat
    delay(20);
      temp5 = readiic(OUT_Y_MSB);       //read Y speed dat
    delay(20);
      temp6 = readiic(OUT_Z_MSB);       // read Z speed dat
    delay(20);
}
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USC(void)
{
      while (UCA0STAT & UCBUSY)
          ;
      UCA0TXBUF = UCA0RXBUF;C:\Users\Administrator\Desktop
}
Thanks in advance!

User avatar
LeighM
Matrix Staff
Posts: 2178
Joined: Tue Jan 17, 2012 10:07 am
Has thanked: 481 times
Been thanked: 699 times
Contact:

Re: The Reading Problems of MMA8451QR1

Post by LeighM »

Maybe you need a "logical AND", not a "bitwise AND"?

Code: Select all

while (!(IFG2 & UCB0RXIFG))

Code: Select all

while (!(IFG2 && UCB0RXIFG))
Although I've not checked these flags to see if this logic is correct.

Post Reply