Режимы задал:
F4 регистр: BMP280_NORMAL_MODE | BMP280_OVERSAMP_T2 | BMP280_OVERSAMP_P16;
F5 регистр: BMP280_STANDBY_TIME_0_5_MS | BMP280_FILTER_COEFF_4;
UPDATE1:
Код инициализации:
Спойлер
Код: Выделить всё
typedef struct _bmp280_cp
{
u16 dig_t1;
s16 dig_t2;
s16 dig_t3;
u16 dig_p1;
s16 dig_p2;
s16 dig_p3;
s16 dig_p4;
s16 dig_p5;
s16 dig_p6;
s16 dig_p7;
s16 dig_p8;
s16 dig_p9;
s32 t_fine;
} bmp280_cal_parm;
u8 bmp280_init( void )
{
u8 com_rslt = 0;
u8 data = 0;
u8 adata[BMP280_CALIB_DATA_SIZE] =
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
// Check ID
com_rslt |= i2c_read_reg
( BMP280_I2C_ADDRESS1,
BMP280_CHIP_ID_REG,
&data,
1 );
if ( ( data != BMP280_CHIP_ID1 ) &&
( data != BMP280_CHIP_ID2 ) &&
( data != BMP280_CHIP_ID3 ) )
return com_rslt |= ERROR_UNIT;
// Set power mode and oversampling
data = BMP280_NORMAL_MODE | BMP280_OVERSAMP_T2 | BMP280_OVERSAMP_P16;
com_rslt |= i2c_write_reg
( BMP280_I2C_ADDRESS1,
BMP280_CTRL_MEAS_REG,
&data,
1 );
// Set standby time and filter
data = BMP280_STANDBY_TIME_0_5_MS | BMP280_FILTER_COEFF_4;
com_rslt |= i2c_write_reg
( BMP280_I2C_ADDRESS1,
BMP280_CONFIG_REG,
&data,
1 );
// Get calibration parameters
com_rslt |= i2c_read_reg
( BMP280_I2C_ADDRESS1,
BMP280_TEMPERATURE_CALIB_DIG_T1_LSB_REG,
adata,
BMP280_CALIB_DATA_SIZE );
bmp280_cp.dig_t1 = ( adata[BMP280_TEMPERATURE_CALIB_DIG_T1_MSB] << 8 ) |
adata[BMP280_TEMPERATURE_CALIB_DIG_T1_LSB];
bmp280_cp.dig_t2 = ( adata[BMP280_TEMPERATURE_CALIB_DIG_T2_MSB] << 8 ) |
adata[BMP280_TEMPERATURE_CALIB_DIG_T2_LSB];
bmp280_cp.dig_t3 = ( adata[BMP280_TEMPERATURE_CALIB_DIG_T3_MSB] << 8 ) |
adata[BMP280_TEMPERATURE_CALIB_DIG_T3_LSB];
bmp280_cp.dig_p1 = ( adata[BMP280_PRESSURE_CALIB_DIG_P1_MSB] << 8 ) |
adata[BMP280_PRESSURE_CALIB_DIG_P1_LSB];
bmp280_cp.dig_p2 = ( adata[BMP280_PRESSURE_CALIB_DIG_P2_MSB] << 8 ) |
adata[BMP280_PRESSURE_CALIB_DIG_P2_LSB];
bmp280_cp.dig_p3 = ( adata[BMP280_PRESSURE_CALIB_DIG_P3_MSB] << 8 ) |
adata[BMP280_PRESSURE_CALIB_DIG_P3_LSB];
bmp280_cp.dig_p4 = ( adata[BMP280_PRESSURE_CALIB_DIG_P4_MSB] << 8 ) |
adata[BMP280_PRESSURE_CALIB_DIG_P4_LSB];
bmp280_cp.dig_p5 = ( adata[BMP280_PRESSURE_CALIB_DIG_P5_MSB] << 8 ) |
adata[BMP280_PRESSURE_CALIB_DIG_P5_LSB];
bmp280_cp.dig_p6 = ( adata[BMP280_PRESSURE_CALIB_DIG_P6_MSB] << 8 ) |
adata[BMP280_PRESSURE_CALIB_DIG_P6_LSB];
bmp280_cp.dig_p7 = ( adata[BMP280_PRESSURE_CALIB_DIG_P7_MSB] << 8 ) |
adata[BMP280_PRESSURE_CALIB_DIG_P7_LSB];
bmp280_cp.dig_p8 = ( adata[BMP280_PRESSURE_CALIB_DIG_P8_MSB] << 8 ) |
adata[BMP280_PRESSURE_CALIB_DIG_P8_LSB];
bmp280_cp.dig_p9 = ( adata[BMP280_PRESSURE_CALIB_DIG_P9_MSB] << 8 ) |
adata[BMP280_PRESSURE_CALIB_DIG_P9_LSB];
return com_rslt;
}
UPDATE2:
Чтение температуры и давления с коррекцией:
Спойлер
Код: Выделить всё
u8 bmp280_get_pt_data( u32 *v_pressure, s32 *v_temperature )
{
u8 com_rslt = 0;
u8 adata[BMP280_TEMPERATURE_DATA_SIZE +
BMP280_PRESSURE_DATA_SIZE] = {0, 0, 0, 0, 0, 0};
s32 unc_pres = 0; // Uncompensate pressure
s32 unc_temp = 0; // Uncompensate temperature
s32 v_x1_u32r = 0;
s32 v_x2_u32r = 0;
// Read temperature and pressure raw data
com_rslt |= i2c_read_reg
( BMP280_I2C_ADDRESS1,
BMP280_PRESSURE_MSB_REG,
adata,
BMP280_TEMPERATURE_DATA_SIZE +
BMP280_PRESSURE_DATA_SIZE );
// Make signed integer value of temperature
unc_temp = ( ( adata[BMP280_TEMPERATURE_MSB_DATA] << 16 ) |
( adata[BMP280_TEMPERATURE_LSB_DATA] << 8 ) |
adata[BMP280_TEMPERATURE_XLSB_DATA] ) >> 4;
// Make signed integer value of pressure
unc_pres = ( ( adata[BMP280_PRESSURE_MSB_DATA] << 16 ) |
( adata[BMP280_PRESSURE_LSB_DATA] << 8 ) |
adata[BMP280_PRESSURE_XLSB_DATA] ) >> 4;
// Compensate temperature
// Calculate x1
v_x1_u32r = ( ( ( ( unc_temp >> 3 ) -
( (s32)bmp280_cp.dig_t1 << 1 ) ) ) *
( (s32)bmp280_cp.dig_t2 ) ) >> 11;
// Calculate x2
v_x2_u32r = ( ( ( ( ( unc_temp >> 4 ) -
( (s32)bmp280_cp.dig_t1 ) ) *
( ( unc_temp >> 4 ) -
( (s32)bmp280_cp.dig_t1 ) ) ) >> 12 ) *
( (s32)bmp280_cp.dig_t3 ) ) >> 14;
// Calculate t_fine
bmp280_cp.t_fine = v_x1_u32r + v_x2_u32r;
// Calculate temperature
*v_temperature = ( bmp280_cp.t_fine * 5 + 128 ) >> 8;
// Compensate pressure
// Calculate x1
v_x1_u32r = ( (s32)bmp280_cp.t_fine >> 1) - (s32)64000;
// Calculate x2
v_x2_u32r = ( ( (v_x1_u32r >> 2) *
(v_x1_u32r >> 2 ) ) >> 11)
* ( (s32)bmp280_cp.dig_p6 );
v_x2_u32r = v_x2_u32r +
( ( v_x1_u32r * ( (s32)bmp280_cp.dig_p5 ) ) << 1 );
v_x2_u32r = ( v_x2_u32r >> 2 ) + ( ( (s32)bmp280_cp.dig_p4 ) << 16 );
// Calculate x1
v_x1_u32r = ( ( ( bmp280_cp.dig_p3 *
( ( ( v_x1_u32r >> 2 ) *
( v_x1_u32r >> 2 ) ) >> 13 ) ) >> 3 ) +
( ( ( (s32)bmp280_cp.dig_p2 ) *
v_x1_u32r ) >> 1 ) ) >> 18;
v_x1_u32r = ( ( ( 32768 + v_x1_u32r ) *
( (s32)bmp280_cp.dig_p1 ) ) >> 15 );
// Calculate pressure
*v_pressure = ( ( (u32)( (s32)1048576 - unc_pres ) -
( v_x2_u32r >> 12 ) ) ) * 3125;
// Check overflow
if ( *v_pressure < 0x80000000 )
// Avoid exception caused by division by zero
if ( v_x1_u32r != 0 )
*v_pressure = ( *v_pressure << 1 ) / ( (u32)v_x1_u32r );
else
return com_rslt | ERROR_INV_DATA;
else
// Avoid exception caused by division by zero
if ( v_x1_u32r != 0 )
*v_pressure = ( *v_pressure / (u32)v_x1_u32r ) * 2;
else
return com_rslt | ERROR_INV_DATA;
// Calculate x1
v_x1_u32r = ( (s32)bmp280_cp.dig_p9 *
(s32)( ( ( *v_pressure >> 3 ) *
( *v_pressure >> 3 ) ) >> 13 ) ) >> 12;
// Calculate x2
v_x2_u32r = ( (s32)( *v_pressure >> 2 ) *
(s32)bmp280_cp.dig_p8 ) >> 13;
// Calculate true pressure
*v_pressure = (u32)( (s32)*v_pressure +
( ( v_x1_u32r +
v_x2_u32r +
bmp280_cp.dig_p7) >> 4 ) );
return com_rslt;
}