Hi,
I am just working through the MMA8652 example code, and generating my define values.
After searching the net I cannot find an example define value for the SENSITIVITY_2G. So would the below be correct for the example code?
#define SENSITIVITY_2G 1024
Z_offset = (Zout_12_bit - SENSITIVITY_2G) / 2 * (-1); // Compute Z-axis offset correction value
Thanks,
Rocketman46
Hi,
Yes, it is correct:
// MMA8652FC Sensitivity
#define SENSITIVITY_2G 1024
#define SENSITIVITY_4G 512
#define SENSITIVITY_8G 256
/******************************************************************************
* Simple accelerometer offset calibration
******************************************************************************/
void MMA8652FC_Calibration (void)
{
char X_offset, Y_offset, Z_offset;
DataReady = 0;
while (!DataReady){} // Is a first set of data ready?
DataReady = 0;
I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG1, 0x00); // Standby mode
I2C_ReadMultiRegisters(MMA8652FC_I2C_ADDRESS, OUT_X_MSB_REG, 6, AccelData); // Read data output registers 0x01-0x06
Xout_12_bit = ((short) (AccelData[0]<<8 | AccelData[1])) >> 4; // Compute 12-bit X-axis acceleration output value
Yout_12_bit = ((short) (AccelData[2]<<8 | AccelData[3])) >> 4; // Compute 12-bit Y-axis acceleration output value
Zout_12_bit = ((short) (AccelData[4]<<8 | AccelData[5])) >> 4; // Compute 12-bit Z-axis acceleration output value
X_offset = Xout_12_bit / 2 * (-1); // Compute X-axis offset correction value
Y_offset = Yout_12_bit / 2 * (-1); // Compute Y-axis offset correction value
Z_offset = (Zout_12_bit - SENSITIVITY_2G) / 2 * (-1); // Compute Z-axis offset correction value
I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, OFF_X_REG, X_offset);
I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, OFF_Y_REG, Y_offset);
I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, OFF_Z_REG, Z_offset);
I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG1, 0x39); // Active mode again
}
Take a look at my complete example code here.
Regards,
Tomas
PS: If my answer helps to solve your question, please mark it as "Correct". Thank you.
OK thank you for your fast reply. I am converting the code for another MCU. Can you explain the below command. I have outlined what I think is happening, is this correct?
* MMA8652FC_I2C_ADDRESS = I2C address.
* OUT_X_MSB_REG = register.
* AccelData = int16_t AccelData[8];
* Is the 6 in the I2C_ReadMultiRegisters() just reading the low 6 bits?
* If the above is correct, therefore my command is wrong as I am reading the whole word, read_word(MMA8652FC_I2C_ADDRESS, OUT_X_MSB, AccelData);
NXP Original code Code:
I2C_ReadMultiRegisters(MMA8652FC_I2C_ADDRESS, OUT_X_MSB_REG, 6, AccelData); // Read data output registers 0x01-0x06
Xout_12_bit = ((short) (AccelData[0]<<8 | AccelData[1])) >> 4; // Compute 12-bit X-axis acceleration output value
Yout_12_bit = ((short) (AccelData[2]<<8 | AccelData[3])) >> 4; // Compute 12-bit Y-axis acceleration output value
Zout_12_bit = ((short) (AccelData[4]<<8 | AccelData[5])) >> 4; // Compute 12-bit Z-axis acceleration output value
Thanks
Rocektman46
Hi,
I do not quite understand your question.
I believe it is obvious that the burst read is performed using the I2C_ReadMultiRegisters(MMA8652FC_I2C_ADDRESS, OUT_X_MSB_REG, 6, AccelData) function, given the 7-bit slave address of the chip (0x1D), the address of the first register to read (0x01), the number of bytes to read (a value of 6 reads all six data output registers 0x01 – 0x06) and the name of an array of six bytes to store the data in. Such a burst read of 6 bytes from registers 0x01 to 0x06 looks like this:
Hope it is clearer now.
Regards,
Tomas
Hi Tomas,
I do not have the I2C_ReadMultiRegisters() function so I am trying to write my own. Is my below function correct although I have commented it for 6 bytes.
//I2C_ReadMultiRegisters(MMA8652FC_I2C_ADDRESS, OUT_X_MSB, 6, AccelData); // Read data output registers 0x01-0x06
void read_multi_registers(uint8_t MPU_Addr, uint8_t Address, uint8_t Number_Of_Bytes, uint16_t Data)
{
int8_t i;
i2c_start_wait(MPU_Addr + I2C_WRITE);
i2c_write(Address);
i2c_stop();
i2c_start_wait(MPU_Addr + I2C_WRITE);
i2c_write(Address);
i2c_rep_start(0x3B + I2C_READ);
// read first 5 bytes of data
for(i = 0; i < Number_Of_Bytes-1; i++)
{
AccelData[i] = i2c_readAck();
i2c_stop();
}
// read last 6th byte of data
AccelData[i+1] = i2c_readNak();
i2c_stop();
}
Thanks Rocketman46
Hi,
It is usually hard to say whether the function is correct or not without seeing what is going on the bus. Do you have a logic analyzer or an oscilloscope to see the traffic on the bus?
Both the single and multiple bytes read transactions are described in the MMA8652FC data sheet (chapters 5.11.1 and 5.11.2). In my source code, you can find the I2C routines in the I2C.c file within the Sources folder.
Regards,
Tomas
OK thanks.
One last question, can I read the data without configuring the interrupt. I mean just send a command and read data?
Thanks,
Rocketman46