Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 1:7cf70724bdb0, committed 2018-06-21
- Comitter:
- adaphoto
- Date:
- Thu Jun 21 08:46:30 2018 +0000
- Parent:
- 0:35bba382318b
- Commit message:
- ???BMP180????????????????
Changed in this revision
| imu.cpp | Show annotated file Show diff for this revision Revisions of this file |
| imu.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 35bba382318b -r 7cf70724bdb0 imu.cpp
--- a/imu.cpp Thu Jun 21 07:00:40 2018 +0000
+++ b/imu.cpp Thu Jun 21 08:46:30 2018 +0000
@@ -28,7 +28,7 @@
void IMU::IMU_Init()
{
MPU9250_Init();
- //BMP180_Init();
+ BMP180_Init();
q0 = 1.0f;
q1 = 0.0f;
@@ -201,6 +201,16 @@
return data;
}
+
+void IMU::BMP180_ReadReg(uint8_t RegAddr, uint8_t Num, char *pBuffer)
+{
+ char data_write[2];
+ char DevAddr = BMP180_ADDR;
+
+ data_write[0] = RegAddr;
+ i2c.write(DevAddr, data_write, 1, 1);
+ i2c.read(DevAddr, pBuffer, Num, 0);
+}
/**
* @brief Initializes MPU9250
* @param None
@@ -400,4 +410,299 @@
MPU9250_Offset.Y = TempGy >> 5;
MPU9250_Offset.Z = TempGz >> 5;
+}
+
+//******************************************************
+//下面的代码是BMP180
+//******************************************************
+/**
+ * @brief Digital filter
+ * @param *pIndex:
+ * @param *pAvgBuffer:
+ * @param InVal:
+ * @param pOutVal:
+ *
+ * @retval None
+ *
+ */
+void IMU::BMP180_CalAvgValue(uint8_t *pIndex, int32_t *pAvgBuffer, int32_t InVal, int32_t *pOutVal)
+{
+ uint8_t i;
+
+ *(pAvgBuffer + ((*pIndex) ++)) = InVal;
+ *pIndex &= 0x07;
+
+ *pOutVal = 0;
+ for(i = 0; i < 8; i ++)
+ {
+ *pOutVal += *(pAvgBuffer + i);
+ }
+ *pOutVal >>= 3;
+}
+
+/**
+ * @brief Start temperature measurement
+ * @param None
+ * @retval None
+ */
+void IMU::BMP180_StartTemperatureMeasurement(void)
+{
+ //BMP180_WriteReg(CONTROL, READ_TEMPERATURE);
+ I2C_WriteOneByte(BMP180_ADDR, CONTROL, READ_TEMPERATURE);
+}
+
+/**
+ * @brief Start pressure measurement
+ * @param None
+ * @retval None
+ */
+void IMU::BMP180_StartPressureMeasurement(void)
+{
+ //BMP180_WriteReg(CONTROL, READ_PRESSURE + (_oss << 6));
+ I2C_WriteOneByte(BMP180_ADDR, CONTROL, READ_PRESSURE + (_oss << 6));
+}
+
+/**
+ * @brief Read uncompensated temperature
+ * @param None
+ * @retval None
+ */
+void IMU::BMP180_ReadUncompensatedTemperature(void)
+{
+ char RegBuff[2];
+ BMP180_ReadReg(CONTROL_OUTPUT, 2, &RegBuff[0]);
+
+ UT = ((int32_t)RegBuff[0] << 8) + (int32_t)RegBuff[1];
+}
+
+/**
+ * @brief Read uncompensated pressure
+ * @param None
+ * @retval None
+ */
+void IMU::BMP180_ReadUncompensatedPressure(void)
+{
+ char RegBuff[3];
+
+ BMP180_ReadReg(CONTROL_OUTPUT, 3, &RegBuff[0]);
+
+ UP = (((int32_t)RegBuff[0] << 16) + ((int32_t)RegBuff[1] << 8) + ((int32_t)RegBuff[2])) >> (8 -_oss); // uncompensated pressure value
+}
+
+/**
+ * @brief Calculate true temperature
+ * @param *pTrueTemperature: true temperature
+ * @retval None
+ */
+void IMU::BMP180_CalculateTrueTemperature(int32_t *pTrueTemperature)
+{
+ int32_t X1, X2;
+
+ X1 = ((UT - AC6) * AC5) >> 15;
+ X2 = (MC << 11) / (X1 + MD);
+ B5 = X1 + X2;
+ *pTrueTemperature = (B5 + 8) >> 4;
+}
+
+/**
+ * @brief Calculate true pressure
+ * @param *pTruePressure: true pressure
+ * @retval None
+ */
+void IMU::BMP180_CalculateTruePressure(int32_t *pTruePressure)
+{
+ int32_t X1, X2, X3, B3, B6, P, Temp;
+ uint32_t B4, B7;
+
+ B6 = B5 - 4000;
+ X1 = (B2* ((B6 * B6) >> 12)) >> 11;
+ X2 = AC2 * B6 >> 11;
+ X3 = X1 + X2;
+ Temp = (((int32_t)AC1 << 2) + X3) << _oss;
+ B3 = (Temp + 2) >> 2;
+ X1 = (AC3 * B6) >> 13;
+ X2 = (B1 * (B6 * B6 >> 12)) >> 16;
+ X3 = ((X1 + X2) + 2) >> 2;
+ B4 = (AC4 * (uint32_t) (X3 + 32768)) >> 15;
+ B7 = ((uint32_t)UP - B3) * (50000 >> _oss);
+ if(B7 < 0x80000000)
+ {
+ P = (B7 << 1) / B4;
+ }
+ else
+ {
+ P = (B7 / B4) << 1;
+ }
+
+ X1 = (P >> 8) * (P >> 8);
+ X1 = (X1 * 3038) >> 16;
+ X2 = (-7357 * P) >> 16;
+
+ *pTruePressure = P + ((X1 + X2 + 3791) >> 4);
+}
+
+/**
+ * @brief Calculating average value of pressure
+ * @param *pVal: the average value of pressure
+ * @retval None
+ */
+void IMU::BMP180_LocalpressureAvg(int32_t *pVal)
+{
+ uint8_t i;
+ int32_t Sum = 0;
+
+ for(i = 0; i < 5; i ++)
+ {
+ BMP180_StartTemperatureMeasurement();
+ Thread::wait(5);//delay_ms(5); //4.5ms 324
+ BMP180_ReadUncompensatedTemperature();
+ BMP180_StartPressureMeasurement();
+ Thread::wait(5);//delay_ms(8);//7.5ms 540
+ BMP180_ReadUncompensatedPressure();
+ BMP180_CalculateTruePressure(&PressureVal);
+ BMP180_CalculateTrueTemperature(&TemperatureVal);
+
+ if(i >= 2)
+ {
+ Sum += PressureVal;
+ }
+ }
+ *pVal = Sum / 3;
+}
+
+/**
+ * @brief Calculating pressure at sea level
+ * @param None
+ * @retval None
+ */
+void IMU::BMP180_PressureAtSeaLevel(void)
+{
+ float Temp = 0.0f;
+
+ BMP180_LocalpressureAvg(&PressureVal);
+
+ Temp = (float)LOCAL_ADS_ALTITUDE / 4433000;
+ Temp = (float)pow((1 - Temp), 5.255f);
+ Pressure0 = (PressureVal - PRESSURE_OFFSET) / Temp;//
+}
+
+/**
+ * @brief Calculating absolute altitude
+ * @param *pAltitude: absolute altitude
+ * @param PressureVal: the pressure at the absolute altitude
+ * @retval None
+ */
+void IMU::BMP180_CalculateAbsoluteAltitude(int32_t *pAltitude, int32_t PressureVal)
+{
+ *pAltitude = 4433000 * (1 - pow((float)(PressureVal / (float)Pressure0), 0.1903f));
+}
+
+/**
+ * @brief Read calibration data from the EEPROM of the BMP180
+ * @param None
+ * @retval None
+ */
+void IMU::BMP180_ReadCalibrationData(void)
+{
+ char RegBuff[2];
+
+ BMP180_ReadReg(CAL_AC1, 2, RegBuff);
+ AC1 = ((int16_t)RegBuff[0] <<8 | ((int16_t)RegBuff[1]));
+
+ BMP180_ReadReg(CAL_AC2, 2, RegBuff);
+ AC2 = ((int16_t)RegBuff[0] <<8 | ((int16_t)RegBuff[1]));
+
+ BMP180_ReadReg(CAL_AC3, 2, RegBuff);
+ AC3 = ((int16_t)RegBuff[0] <<8 | ((int16_t)RegBuff[1]));
+
+ BMP180_ReadReg(CAL_AC4, 2, RegBuff);
+ AC4 = ((uint16_t)RegBuff[0] <<8 | ((uint16_t)RegBuff[1]));
+
+ BMP180_ReadReg(CAL_AC5, 2, RegBuff);
+ AC5 = ((uint16_t)RegBuff[0] <<8 | ((uint16_t)RegBuff[1]));
+
+ BMP180_ReadReg(CAL_AC6, 2, RegBuff);
+ AC6 = ((uint16_t)RegBuff[0] <<8 | ((uint16_t)RegBuff[1]));
+
+ BMP180_ReadReg(CAL_B1, 2, RegBuff);
+ B1 = ((int16_t)RegBuff[0] <<8 | ((int16_t)RegBuff[1]));
+
+ BMP180_ReadReg(CAL_B2, 2, RegBuff);
+ B2 = ((int16_t)RegBuff[0] <<8 | ((int16_t)RegBuff[1]));
+
+ BMP180_ReadReg(CAL_MB, 2, RegBuff);
+ MB = ((int16_t)RegBuff[0] <<8 | ((int16_t)RegBuff[1]));
+
+ BMP180_ReadReg(CAL_MC, 2, RegBuff);
+ MC = ((int16_t)RegBuff[0] <<8 | ((int16_t)RegBuff[1]));
+
+ BMP180_ReadReg(CAL_MD, 2, RegBuff);
+ MD = ((int16_t)RegBuff[0] <<8 | ((int16_t)RegBuff[1]));
+}
+
+/**
+ * @brief Configures hardware pressure sampling accuracy modes
+ * @param None
+ * @retval None
+ */
+void IMU::BMP180_SetOversample(void)
+{
+ _oss = MODE_ULTRA_HIGHRES;
+}
+
+/**
+ * @brief initializes BMP180
+ * @param None
+ * @retval None
+ */
+void IMU::BMP180_Init(void)
+{
+ BMP180_SetOversample();
+ BMP180_ReadCalibrationData();
+ //BMP180_PressureAtSeaLevel();
+}
+
+/**
+ * @brief Calculation of pressure and temperature and altitude for BMP180
+ * @param None
+ * @retval None
+ */
+void IMU::CalTemperatureAndPressureAndAltitude(void)
+{
+ static uint8_t State = START_TEMPERATURE_MEASUREMENT;
+ static BMP180_AvgTypeDef BMP180_Filter[3];
+ int32_t PVal,AVal, TVal;
+
+ switch(State)
+ {
+ case START_TEMPERATURE_MEASUREMENT:
+ BMP180_StartTemperatureMeasurement();
+ Thread::wait(5);//delay_ms(5); //4.5ms
+ State = READ_UT_AND_START_PRESSURE_MEASUREMENT;
+ break;
+
+ case READ_UT_AND_START_PRESSURE_MEASUREMENT:
+ BMP180_ReadUncompensatedTemperature();
+ BMP180_StartPressureMeasurement();
+ Thread::wait(10);//delay_ms(10);//7.5ms
+ State = READ_UP_CAL_TRUE_PRESSURE_TEMPERATURE;
+ break;
+
+ case READ_UP_CAL_TRUE_PRESSURE_TEMPERATURE:
+ BMP180_ReadUncompensatedPressure();
+ BMP180_CalculateTruePressure(&PVal);
+ BMP180_CalAvgValue(&BMP180_Filter[0].Index, BMP180_Filter[0].AvgBuffer, PVal - PRESSURE_OFFSET, &PressureVal);
+
+ BMP180_CalculateAbsoluteAltitude(&AVal, PVal - PRESSURE_OFFSET);
+ BMP180_CalAvgValue(&BMP180_Filter[1].Index, BMP180_Filter[1].AvgBuffer, AVal, &AltitudeVal);
+
+ BMP180_CalculateTrueTemperature(&TVal);
+ BMP180_CalAvgValue(&BMP180_Filter[2].Index, BMP180_Filter[2].AvgBuffer, TVal, &TemperatureVal);
+
+ State = START_TEMPERATURE_MEASUREMENT;
+ break;
+
+ default:
+ break;
+ }
}
\ No newline at end of file
diff -r 35bba382318b -r 7cf70724bdb0 imu.h
--- a/imu.h Thu Jun 21 07:00:40 2018 +0000
+++ b/imu.h Thu Jun 21 08:46:30 2018 +0000
@@ -56,32 +56,83 @@
#define DEFAULT_ADDRESS GYRO_ADDRESS
#define WHO_AM_I_VAL 0x73 //identity of MPU9250 is 0x71. identity of MPU9255 is 0x73.
- typedef struct
- {
- int16_t X;
- int16_t Y;
- int16_t Z;
- }MPU9250_TypeDef;
-
- typedef struct
- {
- int16_t X_Off_Err;
- int16_t Y_Off_Err;
- int16_t Z_Off_Err;
- }MPU9250_TypeDef_Off;
-
- typedef struct
- {
- uint8_t Index;
- int16_t AvgBuffer[8];
- }MPU9250_AvgTypeDef;
+
+// define BMP180 register address
+//****************************************
+#define BMP180_ADDR 0xEE // default I2C address
+
+/* ---- Registers ---- */
+#define CAL_AC1 0xAA // R Calibration data (16 bits)
+#define CAL_AC2 0xAC // R Calibration data (16 bits)
+#define CAL_AC3 0xAE // R Calibration data (16 bits)
+#define CAL_AC4 0xB0 // R Calibration data (16 bits)
+#define CAL_AC5 0xB2 // R Calibration data (16 bits)
+#define CAL_AC6 0xB4 // R Calibration data (16 bits)
+#define CAL_B1 0xB6 // R Calibration data (16 bits)
+#define CAL_B2 0xB8 // R Calibration data (16 bits)
+#define CAL_MB 0xBA // R Calibration data (16 bits)
+#define CAL_MC 0xBC // R Calibration data (16 bits)
+#define CAL_MD 0xBE // R Calibration data (16 bits)
+#define CONTROL 0xF4 // W Control register
+#define CONTROL_OUTPUT 0xF6 // R Output registers 0xF6=MSB, 0xF7=LSB, 0xF8=XLSB
+
+// BMP180 Modes
+#define MODE_ULTRA_LOW_POWER 0 //oversampling=0, internalsamples=1, maxconvtimepressure=4.5ms, avgcurrent=3uA, RMSnoise_hPA=0.06, RMSnoise_m=0.5
+#define MODE_STANDARD 1 //oversampling=1, internalsamples=2, maxconvtimepressure=7.5ms, avgcurrent=5uA, RMSnoise_hPA=0.05, RMSnoise_m=0.4
+#define MODE_HIGHRES 2 //oversampling=2, internalsamples=4, maxconvtimepressure=13.5ms, avgcurrent=7uA, RMSnoise_hPA=0.04, RMSnoise_m=0.3
+#define MODE_ULTRA_HIGHRES 3 //oversampling=3, internalsamples=8, maxconvtimepressure=25.5ms, avgcurrent=12uA, RMSnoise_hPA=0.03, RMSnoise_m=0.25
+
+// Control register
+#define READ_TEMPERATURE 0x2E
+#define READ_PRESSURE 0x34
+//Other
+#define MSLP 102025 // Mean Sea Level Pressure = 1013.25 hPA (1hPa = 100Pa = 1mbar)
+#define LOCAL_ADS_ALTITUDE 2500 //mm altitude of your position now
+#define PRESSURE_OFFSET 0 //Pa Offset
+/*********************************************/
+// struct
+typedef struct
+{
+ int16_t X;
+ int16_t Y;
+ int16_t Z;
+}MPU9250_TypeDef;
+
+typedef struct
+{
+ int16_t X_Off_Err;
+ int16_t Y_Off_Err;
+ int16_t Z_Off_Err;
+}MPU9250_TypeDef_Off;
+
+typedef struct
+{
+ uint8_t Index;
+ int16_t AvgBuffer[8];
+}MPU9250_AvgTypeDef;
+
+typedef struct
+{
+ uint8_t Index;
+ int32_t AvgBuffer[8];
+}BMP180_AvgTypeDef;
+
+enum
+{
+ START_TEMPERATURE_MEASUREMENT = 0,
+ READ_UT_AND_START_PRESSURE_MEASUREMENT,
+ READ_UP_CAL_TRUE_PRESSURE_TEMPERATURE,
+};
+/*******************************************************/
class IMU
{
public:
+ //IMU
void IMU_Init();
void IMU_GetYawPitchRoll(float*Angles);
+
//MPU9255
void MPU9250_Init();
void MPU9250_READ_ACCEL();
@@ -91,14 +142,32 @@
void MPU9250_CalAvgValue(uint8_t *pIndex, int16_t *pAvgBuffer, int16_t InVal, int32_t *pOutVal);
void MPU9250_InitGyrOffset();
- int16_t accel[3], gyro[3], magn[3];
+ //BMP180
+ void CalTemperatureAndPressureAndAltitude(void);
+ void BMP180_Init(void);
+ void BMP180_StartTemperatureMeasurement(void);
+ void BMP180_StartPressureMeasurement(void);
+ void BMP180_ReadUncompensatedTemperature(void);
+ void BMP180_ReadUncompensatedPressure(void);
+ void BMP180_CalculateTrueTemperature(int32_t *pTrueTemperature);
+ void BMP180_CalculateTruePressure(int32_t *pTruePressure);
+ void BMP180_LocalpressureAvg(int32_t *pVal);
+ void BMP180_PressureAtSeaLevel(void);
+ void BMP180_CalculateAbsoluteAltitude(int32_t *pAltitude, int32_t PressureVal);
+ void BMP180_ReadCalibrationData(void);
+ void BMP180_SetOversample(void);
+
+ int32_t PressureVal, TemperatureVal, AltitudeVal;
private:
+ //IMU
+ float q0, q1, q2, q3;
+ //MPU9250
char BUF[10];
- //int16_t accel[3], gyro[3], magn[3];
+ int16_t accel[3], gyro[3], magn[3];
float angles[3];
- float q0, q1, q2, q3;
+
MPU9250_TypeDef MPU9250_Offset;//={0};
MPU9250_TypeDef_Off MPU9250_Magn_Offset;//={0};
@@ -106,10 +175,18 @@
void IMU_AHRSupdate(float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz);
void IMU_GetQuater(void);
- //void MPU9250_CalAvgValue(uint8_t *pIndex, int16_t *pAvgBuffer, int16_t InVal, int32_t *pOutVal);
+ //BMP180
+ //int32_t PressureVal, TemperatureVal, AltitudeVal;
+ int16_t AC1, AC2, AC3, B1, B2, MB, MC, MD, _oss;
+ uint16_t AC4, AC5, AC6;
+ int32_t B5, UT, UP, Pressure0;
+ void BMP180_CalAvgValue(uint8_t *pIndex, int32_t *pAvgBuffer, int32_t InVal, int32_t *pOutVal);
+
+ //I2C
void I2C_WriteOneByte(uint8_t DevAddr, uint8_t RegAddr, uint8_t Data);
uint8_t I2C_ReadOneByte(uint8_t DevAddr, uint8_t RegAddr);
+ void BMP180_ReadReg(uint8_t RegAddr, uint8_t Num, char *pBuffer);
};
#endif
\ No newline at end of file