HAL library develops BMP280 to read pressure

Based on the STM32F103C8T6 IIC, the pressure and temperature of the BMP280 sensor are read and the altitude is calculated.

The calculated altitude is lower than sea level, but the actual altitude is higher than sea level, which may be related to the ambient temperature and calculation method. The actual measured pressure is greater than 101.325Kpa, and the error is still very large. The renderings are as follows:

Reference documentation:

GitHub - ciastkolog/BMP280_STM32: BMP280 / BME280 driver STM32 HAL I2C

Calculate altitude based on temperature and air pressure_Daqiangqiang Xiaoqiangqiang's blog-CSDN blog_Calculate altitude based on air pressure

Hardware connection: PA9 TX

PA10 RX

PB6 SCL

PB7 SDA

BMP280 module

For transplantation, you only need to download bmp.c bmp280.h;

Or directly copy part of the code below;

main.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bmp280.h"
#include "stdio.h"
#include "math.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */


/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
double pow(double X,double Y);
double data_conversion(double air_pressure,double temperature)
{
    double conversion_alt;
    conversion_alt=(pow(101325/air_pressure,1/5.257)-1)*temperature/0.0065f;
    return conversion_alt;
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
  //    int state=0;
    double Alt;
    bmp280_params_t  params;
    BMP280_HandleTypedef bmp280_dev;
    float pressure, temperature, humidity;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_USART1_UART_Init();
    
  /* USER CODE BEGIN 2 */

    bmp280_init_default_params(&params); //BMP280模块配置参数。
    bmp280_dev.addr = BMP280_I2C_ADDRESS_0;
    bmp280_dev.i2c = &hi2c1;
    bmp280_init(&bmp280_dev, &params);
    
//state=bmp280_init(&bmp280_dev, &params);
//    printf("init state = %d \r\n",state);

    bool bme280p = bmp280_dev.id == BME280_CHIP_ID;
    
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    
    bmp280_read_float(&bmp280_dev, &temperature, &pressure, &humidity);
    Alt=data_conversion(pressure,temperature);
        printf("Pressure: %.2f Pa, Temperature: %.2f C, Alt:%.3f m\r\n", pressure, temperature,Alt);
  if (bme280p)
    printf(", Humidity: %.2f\n", humidity);
  else
    printf("\n");
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
    HAL_Delay(500);

    /* USER CODE END WHILE */
    
    /* USER CODE BEGIN 3 */
    
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
int fputc(int ch,FILE *f){
    HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,100);
    return ch;
}


/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

bmp280.c

