STM32驱动BMP280模块

BMP280大气压传感器(我直接叫他高度传感器)看似很冷门,或许大家都觉得,大气压不是一个地区就那么一个值.测量它有什么用?但是这个模块很神奇,它测量精度很高,大气压和所处海拔关系密切,但是精度高的特点使得它可以测你的所在高度,你拿着传感器起身,他的ADC值会发生变化.大佬们就用它给飞控定高(也就是很秀的操作,四轴悬浮在那里,一动不动,很神奇吧!),还有可以做天气监控(Weather monitoring,数据手册写的),所以它是很有必要玩玩的。
先说一下别人分享的代码,虽然编程水平很高,但是很难看懂那些结构体,我总结了一些,把我写的分享给大家,比较清楚的代码。我也看了挺久的数据手册,把我的代码和理解分享给大家
先说一下我的风格吧,我不会一次把代码全贴出来,因为你可能会看懵,一步一步来才能深入,不要先做无用功。

BMP280寄存器

#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

寄存器大概讲一下
1、第一个ID寄存器,读出来好像是0X58,但我的是0X88。
2、第二个复位寄存器,别管太多,让他复位写0xB6就会复位了。
3 、状态寄存器就两个状态,一个是MEASURING,一个是UPDATE,大概意思是当前状态正在测量内部ADC转换,第二个是更新到印象寄存器里。
4、4和5寄存器就是用来设置他的模式了,待会会说
5、最后几个寄存器就是存储ADC读出来的数据寄存器了,XLSB应该是小数位的意思,后面用来浮点转化用的。

I2C基本读写

static uint8_t BMP280_Read_Byte(u8 reg)
{
	uint8_t rec_data;
	I2C_Start();
	I2C_Send_Byte(BMP280_ADDRESS<<1|0);
	I2C_Wait_Ack();
	I2C_Send_Byte(reg);
	I2C_Wait_Ack();
	
	I2C_Start();
	I2C_Send_Byte(BMP280_ADDRESS<<1|1);
	I2C_Wait_Ack();
	rec_data = I2C_Read_Byte(0);	//不应答
	I2C_Stop();
	return rec_data;
}

static void BMP280_Write_Byte(u8 reg,u8 data)
{
	I2C_Start();
	I2C_Send_Byte(BMP280_ADDRESS<<1);
	I2C_Wait_Ack();
	I2C_Send_Byte(reg);
	I2C_Wait_Ack();
	
	I2C_Send_Byte(data);
	I2C_Wait_Ack();
	I2C_Stop();
}

我只用到单字节读写,多字节的目前还没用上,一个I2C时序就不发了,网上都有,这很基础的东西
测试你的I2C没出问题,读一下ID试试,我的是0x88,但是后面读出来的大气压和温度都是对的,别担心,这个我也不知道为什么,或许你是对的,只要能读出来就OK

uint8_t BMP280_ReadID(void)
{
	return BMP280_Read_Byte(BMP280_CHIPID_REG);
}

相关结构体、枚举的定义

也就几个结构体,比较寄存器才那么两三个东西

/BMP工作模式
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;

如果不想看,可以跳过这里,或者待会不懂可以跳回来看一下
1、第一个是模式,三个:睡眠模式、触发模式、正常模式
睡眠模式就是低功耗了,关了不测了;正常模式即连续测,内部一直转化,然后置状态位,我们读寄存器就可以读出原始数据了;触发模式挺有用,你测一次后,传感器进入睡眠模式,下次再测只要重新设置为触发模式就可以再测一次,以此类推,我只说正常模式,触发模式我没写他的代码。你可以自己拓展
2、下面两个都是过采样因子配置,一个是温度,一个是压力,过采样大概是多次采样,获取一个均值,用于滤波
3、这个就是IIR滤波器的常数配置了,可以防止干扰,这些东西也不太需要理解,数据手册中有一个表,针对于不同应用场合,对三个参数进行配置,等会会说一下
4、保持时间,就是两次采样之间的间隔,你在这段时间可以稳定读出寄存器的值
5、下面这个结构体别看很长,就是一个存补偿系数的类型,定义一个全局变量保存,供后面补偿公式计算使用
6、剩余两个结构体就是配置寄存器了,把一个寄存器的东西整合到一起。
PS:BMP280_NORMAL_MODE 这个我看别的文章就直接枚举下去,寄存器是11b才可以进入,所以直接枚举是不行的!我当初在这里浪费了一点时间

BMP280 初始化

要用的矫正数据寄存器,我们不需要了解这些,我是应用的

/*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

自己复制到头文件吧

BMP280* bmp280;		//这个全局结构体变量用来保存存在芯片内ROM补偿参数
void Bmp_Init(void)
{
	u8 Lsb,Msb;
	
	/********************接下来读出矫正参数*********************/
	//温度传感器的矫正值
	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_MODE			BMP_OVERSAMPLE_MODEStructure;
	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_CONFIG					BMP_CONFIGStructure;
	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);
}

