MMA8452Q - Reading values most of the time are correct, but sometimes strange

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

MMA8452Q - Reading values most of the time are correct, but sometimes strange

跳至解决方案
1,503 次查看
鑫勇汪
Contributor I

Hi,

   I am using MMA8452 in one of the projects,  most of the time ,I found the reading values of x,y,z axis are correct ,but sometimes one of them has a strange value , for instance,when the sensor is laying,the z-axis value is about 400mg,  but at sometime, the z-axis value will become 500mg  ,In the next second, the z-axis value is still about 400mg,I don't know why there will be a strange value?

Thank you in advance.

无标题.png

标签 (1)
0 项奖励
回复
1 解答
1,164 次查看
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi,

Could you please post here your complete source code or at least the initialization and data reading/processing routines so that we can more easily analyze where the problem might be? Is the device sitting motionless on your desk while you are running your test? How many boards have you tested so far and on how many of them you are observing this „strange“ readings?

You might also find useful my example code written for the MMA8652FC.

Regards,

Tomas

PS: If my answer helps to solve your question, please mark it as "Correct" or “Helpful”. Thank you.

在原帖中查看解决方案

5 回复数
1,165 次查看
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi,

Could you please post here your complete source code or at least the initialization and data reading/processing routines so that we can more easily analyze where the problem might be? Is the device sitting motionless on your desk while you are running your test? How many boards have you tested so far and on how many of them you are observing this „strange“ readings?

You might also find useful my example code written for the MMA8652FC.

Regards,

Tomas

PS: If my answer helps to solve your question, please mark it as "Correct" or “Helpful”. Thank you.

1,164 次查看
鑫勇汪
Contributor I

Hi,

      The following source code is all about the MMA8452  , thank you for you help!

void SensMma8452Config (void)

{

  MMA8452_WriteReg(0x2A,0x01);

    MMA8452_WriteReg(0x2B,0x02);

}

void I2C_Start (void)

{

    SCL_H;

    SDA_H;

    delay_nus(I2C_DALAY);

    SDA_L;

    delay_nus(I2C_DALAY);

}

void I2C_Stop(void)

{

      SDA_L;

    SCL_L;

      SCL_H;

      delay_nus(I2C_DALAY);

      SDA_H;

      delay_nus(I2C_DALAY);

}

unsigned char I2C_SlaveAck(void)

{

    uint16_t ts=0;

    SCL_L;

      MMA_SDA_IOIN();                 

      delay_nus (I2C_DALAY);

      SCL_H;

    delay_nus (I2C_DALAY);

    while(SDA_STATE != 0)

    {

         ts++;

         if(ts>200){

                     MMA_SDA_IOOUT();                

                     SCL_L;

                 return MMA_ERROR;       

         }

     }

         SCL_L;        

         MMA_SDA_IOOUT();                

     delay_nus(I2C_DALAY);

     return MMA_OK;                

}

void I2C_WriteByte(unsigned char a)

{

    unsigned char i;

    for(i=0; i<8; i++){         

        SCL_L;

        delay_nus(I2C_DALAY);

        if((a&0x80)!=0)

            SDA_H;

    else

            SDA_L;

        a <<= 1;

        delay_nus(I2C_DALAY);

        SCL_H;

        delay_nus(I2C_DALAY);

    }  

     SCL_L;

   if(I2C_SlaveAck()== MMA_ERROR)     

   {

     return ;

   }

}

unsigned char I2C_ReadByte (void)

{

      unsigned char a =0;

      unsigned char i;

   

      MMA_SDA_IOIN();                 

  

      for(i=0; i<8; i++){

             a <<= 1; 

              SCL_H;

              delay_nus(I2C_DALAY);

            if(SDA_STATE)

                    a |= 0x01;

                delay_nus(I2C_DALAY);

                SCL_L;

                delay_nus(I2C_DALAY);

                           

      }

        MMA_SDA_IOOUT();                

       

      return a;

}

void SensMMA8452Read (void)

