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.
解決済! 解決策の投稿を見る。
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.
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.
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);
}
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
Hi,
The problem has been resolved, the reason is that reading values not in the right time. Thank you for your help!
Thanks for the update and glad it is solved.
Regards,
Tomas