diff --git a/Inc/DS_BMP180.h b/Inc/DS_BMP180.h new file mode 100644 index 0000000..33848a5 --- /dev/null +++ b/Inc/DS_BMP180.h @@ -0,0 +1,68 @@ +#ifndef DS_BMP180_H +#define DS_BMP180_H + +#include "main.h" + +#ifdef STM32G0 +#include "stm32g0xx_hal.h" +#endif + +#ifdef STM32F0 +#include "stm32f0xx_hal.h" +#endif + +typedef struct __DS_BMP180_CalibrationType +{ + int16_t AC1; + int16_t AC2; + int16_t AC3; + uint16_t AC4; + uint16_t AC5; + uint16_t AC6; + + int16_t B1; + int16_t B2; + + long B5; + + int16_t MB; + int16_t MC; + int16_t MD; + + uint8_t OSS; +} __DS_BMP180_CalibrationType; + + +typedef struct DS_BMP180 +{ + I2C_HandleTypeDef *hi2c; + uint8_t address; + __DS_BMP180_CalibrationType Calibration; + +} DS_BMP180; + +void DS_BMP180_Init(DS_BMP180 *DS_BMP180, I2C_HandleTypeDef *hi2c, uint8_t address); + +/// @brief +/// @param DS_BMP180 +/// @param OversamplingRatio 0 - ultra low power +//// 1 - standard +//// 2 - high resolution +//// 3 - ultra high resolution +void DS_BMP180_StartConversionPressure(DS_BMP180 *DS_BMP180, uint8_t OversamplingRatio); + +void DS_BMP180_StartConversionTemperature(DS_BMP180 *DS_BMP180); + +/// @brief Temperature in 0.1° Celsius +/// @param DS_BMP180 +/// @return +long DS_BMP180_GetTemperature(DS_BMP180 *DS_BMP180); + +/// @brief Pressure in Pascal +/// @param DS_BMP180 +/// @return Pressure +long DS_BMP180_GetPressure(DS_BMP180 *DS_BMP180); + + + +#endif //DS_BMP180_H \ No newline at end of file diff --git a/README.md b/README.md index daa6519..08bf3bf 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ # DS_BMP180 +Для вычисления давления, сначала необходимо вычислить температуру. +Так как часть коэфициентов зависит от неё. + diff --git a/Src/DS_BMP180.c b/Src/DS_BMP180.c new file mode 100644 index 0000000..755b4fc --- /dev/null +++ b/Src/DS_BMP180.c @@ -0,0 +1,127 @@ +#include "DS_BMP180.h" + +void DS_BMP180_Init(DS_BMP180 *DS_BMP180, I2C_HandleTypeDef *hi2c, uint8_t address) +{ + uint8_t calibration[22]; + + DS_BMP180->address = address; + DS_BMP180->hi2c = hi2c; + + for (uint8_t i = 0; i < 21; i++) + { + calibration[i] = 0; + }; + + HAL_I2C_Mem_Read(DS_BMP180->hi2c, DS_BMP180->address, 0xAA, 1, (uint8_t*)(&calibration), 22, 1000); + + // uint8_t a = 0; + // uint8_t temp = 0; + // for (uint8_t i = 0; i < 21; i++) + // { + // if (a==0) + // { + // temp = calibration[i]; + // a++; + // } + // else + // { + // calibration[i-1] = calibration[i]; + // calibration[i] = temp; + // a=0; + // } + // }; + + // int16_t *pAC1 = &calibration[0]; + // void *vp; + // vp = pAC1; + + // uint16_t AC1; + // AC1 = (uint16_t)*((uint16_t *)vp); + + //void AC1 = *pAC1; + + //uint16_t AC1 = *(uint16_t*)(&calibration[0]); + + DS_BMP180->Calibration.AC1 = (calibration[0]<<8) + calibration[1]; + DS_BMP180->Calibration.AC2 = (calibration[2]<<8) + calibration[3]; + DS_BMP180->Calibration.AC3 = (calibration[4]<<8) + calibration[5]; + DS_BMP180->Calibration.AC4 = (calibration[6]<<8) + calibration[7]; + DS_BMP180->Calibration.AC5 = (calibration[8]<<8) + calibration[9]; + DS_BMP180->Calibration.AC6 = (calibration[10]<<8) + calibration[11]; + + DS_BMP180->Calibration.B1 = (calibration[12]<<8) + calibration[13]; + DS_BMP180->Calibration.B2 = (calibration[14]<<8) + calibration[15]; + + DS_BMP180->Calibration.MB = (calibration[16]<<8) + calibration[17]; + DS_BMP180->Calibration.MC = (calibration[18]<<8) + calibration[19]; + DS_BMP180->Calibration.MD = (calibration[20]<<8) + calibration[21]; +} + +void DS_BMP180_StartConversionPressure(DS_BMP180 *DS_BMP180, uint8_t OversamplingRatio) +{ + uint8_t pData[1]; + pData[0] = 0x34 + (OversamplingRatio << 6); + DS_BMP180->Calibration.OSS = OversamplingRatio; + HAL_I2C_Mem_Write(DS_BMP180->hi2c, DS_BMP180->address, 0xF4, 1, (uint8_t*)&pData, 1, 1000); +} + +void DS_BMP180_StartConversionTemperature(DS_BMP180 *DS_BMP180) +{ + uint8_t pData[1]; + pData[0] = 0x2E; + HAL_I2C_Mem_Write(DS_BMP180->hi2c, DS_BMP180->address, 0xF4, 1, (uint8_t*)&pData, 1, 1000); +} + +long DS_BMP180_GetTemperature(DS_BMP180 *DS_BMP180) +{ + uint16_t pow15 = 32768; + uint16_t pow11 = 2048; + uint8_t pow4 = 16; + + uint8_t pData[2]; + HAL_I2C_Mem_Read(DS_BMP180->hi2c, DS_BMP180->address, 0xF6, 1, (uint8_t*)(&pData), 2, 1000); + + long UT = (pData[0]<<8) + pData[1]; + + long X1 = (UT - DS_BMP180->Calibration.AC6) * DS_BMP180->Calibration.AC5 / pow15; + long X2 = DS_BMP180->Calibration.MC * pow11 / (X1+DS_BMP180->Calibration.MD); + DS_BMP180->Calibration.B5 = X1 + X2; + long T = (DS_BMP180->Calibration.B5+8) / pow4; + return T; +} + +long DS_BMP180_GetPressure(DS_BMP180 *DS_BMP180) +{ + uint32_t pow16 = 65536; + uint16_t pow15 = 32768; + uint16_t pow13 = 8192; + uint16_t pow12 = 4096; + uint16_t pow11 = 2048; + uint16_t pow8 = 256; + uint8_t pow4 = 16; + + uint8_t pData[3]; + HAL_I2C_Mem_Read(DS_BMP180->hi2c, DS_BMP180->address, 0xF6, 1, (uint8_t*)(&pData), 8, 1000); + + long UP = ((pData[0]<<16) + (pData[1]<<8) + pData[0]) >> (8-DS_BMP180->Calibration.OSS); + + long B6 = DS_BMP180->Calibration.B5 - 4000; + long X1 = (DS_BMP180->Calibration.B2 * (B6 * B6 / pow12))/pow11; + long X2 = DS_BMP180->Calibration.AC2 * B6 / pow11; + long X3 = X1 + X2; + long B3 = (((DS_BMP180->Calibration.AC1*4+X3)<Calibration.OSS)+2)/4; + X1 = DS_BMP180->Calibration.AC3 * B6 /pow13; + X2 = (DS_BMP180->Calibration.B1*(B6*B6/pow12))/pow16; + X3 = ((X1 + X2)+2)/4; + unsigned long B4 = DS_BMP180->Calibration.AC4 * (unsigned long)(X3+pow15)/pow15; + unsigned long B7 = ((unsigned long)UP - B3)*(50000>>DS_BMP180->Calibration.OSS); + long p; + if (B7 < 0x80000000) {p = (B7 * 2)/B4;} + else {p = (B7 / B4) * 2;} + X1 = (p/pow8)*(p/pow8); + X1 = (X1 * 3038)/pow16; + X2 = (-7357*p)/pow16; + p = p + (X1 + X2 + 3791) / pow4; + + return p; +}