【气象检测项目】BME280

博世BOSCH公司出了两款大气压检测模块,BME280BMP280.

        

BMP280有温度检测、大气压检测

BME280有温度检测、大气压检测、湿度检测

本文主要选用的传感器是BME280,该传感器有两种通信方式,IIC(3.4MHz)和SPI(10MHz)。而我们采用的是IIC通信

电压范围: 1.71 V to 3.6 V

温度范围:-40~+85℃

湿度范围:0~100%RH

大气压范围:300~1100hPa

程序流程图:

根据数据手册我们可以知道,设备的前六位是固定的,而最后一位由SDO决定。

若SDO 接 GND     则设备地址为 0x76

若SDO 接 VDDIO  则设备地址为 0x77

我们通过原理图可以看出SDO接GND,故设备地址为 0x76

从上面的表我们可以得出

设备 ID 地址 为 0xD0,而返回的数值为 0x60

配置 地址为  0xF5

读取大气压地址为0xF7

#define BME280_ADDRESS 0x76

#define BME280_CHIP_ID 0xD0 				//发送芯片ID
#define BME280_DEFAULT_CHIP_ID 0x60         //返回芯片ID

#define BME280_Ctrl_Hum 0xF2
#define BME280_Ctrl_Meas 0xF4
#define BME280_Config 0xF5

#define BME280_Ctrl_Meas_MODE 	(BME280_Temperature_OSR<<5)|(BME280_Pressure_OSR<<2)|BME280_Normal_Mode
#define BME280_Config_MODE  (BME280_TStandBy_1000Ms<<5)|(BME280_Filter_off<<2)|BME280_Spi3W_en

#define BME280_Pressure_OSR 		  BME280_OversamplingX8
#define BME280_Temperature_OSR		BME280_OversamplingX16
#define BME280_Humidity_OSR				BME280_OversamplingX16

#define BME280_OversamplingX1  0x01
#define BME280_OversamplingX2  0x02
#define BME280_OversamplingX4  0x03
#define BME280_OversamplingX8  0x04
#define BME280_OversamplingX16 0x05

#define BME280_Sleep_Mode 0x00
#define BME280_Forced_Mode 0x01
#define BME280_Normal_Mode 0x03

#define BME280_TStandBy_1000Ms 0x05
#define BME280_Filter_off 0x00
#define BME280_Spi3W_en 0x00
void BME280_Init(void)//BME280初始化
{
    //IIC初始化
	gpio_init(GPIOB,GPIO_Pin_6,GPO_P,1);//PB6推挽输出——SDA
	gpio_init(GPIOB,GPIO_Pin_7,GPO_P,1);//PB7推挽输出——SCL

	delay_ms(20);
	
	//检测芯片ID
	bme280ID = IIC_Read_Reg(BME280_ADDRESS,BME280_CHIP_ID);
	
	while(bme280ID != BME280_DEFAULT_CHIP_ID);
	
	
	IIC_Write_Reg(BME280_ADDRESS,BME280_Ctrl_Hum,BME280_Humidity_OSR);
	IIC_Write_Reg(BME280_ADDRESS,BME280_Ctrl_Meas,BME280_Ctrl_Meas_MODE);	
	IIC_Write_Reg(BME280_ADDRESS,BME280_Config,BME280_Config_MODE);	
	
	//校准数据
	trimming_values();
		
}

读取 Trimming data:

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;

int8_t  dig_H1;
int16_t dig_H2;
int8_t  dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t  dig_H6;

void trimming_values(void)
{
	u8 data[32];
	IIC_Read_Buff(BME280_ADDRESS,0x88,24,&data[0]);
	IIC_Read_Buff(BME280_ADDRESS,0xA1,1,&data[24]);
	IIC_Read_Buff(BME280_ADDRESS,0xE1,7,&data[25]);
	
	dig_T1 = (data[1] << 8) | data[0];
	dig_T2 = (data[3] << 8) | data[2];
	dig_T3 = (data[5] << 8) | data[4];
	
	dig_P1 = (data[7] << 8) | data[6];
	dig_P2 = (data[9] << 8) | data[8];
	dig_P3 = (data[11] << 8) | data[10];
	dig_P4 = (data[13] << 8) | data[12];
	dig_P5 = (data[15] << 8) | data[14];
	dig_P6 = (data[17] << 8) | data[16];
	dig_P7 = (data[19] << 8) | data[18];
	dig_P8 = (data[21] << 8) | data[20];
	dig_P9 = (data[23] << 8) | data[22];
	
	dig_H1 =  data[24];
	dig_H2 = (data[26] << 8) | data[25];
	dig_H3 =  data[27];
	dig_H4 =  (data[28] << 4) | (data[29] & 0x0F);
	dig_H5 =  (data[30] << 4) | ((data[29] >> 4) );
	dig_H6 =  data[31];	
}

