In one of my previous documents I presented a simple example code/demo that reads both the altitude and temperature data from the Xtrinsic MPL3115A2 pressure sensor and visualizes them using the FreeMASTER tool via USBDM interface. This time I would like to share another example with the MPL3115A2 programmed to measure pressure (barometer mode) and temperature. The Freescale FRDM-KL25Z board coupled with the Xtrinsic MEMS sensors board was used for this project.
The initialization of the Kinetis KL25Z128 MCU remains the same, the only small change is in the initialization of the MPL3115A2, this time the barometer mode is selected with the OSR of 128.
void MPL3115A2_Init (void)
unsigned char reg_val = 0;
I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG1, 0x04); // Reset all registers to POR values
do // Wait for the RST bit to clear
reg_val = I2C_ReadRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG1) & 0x04;
} while (reg_val);
I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, PT_DATA_CFG_REG, 0x07); // Enable data flags
I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG3, 0x11); // Open drain, active low interrupts
I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG4, 0x80); // Enable DRDY interrupt
I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG5, 0x00); // DRDY interrupt routed to INT2 - PTD3
I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG1, 0x39); // Active barometer mode, OSR = 128
In the main loop, both pressure and temperature data are read and then calculated as follows.
if (DataReady) // Is a new set of data ready?
DataReady = 0;
/* Read both the pressure and temperature data */
OUT_P_MSB = I2C_ReadRegister(MPL3115A2_I2C_ADDRESS, OUT_P_MSB_REG);
OUT_P_CSB = I2C_ReadRegister(MPL3115A2_I2C_ADDRESS, OUT_P_CSB_REG);
OUT_P_LSB = I2C_ReadRegister(MPL3115A2_I2C_ADDRESS, OUT_P_LSB_REG);
OUT_T_MSB = I2C_ReadRegister(MPL3115A2_I2C_ADDRESS, OUT_T_MSB_REG);
OUT_T_LSB = I2C_ReadRegister(MPL3115A2_I2C_ADDRESS, OUT_T_LSB_REG);
/* Get pressure, the 20-bit measurement in Pascals is comprised of an unsigned integer component and a fractional component.
The unsigned 18-bit integer component is located in OUT_P_MSB, OUT_P_CSB and bits 7-6 of OUT_P_LSB.
The fractional component is located in bits 5-4 of OUT_P_LSB. Bits 3-0 of OUT_P_LSB are not used.*/
Pressure = (float) (((OUT_P_MSB << 16) | (OUT_P_CSB << 8) | (OUT_P_LSB & 0xC0)) >> 6) + (float) ((OUT_P_LSB & 0x30) >> 4) * 0.25;
/* Get temperature, the 12-bit temperature measurement in °C is comprised of a signed integer component and a fractional component.
The signed 8-bit integer component is located in OUT_T_MSB. The fractional component is located in bits 7-4 of OUT_T_LSB.
Bits 3-0 of OUT_T_LSB are not used. */
Temperature = (float) ((signed char) OUT_T_MSB) + (float) (OUT_T_LSB >> 4) * 0.0625;
As usual, the calculated values can be watched in the "Variables" window on the top right of the Debug perspective or in the FreeMASTER application.
The complete source code written in the CW 10.3 as well as the FreeMASTER project is attached to this document.
If there are any questions regarding this simple application, please feel free to ask below. Your feedback or suggestions are also welcome.