一、BMP280气压传感器简介
BMP280是一款博世公司APSM(Advanced Porous Silicon Membrane)工艺的小封装低功耗数字复合传感器,它可以测量环境温湿度和大气压强。气敏元件是一个压阻式低噪高精度高分辨率绝对大气压力感应元件。
二、参数属性
相对湿度:测量范围0%-100%,湿度响应时间:大于1s,湿度测量误差±2%,分辨率0.8%;
气压:测量范围300~1100hPa(百帕斯卡),气压测量误差±1hPa,分辨率0.18Pa。
温度:测量误差±0.5℃,分辨率0.1℃。
工作电压3.3v(不建议接5V烧毁概率较大)。
三、引脚说明
六个引脚,名称与功能如下;
pin1:VCC(3.3V供电,切记不可以接5v)
pin2:GND
pin3:SCL(I2C通信模式时钟信号)
pin4:SDA(I2C通信模式数据信号)
pin5:CSB(SPI通信模式下用到的引脚,片选引脚,拉低后启用,即CSB接高电平为IIC通信,接低电平为SPI,内部电路默认将其上拉为高电平)
pin6:SDO(传感器地址控制位,内部电路默认下拉)
四、附录-源码
说明:
①代码为借鉴某280库代码,并非本人全程撰写,仅提供移植示范。
②代码发布过程中,文字编码不兼容,故出现注释乱码现象。
③引脚说明:取决于你的IIC文件,本例程不附带IIC文件。
.c文件
#include "stm32f10x.h" // Device header
#include "iic.h"
#include "BMP280.h"
BMP280 bmp280_inst;
BMP280* bmp280 = &bmp280_inst; //Õâ¸öÈ«¾Ö½á¹¹Ìå±äÁ¿ÓÃÀ´±£´æ´æÔÚоƬÄÚROM²¹³¥²ÎÊý
void Bmp_Init(void)
{
u8 Lsb,Msb;
BMP_OVERSAMPLE_MODE BMP_OVERSAMPLE_MODEStructure;
BMP_CONFIG BMP_CONFIGStructure;
IIC_Init();
/********************½ÓÏÂÀ´¶Á³ö½ÃÕý²ÎÊý*********************/
//ζȴ«¸ÐÆ÷µÄ½ÃÕýÖµ
Lsb = BMP280_Read_Byte(BMP280_DIG_T1_LSB_REG);
Msb = BMP280_Read_Byte(BMP280_DIG_T1_MSB_REG);
bmp280->T1 = (((u16)Msb)<<8) + Lsb; //¸ßλ¼ÓµÍλ
Lsb = BMP280_Read_Byte(BMP280_DIG_T2_LSB_REG);
Msb = BMP280_Read_Byte(BMP280_DIG_T2_MSB_REG);
bmp280->T2 = (((u16)Msb)<<8) + Lsb;
Lsb = BMP280_Read_Byte(BMP280_DIG_T3_LSB_REG);
Msb = BMP280_Read_Byte(BMP280_DIG_T3_MSB_REG);
bmp280->T3 = (((u16)Msb)<<8) + Lsb;
//´óÆøѹ´«¸ÐÆ÷µÄ½ÃÕýÖµ
Lsb = BMP280_Read_Byte(BMP280_DIG_P1_LSB_REG);
Msb = BMP280_Read_Byte(BMP280_DIG_P1_MSB_REG);
bmp280->P1 = (((u16)Msb)<<8) + Lsb;
Lsb = BMP280_Read_Byte(BMP280_DIG_P2_LSB_REG);
Msb = BMP280_Read_Byte(BMP280_DIG_P2_MSB_REG);
bmp280->P2 = (((u16)Msb)<<8) + Lsb;
Lsb = BMP280_Read_Byte(BMP280_DIG_P3_LSB_REG);
Msb = BMP280_Read_Byte(BMP280_DIG_P3_MSB_REG);
bmp280->P3 = (((u16)Msb)<<8) + Lsb;
Lsb = BMP280_Read_Byte(BMP280_DIG_P4_LSB_REG);
Msb = BMP280_Read_Byte(BMP280_DIG_P4_MSB_REG);
bmp280->P4 = (((u16)Msb)<<8) + Lsb;
Lsb = BMP280_Read_Byte(BMP280_DIG_P5_LSB_REG);
Msb = BMP280_Read_Byte(BMP280_DIG_P5_MSB_REG);
bmp280->P5 = (((u16)Msb)<<8) + Lsb;
Lsb = BMP280_Read_Byte(BMP280_DIG_P6_LSB_REG);
Msb = BMP280_Read_Byte(BMP280_DIG_P6_MSB_REG);
bmp280->P6 = (((u16)Msb)<<8) + Lsb;
Lsb = BMP280_Read_Byte(BMP280_DIG_P7_LSB_REG);
Msb = BMP280_Read_Byte(BMP280_DIG_P7_MSB_REG);
bmp280->P7 = (((u16)Msb)<<8) + Lsb;
Lsb = BMP280_Read_Byte(BMP280_DIG_P8_LSB_REG);
Msb = BMP280_Read_Byte(BMP280_DIG_P8_MSB_REG);
bmp280->P8 = (((u16)Msb)<<8) + Lsb;
Lsb = BMP280_Read_Byte(BMP280_DIG_P9_LSB_REG);
Msb = BMP280_Read_Byte(BMP280_DIG_P9_MSB_REG);
bmp280->P9 = (((u16)Msb)<<8) + Lsb;
/******************************************************/
BMP280_Write_Byte(BMP280_RESET_REG,BMP280_RESET_VALUE); //Íù¸´Î»¼Ä´æÆ÷дÈë¸ø¶¨Öµ
BMP_OVERSAMPLE_MODEStructure.P_Osample = BMP280_P_MODE_3;
BMP_OVERSAMPLE_MODEStructure.T_Osample = BMP280_T_MODE_1;
BMP_OVERSAMPLE_MODEStructure.WORKMODE = BMP280_NORMAL_MODE;
BMP280_Set_TemOversamp(&BMP_OVERSAMPLE_MODEStructure);
BMP_CONFIGStructure.T_SB = BMP280_T_SB1;
BMP_CONFIGStructure.FILTER_COEFFICIENT = BMP280_FILTER_MODE_4;
BMP_CONFIGStructure.SPI_EN = DISABLE;
BMP280_Set_Standby_FILTER(&BMP_CONFIGStructure);
}
//ÉèÖÃBMP¹ý²ÉÑùÒò×Ó MODE
//BMP280_SLEEP_MODE||BMP280_FORCED_MODE||BMP280_NORMAL_MODE
void BMP280_Set_TemOversamp(BMP_OVERSAMPLE_MODE * Oversample_Mode)
{
u8 Regtmp;
Regtmp = ((Oversample_Mode->T_Osample)<<5)|
((Oversample_Mode->P_Osample)<<2)|
((Oversample_Mode)->WORKMODE);
BMP280_Write_Byte(BMP280_CTRLMEAS_REG,Regtmp);
}
//ÉèÖñ£³Öʱ¼äºÍÂ˲¨Æ÷·ÖƵÒò×Ó
void BMP280_Set_Standby_FILTER(BMP_CONFIG * BMP_Config)
{
u8 Regtmp;
Regtmp = ((BMP_Config->T_SB)<<5)|
((BMP_Config->FILTER_COEFFICIENT)<<2)|
((BMP_Config->SPI_EN));
BMP280_Write_Byte(BMP280_CONFIG_REG,Regtmp);
}
//»ñÈ¡BMPµ±Ç°×´Ì¬ Ôʼֵ
//status_flag = BMP280_MEASURING ||
// BMP280_IM_UPDATE
u8 BMP280_GetStatus(u8 status_flag)
{
u8 flag;
flag = BMP280_Read_Byte(BMP280_STATUS_REG);
if(flag&status_flag) return SET;
else return RESET;
}
static uint8_t BMP280_Read_Byte(u8 reg)
{
uint8_t rec_data;
IIC_Start();
IIC_Send_Byte(BMP280_ADDRESS<<1|0);
IIC_Wait_Ack();
IIC_Send_Byte(reg);
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(BMP280_ADDRESS<<1|1);
IIC_Wait_Ack();
rec_data = IIC_Read_Byte(0); //²»Ó¦´ð
IIC_Stop();
return rec_data;
}
void BMP280_Write_Byte(u8 reg,u8 data)
{
IIC_Start();
IIC_Send_Byte(BMP280_ADDRESS<<1);
IIC_Wait_Ack();
IIC_Send_Byte(reg);
IIC_Wait_Ack();
IIC_Send_Byte(data);
IIC_Wait_Ack();
IIC_Stop();
}
uint8_t BMP280_ReadID(void)
{
return BMP280_Read_Byte(BMP280_CHIPID_REG);
}
/*******************Ö÷Òª²¿·Ö*********************/
/****************»ñÈ¡´«¸ÐÆ÷¾«È·Öµ****************/
//´óÆøѹֵ-Pa
/**************************´«¸ÐÆ÷ֵת¶¨µãÖµ*************************************/
BMP280_S32_t t_fine; //ÓÃÓÚ¼ÆËã²¹³¥
//ÎÒÓø¡µã²¹³¥
#ifdef USE_FIXED_POINT_COMPENSATE
// Returns temperature in DegC, resolution is 0.01 DegC. Output value of ¡°5123¡± equals 51.23 DegC.
// t_fine carries fine temperature as global value
BMP280_S32_t bmp280_compensate_T_int32(BMP280_S32_t adc_T)
{
BMP280_S32_t var1, var2, T;
var1 = ((((adc_T>>3) - ((BMP280_S32_t)dig_T1<<1))) * ((BMP280_S32_t)dig_T2)) >> 11;
var2 = (((((adc_T>>4) - ((BMP280_S32_t)dig_T1)) * ((adc_T>>4) - ((BMP280_S32_t)dig_T1))) >> 12) *
((BMP280_S32_t)dig_T3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}
// Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits).
// Output value of ¡°24674867¡± represents 24674867/256 = 96386.2 Pa = 963.862 hPa
BMP280_U32_t bmp280_compensate_P_int64(BMP280_S32_t adc_P)
{
BMP280_S64_t var1, var2, p;
var1 = ((BMP280_S64_t)t_fine) - 128000;
var2 = var1 * var1 * (BMP280_S64_t)dig_P6;
var2 = var2 + ((var1*(BMP280_S64_t)dig_P5)<<17);
var2 = var2 + (((BMP280_S64_t)dig_P4)<<35);
var1 = ((var1 * var1 * (BMP280_S64_t)dig_P3)>>8) + ((var1 * (BMP280_S64_t)dig_P2)<<12);
var1 = (((((BMP280_S64_t)1)<<47)+var1))*((BMP280_S64_t)dig_P1)>>33;
if (var1 == 0)
{
return 0; // avoid exception caused by division by zero
}
p = 1048576-adc_P;
p = (((p<<31)-var2)*3125)/var1;
var1 = (((BMP280_S64_t)dig_P9) * (p>>13) * (p>>13)) >> 25;
var2 = (((BMP280_S64_t)dig_P8) * p) >> 19;
p = ((p + var1 + var2) >> 8) + (((BMP280_S64_t)dig_P7)<<4);
return (BMP280_U32_t)p;
}
/***********************************CUT*************************************/
#else
/**************************´«¸ÐÆ÷ֵת¶¨µãÖµ*************************************/
// Returns temperature in DegC, double precision. Output value of ¡°51.23¡± equals 51.23 DegC.
// t_fine carries fine temperature as global value
double bmp280_compensate_T_double(BMP280_S32_t adc_T)
{
double var1, var2, T;
var1 = (((double)adc_T)/16384.0 - ((double)dig_T1)/1024.0) * ((double)dig_T2);
var2 = ((((double)adc_T)/131072.0 - ((double)dig_T1)/8192.0) *
(((double)adc_T)/131072.0 - ((double) dig_T1)/8192.0)) * ((double)dig_T3);
t_fine = (BMP280_S32_t)(var1 + var2);
T = (var1 + var2) / 5120.0;
return T;
}
// Returns pressure in Pa as double. Output value of ¡°96386.2¡± equals 96386.2 Pa = 963.862 hPa
double bmp280_compensate_P_double(BMP280_S32_t adc_P)
{
double var1, var2, p;
var1 = ((double)t_fine/2.0) - 64000.0;
var2 = var1 * var1 * ((double)dig_P6) / 32768.0;
var2 = var2 + var1 * ((double)dig_P5) * 2.0;
var2 = (var2/4.0)+(((double)dig_P4) * 65536.0);
var1 = (((double)dig_P3) * var1 * var1 / 524288.0 + ((double)dig_P2) * var1) / 524288.0;
var1 = (1.0 + var1 / 32768.0)*((double)dig_P1);
if (var1 == 0.0)
{
return 0; // avoid exception caused by division by zero
}
p = 1048576.0 - (double)adc_P;
p = (p - (var2 / 4096.0)) * 6250.0 / var1;
var1 = ((double)dig_P9) * p * p / 2147483648.0;
var2 = p * ((double)dig_P8) / 32768.0;
p = p + (var1 + var2 + ((double)dig_P7)) / 16.0;
return p;
}
#endif
double BMP280_Get_Pressure(void)
{
uint8_t XLsb,Lsb, Msb;
long signed Bit32;
double pressure;
XLsb = BMP280_Read_Byte(BMP280_PRESSURE_XLSB_REG);
Lsb = BMP280_Read_Byte(BMP280_PRESSURE_LSB_REG);
Msb = BMP280_Read_Byte(BMP280_PRESSURE_MSB_REG);
Bit32 = ((long)(Msb << 12))|((long)(Lsb << 4))|(XLsb>>4); //¼Ä´æÆ÷µÄÖµ,×é³ÉÒ»¸ö¸¡µãÊý
pressure = bmp280_compensate_P_double(Bit32);
return pressure;
}
//ζÈÖµ-¡æ
double BMP280_Get_Temperature(void)
{
uint8_t XLsb,Lsb, Msb;
long signed Bit32;
double temperature;
XLsb = BMP280_Read_Byte(BMP280_TEMPERATURE_XLSB_REG);
Lsb = BMP280_Read_Byte(BMP280_TEMPERATURE_LSB_REG);
Msb = BMP280_Read_Byte(BMP280_TEMPERATURE_MSB_REG);
Bit32 = ((long)(Msb << 12))|((long)(Lsb << 4))|(XLsb>>4); //¼Ä´æÆ÷µÄÖµ,×é³ÉÒ»¸ö¸¡µãÊý
temperature = bmp280_compensate_T_double(Bit32);
return temperature;
}
/***************************************END OF LINE*********************************************/
.h文件
#include "stm32f10x.h"
#ifndef __BMP280_H
#define __BMP280_H
#define BMP280_ADDRESS 0x76 //´ÓÉ豸µØÖ·
#define BMP280_RESET_VALUE 0xB6 //¸´Î»¼Ä´æÆ÷дÈëÖµ
#define BMP280_CHIPID_REG 0xD0 /*Chip ID Register */
#define BMP280_RESET_REG 0xE0 /*Softreset Register */
#define BMP280_STATUS_REG 0xF3 /*Status Register */
#define BMP280_CTRLMEAS_REG 0xF4 /*Ctrl Measure Register */
#define BMP280_CONFIG_REG 0xF5 /*Configuration Register */
#define BMP280_PRESSURE_MSB_REG 0xF7 /*Pressure MSB Register */
#define BMP280_PRESSURE_LSB_REG 0xF8 /*Pressure LSB Register */
#define BMP280_PRESSURE_XLSB_REG 0xF9 /*Pressure XLSB Register */
#define BMP280_TEMPERATURE_MSB_REG 0xFA /*Temperature MSB Reg */
#define BMP280_TEMPERATURE_LSB_REG 0xFB /*Temperature LSB Reg */
#define BMP280_TEMPERATURE_XLSB_REG 0xFC /*Temperature XLSB Reg */
//״̬¼Ä´æÆ÷ת»»±êÖ¾
#define BMP280_MEASURING 0x01
#define BMP280_IM_UPDATE 0x08
/*calibration parameters */
#define BMP280_DIG_T1_LSB_REG 0x88
#define BMP280_DIG_T1_MSB_REG 0x89
#define BMP280_DIG_T2_LSB_REG 0x8A
#define BMP280_DIG_T2_MSB_REG 0x8B
#define BMP280_DIG_T3_LSB_REG 0x8C
#define BMP280_DIG_T3_MSB_REG 0x8D
#define BMP280_DIG_P1_LSB_REG 0x8E
#define BMP280_DIG_P1_MSB_REG 0x8F
#define BMP280_DIG_P2_LSB_REG 0x90
#define BMP280_DIG_P2_MSB_REG 0x91
#define BMP280_DIG_P3_LSB_REG 0x92
#define BMP280_DIG_P3_MSB_REG 0x93
#define BMP280_DIG_P4_LSB_REG 0x94
#define BMP280_DIG_P4_MSB_REG 0x95
#define BMP280_DIG_P5_LSB_REG 0x96
#define BMP280_DIG_P5_MSB_REG 0x97
#define BMP280_DIG_P6_LSB_REG 0x98
#define BMP280_DIG_P6_MSB_REG 0x99
#define BMP280_DIG_P7_LSB_REG 0x9A
#define BMP280_DIG_P7_MSB_REG 0x9B
#define BMP280_DIG_P8_LSB_REG 0x9C
#define BMP280_DIG_P8_MSB_REG 0x9D
#define BMP280_DIG_P9_LSB_REG 0x9E
#define BMP280_DIG_P9_MSB_REG 0x9F
void Bmp_Init(void);
static uint8_t BMP280_Read_Byte(u8 reg);
static void BMP280_Write_Byte(u8 reg,u8 data);
uint8_t BMP280_ReadID(void);
//½á¹¹Ìå²ÎÊý
typedef enum {
BMP280_SLEEP_MODE = 0x0,
BMP280_FORCED_MODE = 0x1, //¿ÉÒÔ˵0x2
BMP280_NORMAL_MODE = 0x3
} BMP280_WORK_MODE;
//BMPѹÁ¦¹ý²ÉÑùÒò×Ó
typedef enum
{
BMP280_P_MODE_SKIP = 0x0, /*skipped*/
BMP280_P_MODE_1, /*x1*/
BMP280_P_MODE_2, /*x2*/
BMP280_P_MODE_3, /*x4*/
BMP280_P_MODE_4, /*x8*/
BMP280_P_MODE_5 /*x16*/
} BMP280_P_OVERSAMPLING;
//BMPζȹý²ÉÑùÒò×Ó
typedef enum {
BMP280_T_MODE_SKIP = 0x0, /*skipped*/
BMP280_T_MODE_1, /*x1*/
BMP280_T_MODE_2, /*x2*/
BMP280_T_MODE_3, /*x4*/
BMP280_T_MODE_4, /*x8*/
BMP280_T_MODE_5 /*x16*/
} BMP280_T_OVERSAMPLING;
//IIRÂ˲¨Æ÷ʱ¼ä³£Êý
typedef enum {
BMP280_FILTER_OFF = 0x0, /*filter off*/
BMP280_FILTER_MODE_1, /*0.223*ODR*/ /*x2*/
BMP280_FILTER_MODE_2, /*0.092*ODR*/ /*x4*/
BMP280_FILTER_MODE_3, /*0.042*ODR*/ /*x8*/
BMP280_FILTER_MODE_4 /*0.021*ODR*/ /*x16*/
} BMP280_FILTER_COEFFICIENT;
//±£³Öʱ¼ä
typedef enum {
BMP280_T_SB1 = 0x0, /*0.5ms*/
BMP280_T_SB2, /*62.5ms*/
BMP280_T_SB3, /*125ms*/
BMP280_T_SB4, /*250ms*/
BMP280_T_SB5, /*500ms*/
BMP280_T_SB6, /*1000ms*/
BMP280_T_SB7, /*2000ms*/
BMP280_T_SB8, /*4000ms*/
} BMP280_T_SB;
typedef struct
{
/* T1~P9 Ϊ²¹³¥ÏµÊý */
uint16_t T1;
int16_t T2;
int16_t T3;
uint16_t P1;
int16_t P2;
int16_t P3;
int16_t P4;
int16_t P5;
int16_t P6;
int16_t P7;
int16_t P8;
int16_t P9;
} BMP280;
typedef struct
{
BMP280_P_OVERSAMPLING P_Osample;
BMP280_T_OVERSAMPLING T_Osample;
BMP280_WORK_MODE WORKMODE;
} BMP_OVERSAMPLE_MODE;
typedef struct
{
BMP280_T_SB T_SB;
BMP280_FILTER_COEFFICIENT FILTER_COEFFICIENT;
FunctionalState SPI_EN;
} BMP_CONFIG;
extern BMP280* bmp280;
void BMP280_Set_TemOversamp(BMP_OVERSAMPLE_MODE * Oversample_Mode);
void BMP280_Set_Standby_FILTER(BMP_CONFIG * BMP_Config);
u8 BMP280_GetStatus(u8 status_flag);
//´óÆøѹֵ-Pa
double BMP280_Get_Pressure(void);
double BMP280_Get_Temperature(void);
/*******************************ÏÂÃæÊÇÓÃÀ´¼ÆËã²¹³¥ÖµÏà¹Ø**********************************/
typedef long signed int BMP280_S32_t; //ÓзûºÅ 64λ£¡
typedef long unsigned int BMP280_U32_t; //ÎÞ·ûºÅ 32λ£¡
typedef long long signed int BMP280_S64_t;
#define dig_T1 bmp280->T1
#define dig_T2 bmp280->T2
#define dig_T3 bmp280->T3
#define dig_P1 bmp280->P1
#define dig_P2 bmp280->P2
#define dig_P3 bmp280->P3
#define dig_P4 bmp280->P4
#define dig_P5 bmp280->P5
#define dig_P6 bmp280->P6
#define dig_P7 bmp280->P7
#define dig_P8 bmp280->P8
#define dig_P9 bmp280->P9
/************************************************CUT****************************************/
#endif
main.c
Bmp_Init();
pa=BMP280_Get_Pressure();