大气压读取地址:0xF7-0xF9

温度读取地址:0xFA-0xFC

湿度读取地址:0xFD-0xFE

//读取数值
void BME280_GetData(float *pressure,float *temperature,float *humility)
{
	u8 data[8];
	u32 press_t,temp_t,hum_t;
	//校正
	signed long int temp_cal;
	unsigned long int press_cal,hum_cal;

	
	IIC_Read_Buff(BME280_ADDRESS,0xF7,8,&data[0]);
	press_t = (data[0]<<12)|(data[1]<<4)|(data[2]>>4);
	temp_t =  (data[3]<<12)|(data[4]<<4)|(data[5]>>4);
	hum_t =  (data[6]<<8)|data[7];
	
	temp_cal = (double)calibration_T(temp_t) / 100.0;
	press_cal = (double)calibration_P(press_t) / 25600.0;
	hum_cal = (double)calibration_H(hum_t) / 1024.0;
	
	*temperature = temp_cal;
	*pressure = press_cal;
	*humility = hum_cal;
}

数值校正函数:

//返回温度值,单位为度degree,输出值若为“5123”等价于51.23度
signed long int calibration_T(signed long int adc_T)
{
    signed long int var1, var2, T;
    var1 = ((((adc_T >> 3) - ((signed long int)dig_T1<<1))) * ((signed long int)dig_T2)) >> 11;
    var2 = (((((adc_T >> 4) - ((signed long int)dig_T1)) * ((adc_T>>4) - ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14;
    
    t_fine = var1 + var2;
    T = (t_fine * 5 + 128) >> 8;
    return T; 
}
//返回大气压值,单位为Pa
//输出值若为“24674867”  等于 24674867/256 = 96386.2Pa = 963862hPa
unsigned long int calibration_P(signed long int adc_P)
{
    int64_t var1, var2,P;

    var1 = ((int64_t)t_fine) - 128000;
    var2 = var1 * var1  * (int64_t)dig_P6;
    var2 = var2 + ((var1*(int64_t)dig_P5)<<17);
    var2 = var2 + (((int64_t)dig_P4) <<35);
    var1 = ((var1 * var1 * (int64_t)dig_P3) >> 8) + ((var1 * (int64_t)dig_P2) << 12);
	var1 = (((((int64_t)1)<<47)+var1))*((int64_t)dig_P1)>>33;
	   
	if (var1 == 0)    return 0;
 
    P = 1048576-adc_P;
	P = (((P<<31)-var2)*3125)/var1;
    var1 = (((int64_t)dig_P9) * (P>>13) * (P>>13))>>25; 
	var2 = (((int64_t)dig_P8) * P) >> 19;	
	P = ((P + var1 + var2) >> 8) + (((int64_t)dig_P7)<<4);
    
	return (unsigned long int)P;
}
//输出值为"47445",代表 47445/1021 = 46.333%RH
unsigned long int calibration_H(signed long int adc_H)
{
	int64_t v_x1_u32r;

	v_x1_u32r=(t_fine-((int64_t)76800));
	v_x1_u32r=(((((adc_H<<14)-(((int64_t)dig_H4)<<20)-(((int64_t)dig_H5)*v_x1_u32r))+((int64_t)16384))>>15)*(((((((v_x1_u32r*(
		(int64_t)dig_H6))>>10)*(((v_x1_u32r*((int64_t)dig_H3))>>11)+((int64_t)32768)))>>10)+((int64_t)2097152))*((int64_t)
		dig_H2)+8192)>>14));
	v_x1_u32r=(v_x1_u32r-(((((v_x1_u32r>>15)*(v_x1_u32r>>15))>>7)*((int64_t)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 (uint32_t)(v_x1_u32r>>12);
}

最终结果:

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值