然后是开始配置两个寄存器,上面是代码。把数据对齐,写进入。前面说了,两个结构体封装起来了,就跟配置固件库一样用了,先是模式,选正常模式,其他两个先不管,看下面,保持时间选SB1,就是0.5ms,0.5ms够用了。不使能SPI模式。接下来的几个参数,我们根据官方推荐的来配置,人家是开发这个的,跟着来效果肯定最好的。附上图:
在这里插入图片描述
按动态手册设备这个来,压力的过采样去X4,就是模式3;温度x1,模式1,滤波器模式4.这就配置好了

获取原始数据

前面是不是有说到一个寄存器,status这个,传过去数据时,可以用来检测状态,确保转换完成

//获取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;
}

然后获取原始数据,先别急获取现实值,这个函数后面做一下小修改就得到了

//大气压值-Pa
long 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);	//寄存器的值组合起来
	return Bit32 ;
}

main函数是这样的

int main()
{
	/*Parameter Configuration*/
	long BMP_Pressure;
	/*Init*/
	delay_init(168);
	USART_Config();
	MY_I2C_GPIO_Config();
	Bmp_Init();
	printf("\r\nBMP280大气压传感器实验");
	delay_ms(50);
	/*Configuration Operation*/
	printf("\r\nBMP280 ID:0x%d",BMP280_ReadID());	
	delay_ms(2000);	//给你看一下ID
	/*LOOP*/
	while(1)
	{
		while(BMP280_GetStatus(BMP280_MEASURING) != RESET);
		while(BMP280_GetStatus(BMP280_IM_UPDATE) != RESET);
		BMP_Temperature = BMP280_Get_Temperature();
		printf("\r\nPressure %ld",BMP_Pressure);
		delay_ms(200);
	}
}

获取的数据是变化的,不变基本就是I2C或者前面配置出问题了先回去解决基本问题吧,温度传感器的不发了,等下直接给转换的,两个没啥区别

数据补偿转化

两种补偿,定点补偿公式,浮点补偿公式
具体算法我不懂,我按着数据手册移植的,我对这个不感兴趣,直接复制就好了

/**************************传感器值转定点值*************************************/
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

复制上去是不是一堆错呢,加下面宏定义

/*******************************下面是用来计算补偿值相关**********************************/
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****************************************/

STM32是可以64位有符号的,好像是两个32位一正一负,还有我用浮点补偿那部分,F4有浮点运算指令,转换他的计算值很快的。如果是F1的stm32,那就定义那个define后面的东西,然后在后面函数修改一些接口就可以了

/*******************主要部分*********************/
/****************获取传感器精确值****************/
//大气压值-Pa
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*********************************************/

这就是全部代码了,下面这个两个可以直接读出现实生活的数据了
如果需要,我分享一下我的测试代码

int main()
{
	/*Parameter Configuration*/
	double	BMP_Pressure,BMP_Temperature;
	/*Init*/
	delay_init(168);
	USART_Config();
	MY_I2C_GPIO_Config();
	Bmp_Init();
	printf("\r\nBMP280大气压传感器实验");
	delay_ms(50);
	/*Configuration Operation*/
	
	printf("\r\nBMP280 ID:0x%d",BMP280_ReadID());	
	
	delay_ms(2000);
	/*LOOP*/
	while(1)
	{
		while(BMP280_GetStatus(BMP280_MEASURING) != RESET);
		while(BMP280_GetStatus(BMP280_IM_UPDATE) != RESET);
		BMP_Temperature = BMP280_Get_Temperature();
		BMP_Pressure = BMP280_Get_Pressure();
		printf("\r\nTemperature %f C Pressure %f Pa",BMP_Temperature,BMP_Pressure);
		delay_ms(500);
	}
}

串口数据如图
在这里插入图片描述
你可以把传感器抬高,然后压力会变化几帕或者十几帕

结语

这个传感器也是花了我挺久时间,人家的博客,看数据手册,他们的代码似乎不是很清楚,我完善了一下比较易懂,分享给大家,估计又加了一波这个模块的销量。。。

版权声明:本文为CSDN博主「bdjsm_hh」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bdjsm_hh/article/details/107623788

生成海报
点赞 0

bdjsm_hh

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

基于STM32F407 DHT22温湿度测量

一、DHT22简介 1、DHT22介绍说明 DHT22数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电容

OV7670摄像头模块资料

OV7670摄像头模块资料 一、实物图和原理图 二、模块简介 OV7670 是 OV( OmniVision)公司生产的 CMOS VGA 图像传感器。该传感器体积小、工作电压低,提供单片 VGA

TCRT5000循迹模块原理及应用

前言 本文将讲述TCRT5000循迹模块的原理及应用。本文应用于STM32,对于使用循迹模块的你有一定的帮助。 以下是本篇文章的正文内容 一、TCRT5000循迹模块介绍 TCRT5000就是一个红外发射和接收器&#xff0