赞
踩
博世BOSCH公司出了两款大气压检测模块,BME280和BMP280.
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];
- }
- //读取数值
- 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);
- }
最终结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。