/**
 * Ciastkolog.pl (https://github.com/ciastkolog)
 * 
*/
/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2016 sheinz (https://github.com/sheinz)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "bmp280.h"
/**
 * BMP280 registers
 */
#define BMP280_REG_TEMP_XLSB   0xFC /* bits: 7-4 */
#define BMP280_REG_TEMP_LSB    0xFB
#define BMP280_REG_TEMP_MSB    0xFA
#define BMP280_REG_TEMP        (BMP280_REG_TEMP_MSB)
#define BMP280_REG_PRESS_XLSB  0xF9 /* bits: 7-4 */
#define BMP280_REG_PRESS_LSB   0xF8
#define BMP280_REG_PRESS_MSB   0xF7
#define BMP280_REG_PRESSURE    (BMP280_REG_PRESS_MSB)
#define BMP280_REG_CONFIG      0xF5 /* bits: 7-5 t_sb; 4-2 filter; 0 spi3w_en */
#define BMP280_REG_CTRL        0xF4 /* bits: 7-5 osrs_t; 4-2 osrs_p; 1-0 mode */
#define BMP280_REG_STATUS      0xF3 /* bits: 3 measuring; 0 im_update */
#define BMP280_REG_CTRL_HUM    0xF2 /* bits: 2-0 osrs_h; */
#define BMP280_REG_RESET       0xE0
#define BMP280_REG_ID          0xD0
#define BMP280_REG_CALIB       0x88
#define BMP280_REG_HUM_CALIB   0x88

#define BMP280_RESET_VALUE     0xB6



void bmp280_init_default_params(bmp280_params_t *params) {
    params->mode = BMP280_MODE_NORMAL;
    params->filter = BMP280_FILTER_OFF;
    params->oversampling_pressure = BMP280_STANDARD;
    params->oversampling_temperature = BMP280_STANDARD;
    params->oversampling_humidity = BMP280_STANDARD;
    params->standby = BMP280_STANDBY_250;
}

static bool read_register16(BMP280_HandleTypedef *dev, uint8_t addr, uint16_t *value) {
    uint16_t tx_buff;
    uint8_t rx_buff[2];
    tx_buff = (dev->addr << 1);

    if (HAL_I2C_Mem_Read(dev->i2c, tx_buff, addr, 1, rx_buff, 2, 5000)
            == HAL_OK) {
        *value = (uint16_t) ((rx_buff[1] << 8) | rx_buff[0]);
        return true;
    } else
        return false;

}

static inline int read_data(BMP280_HandleTypedef *dev, uint8_t addr, uint8_t *value,
        uint8_t len) {
    uint16_t tx_buff;
    tx_buff = (dev->addr << 1);
//IIC的配置信息结构体    七位地址  内部内存地址 内部内存地址大小 指向数据缓冲区的指针 发送的数据量 超时时间
    if (HAL_I2C_Mem_Read(dev->i2c, tx_buff, addr, 1, value, len, 5000) == HAL_OK)
        return 0;
    else
        return 1;

}

static bool read_calibration_data(BMP280_HandleTypedef *dev) {

    if (read_register16(dev, 0x88, &dev->dig_T1)
            && read_register16(dev, 0x8a, (uint16_t *) &dev->dig_T2)
            && read_register16(dev, 0x8c, (uint16_t *) &dev->dig_T3)
            && read_register16(dev, 0x8e, &dev->dig_P1)
            && read_register16(dev, 0x90, (uint16_t *) &dev->dig_P2)
            && read_register16(dev, 0x92, (uint16_t *) &dev->dig_P3)
            && read_register16(dev, 0x94, (uint16_t *) &dev->dig_P4)
            && read_register16(dev, 0x96, (uint16_t *) &dev->dig_P5)
            && read_register16(dev, 0x98, (uint16_t *) &dev->dig_P6)
            && read_register16(dev, 0x9a, (uint16_t *) &dev->dig_P7)
            && read_register16(dev, 0x9c, (uint16_t *) &dev->dig_P8)
            && read_register16(dev, 0x9e,
                    (uint16_t *) &dev->dig_P9)) {

        return true;
    }

    return false;
}

static bool read_hum_calibration_data(BMP280_HandleTypedef *dev) {
    uint16_t h4, h5;

    if (!read_data(dev, 0xa1, &dev->dig_H1, 1)
            && read_register16(dev, 0xe1, (uint16_t *) &dev->dig_H2)
            && !read_data(dev, 0xe3, &dev->dig_H3, 1)
            && read_register16(dev, 0xe4, &h4)
            && read_register16(dev, 0xe5, &h5)
            && !read_data(dev, 0xe7, (uint8_t *) &dev->dig_H6, 1)) {
        dev->dig_H4 = (h4 & 0x00ff) << 4 | (h4 & 0x0f00) >> 8;
        dev->dig_H5 = h5 >> 4;

        return true;
    }

    return false;
}

static int write_register8(BMP280_HandleTypedef *dev, uint8_t addr, uint8_t value) {
    uint16_t tx_buff;

    tx_buff = (dev->addr << 1);

    if (HAL_I2C_Mem_Write(dev->i2c, tx_buff, addr, 1, &value, 1, 10000) == HAL_OK)
        
        return false;
    else
        return true;
}

bool bmp280_init(BMP280_HandleTypedef *dev, bmp280_params_t *params) {

    if (dev->addr != BMP280_I2C_ADDRESS_0
            && dev->addr != BMP280_I2C_ADDRESS_1) {
        return false;
    }

    if (read_data(dev, BMP280_REG_ID, &dev->id, 1)) {
        return false;
    }

    if (dev->id != BMP280_CHIP_ID && dev->id != BME280_CHIP_ID) {
        return false;
    }

    // Soft reset.
    if (write_register8(dev, BMP280_REG_RESET, BMP280_RESET_VALUE)) {
        return false;
    }
    
    // Wait until finished copying over the NVP data.
    while (1) {
        uint8_t status;
        if (!read_data(dev, BMP280_REG_STATUS, &status, 1)
                && (status & 1) == 0)
            break;
    }

    if (!read_calibration_data(dev)) {
        return false;
    }

    if (dev->id == BME280_CHIP_ID && !read_hum_calibration_data(dev)) {
        return false;
    }

    uint8_t config = (params->standby << 5) | (params->filter << 2);
    if (write_register8(dev, BMP280_REG_CONFIG, config)) {
        return false;
    }

    if (params->mode == BMP280_MODE_FORCED) {
        params->mode = BMP280_MODE_SLEEP;  // initial mode for forced is sleep
    }

    uint8_t ctrl = (params->oversampling_temperature << 5)
            | (params->oversampling_pressure << 2) | (params->mode);

    if (dev->id == BME280_CHIP_ID) {
        // Write crtl hum reg first, only active after write to BMP280_REG_CTRL.
        uint8_t ctrl_hum = params->oversampling_humidity;
        if (write_register8(dev, BMP280_REG_CTRL_HUM, ctrl_hum)) {
            return false;
        }
    }

    if (write_register8(dev, BMP280_REG_CTRL, ctrl)) {
        return false;
    }

    return true;
}

bool bmp280_force_measurement(BMP280_HandleTypedef *dev) {
    uint8_t ctrl;
    if (read_data(dev, BMP280_REG_CTRL, &ctrl, 1)){
        return false;
        }
    
    //ctrl &= ~0b11;  // clear two lower bits 原文这样写编译不通过
    ctrl &= 0x03;  // clear two lower bits
    
    ctrl |= BMP280_MODE_FORCED;
    if (write_register8(dev, BMP280_REG_CTRL, ctrl)) {
        return false;
    }
    return true;
}

bool bmp280_is_measuring(BMP280_HandleTypedef *dev) {
    uint8_t status;
    if (read_data(dev, BMP280_REG_STATUS, &status, 1))
        return false;
    if (status & (1 << 3)) {
        return true;
    }
    return false;
}

/**
 * Compensation algorithm is taken from BMP280 datasheet.
 *
 * Return value is in degrees Celsius.
 */
static inline int32_t compensate_temperature(BMP280_HandleTypedef *dev, int32_t adc_temp,
        int32_t *fine_temp) {
    int32_t var1, var2;

    var1 = ((((adc_temp >> 3) - ((int32_t) dev->dig_T1 << 1)))
            * (int32_t) dev->dig_T2) >> 11;
    var2 = (((((adc_temp >> 4) - (int32_t) dev->dig_T1)
            * ((adc_temp >> 4) - (int32_t) dev->dig_T1)) >> 12)
            * (int32_t) dev->dig_T3) >> 14;

    *fine_temp = var1 + var2;
    return (*fine_temp * 5 + 128) >> 8;
}

/**
 * Compensation algorithm is taken from BMP280 datasheet.
 *
 * Return value is in Pa, 24 integer bits and 8 fractional bits.
 */
static inline uint32_t compensate_pressure(BMP280_HandleTypedef *dev, int32_t adc_press,
        int32_t fine_temp) {
    int64_t var1, var2, p;

    var1 = (int64_t) fine_temp - 128000;
    var2 = var1 * var1 * (int64_t) dev->dig_P6;
    var2 = var2 + ((var1 * (int64_t) dev->dig_P5) << 17);
    var2 = var2 + (((int64_t) dev->dig_P4) << 35);
    var1 = ((var1 * var1 * (int64_t) dev->dig_P3) >> 8)
            + ((var1 * (int64_t) dev->dig_P2) << 12);
    var1 = (((int64_t) 1 << 47) + var1) * ((int64_t) dev->dig_P1) >> 33;

    if (var1 == 0) {
        return 0;  // avoid exception caused by division by zero
    }

    p = 1048576 - adc_press;
    p = (((p << 31) - var2) * 3125) / var1;
    var1 = ((int64_t) dev->dig_P9 * (p >> 13) * (p >> 13)) >> 25;
    var2 = ((int64_t) dev->dig_P8 * p) >> 19;

    p = ((p + var1 + var2) >> 8) + ((int64_t) dev->dig_P7 << 4);
    return p;
}

/**
 * Compensation algorithm is taken from BME280 datasheet.
 *
 * Return value is in Pa, 24 integer bits and 8 fractional bits.
 */
static inline uint32_t compensate_humidity(BMP280_HandleTypedef *dev, int32_t adc_hum,
        int32_t fine_temp) {
    int32_t v_x1_u32r;

    v_x1_u32r = fine_temp - (int32_t) 76800;
    v_x1_u32r = ((((adc_hum << 14) - ((int32_t) dev->dig_H4 << 20)
            - ((int32_t) dev->dig_H5 * v_x1_u32r)) + (int32_t) 16384) >> 15)
            * (((((((v_x1_u32r * (int32_t) dev->dig_H6) >> 10)
                    * (((v_x1_u32r * (int32_t) dev->dig_H3) >> 11)
                            + (int32_t) 32768)) >> 10) + (int32_t) 2097152)
                    * (int32_t) dev->dig_H2 + 8192) >> 14);
    v_x1_u32r = v_x1_u32r
            - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7)
                    * (int32_t) dev->dig_H1) >> 4);
    v_x1_u32r = v_x1_u32r < 0 ? 0 : v_x1_u32r;
    v_x1_u32r = v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r;
    return v_x1_u32r >> 12;
}