{  

    uint8_t  i,j;

      uint8_t MMA8452_Data[6] = {0};

   

    int     temp;

      int     x_acc_sum = 0;

      int     y_acc_sum = 0;

      int     z_acc_sum = 0;

    int     x_acc_single[10] = {0};

    int     y_acc_single[10] = {0};

    int     z_acc_single[10] = {0};

        for (i = 0; i < 10; i++) {           

            MMA8452_Begin();

           

        I2C_Start();                        

        I2C_WriteByte(SlaveAddress);       

        I2C_WriteByte(0x01);                 

        I2C_Start();                         

        I2C_WriteByte(SlaveAddress+1);     

        MMA8452_Data[0] = I2C_ReadByte();    

        I2C_SlaveAck();

        I2C_Stop();                      

        I2C_Start();                        

        I2C_WriteByte(SlaveAddress);         

        I2C_WriteByte(0x02);                

        I2C_Start();                       

        I2C_WriteByte(SlaveAddress+1);      

        MMA8452_Data[1] = I2C_ReadByte();   

        I2C_SlaveAck();

        I2C_Stop();

        

        I2C_Start();                      

        I2C_WriteByte(SlaveAddress);        

        I2C_WriteByte(0x03);                  

        I2C_Start();                      

        I2C_WriteByte(SlaveAddress+1);     

        MMA8452_Data[2] = I2C_ReadByte();    

        I2C_SlaveAck();

        I2C_Stop();

       

        I2C_Start();                     

        I2C_WriteByte(SlaveAddress);       

        I2C_WriteByte(0x04);                  

        I2C_Start();                       

        I2C_WriteByte(SlaveAddress+1);    

        MMA8452_Data[3] = I2C_ReadByte();    

        I2C_SlaveAck();

        I2C_Stop();

       

        I2C_Start();                      

        I2C_WriteByte(SlaveAddress);       

        I2C_WriteByte(0x05);                 

        I2C_Start();                      

        I2C_WriteByte(SlaveAddress+1);       

        MMA8452_Data[4] = I2C_ReadByte();    

        I2C_SlaveAck();

        I2C_Stop();

       

            I2C_Start();                     

        I2C_WriteByte(SlaveAddress);       

        I2C_WriteByte(0x06);                

        I2C_Start();                        

        I2C_WriteByte(SlaveAddress+1);       

        MMA8452_Data[5] = I2C_ReadByte();  

        I2C_SlaveAck();

        I2C_Stop();

       

            x_acc_single[i] = (MMA8452_Data[0] << 4) + (MMA8452_Data[1] >> 4);

            y_acc_single[i] = (MMA8452_Data[2] << 4) + (MMA8452_Data[3] >> 4);

            z_acc_single[i] = (MMA8452_Data[4] << 4) + (MMA8452_Data[5] >> 4);

   

               

                if (x_acc_single[i] >= 0x800) {           

                    x_acc_single[i] &= 0x7FF;

            x_acc_single[i] = 1999*x_acc_single[i]/2047 - 2000;                   

                } else {

                      x_acc_single[i] = 1999*x_acc_single[i]/2047;

                }

               

                if (y_acc_single[i] >= 0x800) {           

                    y_acc_single[i] &= 0x7FF;

            y_acc_single[i] = 1999*y_acc_single[i]/2047 - 2000;                   

                } else {

                      y_acc_single[i] = 1999*y_acc_single[i]/2047;

                }

               

                if (z_acc_single[i] >= 0x800) {         

                    z_acc_single[i] &= 0x7FF;

            z_acc_single[i] = 1999*z_acc_single[i]/2047 - 2000;                   

                } else {

                      z_acc_single[i] = 1999*z_acc_single[i]/2047;

                }

               

                x_acc_sum += x_acc_single[i];

          y_acc_sum += y_acc_single[i];

            z_acc_sum += z_acc_single[i];   

               

          }

               

            x_acc = x_acc_sum/10;

        y_acc = y_acc_sum/10;

            z_acc = z_acc_sum/10;   

           

}

void MMA8452_Begin (void)

{

    MMA8452_WriteReg(0x2A,0x01);                           //standby mode

      MMA8452_WriteReg(0x2B,0x02);                           //No Sleep Count

}

uint8_t MMA8452_GetResult (unsigned char Regs_Addr)

{

   uint8_t  ret;

 

   ret = MMA8452_ReadReg(Regs_Addr);

   while (ret&0x40) {

       ret=MMA8452_ReadReg(Regs_Addr);          

   }

   return ret;

}

static unsigned char MMA8452_ReadReg (unsigned char Regs_Addr)

{

    unsigned char ret;

  

   

    I2C_Start();  

    I2C_WriteByte(SlaveAddress);    

    I2C_WriteByte(Regs_Addr);           

  

    I2C_Start();

    I2C_WriteByte(SlaveAddress+1);     

    ret=I2C_ReadByte();                   

    I2C_SlaveAck();

    I2C_Stop();                     

  

    return ret;

}

static void MMA8452_WriteReg (unsigned char Regs_Addr, unsigned char Regs_Data)

    I2C_Start();

    I2C_WriteByte(SlaveAddress);    

    I2C_WriteByte(Regs_Addr);           

    I2C_WriteByte(Regs_Data);           

    I2C_Stop();                         

}

static void MMA_SDA_IOOUT(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

  GPIO_InitStructure.GPIO_Pin = SDA ;           

  GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_Out_OD;             

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;            

  GPIO_Init(GPIOB, &GPIO_InitStructure);                       

}

static void MMA_SDA_IOIN(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           

  GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IN_FLOATING;   

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;               

  GPIO_Init(GPIOB, &GPIO_InitStructure);                    

}

0 项奖励
回复
1,164 次查看
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi,

It looks like you are not converting correctly the raw values from registers 0x01 – 0x06 to signed 12-bit values.

You should use something like this:

x_acc_single[i] = ((int) (MMA8452_Data[0] << 8 + MMA8452_Data[1])) >> 4;

y_acc_single[i] = ((int) (MMA8452_Data[2] << 8 + MMA8452_Data[3])) >> 4;

z_acc_single[i] = ((int) (MMA8452_Data[4] << 8 + MMA8452_Data[5])) >> 4;

Please let me know whether or not it helps.

Regards,

Tomas

0 项奖励
回复
1,164 次查看
鑫勇汪
Contributor I

Hi,

       The problem has been resolved, the  reason is that reading values not in the right time. Thank you for your help!

0 项奖励
回复
1,164 次查看
TomasVaverka
NXP TechSupport
NXP TechSupport

Thanks for the update and glad it is solved.

Regards,

Tomas

0 项奖励
回复