bool bmp280_read_fixed(BMP280_HandleTypedef *dev, int32_t *temperature, uint32_t *pressure,
        uint32_t *humidity) {
    int32_t adc_pressure;
    int32_t adc_temp;
    uint8_t data[8];

    // Only the BME280 supports reading the humidity.
    if (dev->id != BME280_CHIP_ID) {
        if (humidity)
            *humidity = 0;
        humidity = NULL;
    }

    // Need to read in one sequence to ensure they match.
    size_t size = humidity ? 8 : 6;
    if (read_data(dev, 0xf7, data, size)) {
        return false;
    }

    adc_pressure = data[0] << 12 | data[1] << 4 | data[2] >> 4;
    adc_temp = data[3] << 12 | data[4] << 4 | data[5] >> 4;

    int32_t fine_temp;
    *temperature = compensate_temperature(dev, adc_temp, &fine_temp);
    *pressure = compensate_pressure(dev, adc_pressure, fine_temp);

    if (humidity) {
        int32_t adc_humidity = data[6] << 8 | data[7];
        *humidity = compensate_humidity(dev, adc_humidity, fine_temp);
    }

    return true;
}

bool bmp280_read_float(BMP280_HandleTypedef *dev, float *temperature, float *pressure,
        float *humidity) {
    int32_t fixed_temperature;
    uint32_t fixed_pressure;
    uint32_t fixed_humidity;
    if (bmp280_read_fixed(dev, &fixed_temperature, &fixed_pressure,
            humidity ? &fixed_humidity : NULL)) {
        *temperature = (float) fixed_temperature / 100;
        *pressure = (float) fixed_pressure / 256;
        if (humidity)
            *humidity = (float) fixed_humidity / 1024;
        return true;
    }

    return false;
}

bmp280.h

/**
 * Ciastkolog.pl (https://github.com/ciastkolog)
 * 
*/
/**
 * The MIT License (MIT)
 * Copyright (c) 2016 sheinz (https://github.com/sheinz)
 */
#ifndef __BMP280_H__
#define __BMP280_H__

#include "stm32f1xx_hal.h"
#include <stdint.h>
#include <stdbool.h>

/**
 * BMP280 or BME280 address is 0x77 if SDO pin is high, and is 0x76 if
 * SDO pin is low.
 */

#define BMP280_I2C_ADDRESS_0  0x76
#define BMP280_I2C_ADDRESS_1  0x77

#define BMP280_CHIP_ID  0x58 /* BMP280 has chip-id 0x58 */
#define BME280_CHIP_ID  0x60 /* BME280 has chip-id 0x60 */

/**
 * Mode of BMP280 module operation.
 * Forced - Measurement is initiated by user.
 * Normal - Continues measurement.
 */
typedef enum {
    BMP280_MODE_SLEEP = 0,
    BMP280_MODE_FORCED = 1,
    BMP280_MODE_NORMAL = 3
} BMP280_Mode;

typedef enum {
    BMP280_FILTER_OFF = 0,
    BMP280_FILTER_2 = 1,
    BMP280_FILTER_4 = 2,
    BMP280_FILTER_8 = 3,
    BMP280_FILTER_16 = 4
} BMP280_Filter;

/**
 * Pressure oversampling settings
 * 压力过采样设置
 */
typedef enum {
    BMP280_SKIPPED = 0,          /* no measurement  */
    BMP280_ULTRA_LOW_POWER = 1,  /* oversampling x1 */
    BMP280_LOW_POWER = 2,        /* oversampling x2 */
    BMP280_STANDARD = 3,         /* oversampling x4 */
    BMP280_HIGH_RES = 4,         /* oversampling x8 */
    BMP280_ULTRA_HIGH_RES = 5    /* oversampling x16 */
} BMP280_Oversampling;

/**
 * Stand by time between measurements in normal mode
 */
typedef enum {
    BMP280_STANDBY_05 = 0,      /* stand by time 0.5ms */
    BMP280_STANDBY_62 = 1,      /* stand by time 62.5ms */
    BMP280_STANDBY_125 = 2,     /* stand by time 125ms */
    BMP280_STANDBY_250 = 3,     /* stand by time 250ms */
    BMP280_STANDBY_500 = 4,     /* stand by time 500ms */
    BMP280_STANDBY_1000 = 5,    /* stand by time 1s */
    BMP280_STANDBY_2000 = 6,    /* stand by time 2s BMP280, 10ms BME280 */
    BMP280_STANDBY_4000 = 7,    /* stand by time 4s BMP280, 20ms BME280 */
} BMP280_StandbyTime;

/**
 * Configuration parameters for BMP280 module.
 * Use function bmp280_init_default_params to use default configuration.
 */
typedef struct {
    BMP280_Mode mode;
    BMP280_Filter filter;
    BMP280_Oversampling oversampling_pressure;
    BMP280_Oversampling oversampling_temperature;
    BMP280_Oversampling oversampling_humidity;
    BMP280_StandbyTime standby;
} bmp280_params_t;


typedef struct {
    uint16_t dig_T1;
    int16_t  dig_T2;
    int16_t  dig_T3;
    uint16_t dig_P1;
    int16_t  dig_P2;
    int16_t  dig_P3;
    int16_t  dig_P4;
    int16_t  dig_P5;
    int16_t  dig_P6;
    int16_t  dig_P7;
    int16_t  dig_P8;
    int16_t  dig_P9;

    /* Humidity compensation for BME280 */
    uint8_t  dig_H1;
    int16_t  dig_H2;
    uint8_t  dig_H3;
    int16_t  dig_H4;
    int16_t  dig_H5;
    int8_t   dig_H6;

    uint16_t addr;

    I2C_HandleTypeDef* i2c;

    bmp280_params_t params;

    uint8_t  id;        /* Chip ID */

} BMP280_HandleTypedef;

/**
 * Initialize default parameters.
 * Default configuration:
 *      mode: NORAML
 *      filter: OFF
 *      oversampling: x4
 *      standby time: 250ms
 */
void bmp280_init_default_params(bmp280_params_t *params);

/**
 * Initialize BMP280 module, probes for the device, soft resets the device,
 * reads the calibration constants, and configures the device using the supplied
 * parameters. Returns true on success otherwise false.
 *
 * The I2C address is assumed to have been initialized in the dev, and
 * may be either BMP280_I2C_ADDRESS_0 or BMP280_I2C_ADDRESS_1. If the I2C
 * address is unknown then try initializing each in turn.
 *
 * This may be called again to soft reset the device and initialize it again.
 */
bool bmp280_init(BMP280_HandleTypedef *dev, bmp280_params_t *params);

/**
 * Start measurement in forced mode.
 * The module remains in forced mode after this call.
 * Do not call this method in normal mode.
 */
bool bmp280_force_measurement(BMP280_HandleTypedef *dev);

/**
 * Check if BMP280 is busy with measuring temperature/pressure.
 * Return true if BMP280 is busy.
 */
bool bmp280_is_measuring(BMP280_HandleTypedef *dev);

/**
 * Read compensated temperature and pressure data:
 *
 *  Temperature in degrees Celsius times 100.
 *
 *  Pressure in Pascals in fixed point 24 bit integer 8 bit fraction format.
 *
 *  Humidity is optional and only read for the BME280, in percent relative
 *  humidity as a fixed point 22 bit interger and 10 bit fraction format.
 */
bool bmp280_read_fixed(BMP280_HandleTypedef *dev, int32_t *temperature,
                       uint32_t *pressure, uint32_t *humidity);

/**
 * Read compensated temperature and pressure data:
 *  Temperature in degrees Celsius.
 *  Pressure in Pascals.
 *  Humidity is optional and only read for the BME280, in percent relative
 *  humidity.
 */
bool bmp280_read_float(BMP280_HandleTypedef *dev, float *temperature,
                       float *pressure, float *humidity);


#endif  // __BMP280_H__

Guess you like

Origin blog.csdn.net/jiujiumo_/article/details/128925030