当前位置:   article > 正文

【气象检测项目】BME280

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

  1. #define BME280_ADDRESS 0x76
  2. #define BME280_CHIP_ID 0xD0 //发送芯片ID
  3. #define BME280_DEFAULT_CHIP_ID 0x60 //返回芯片ID
  4. #define BME280_Ctrl_Hum 0xF2
  5. #define BME280_Ctrl_Meas 0xF4
  6. #define BME280_Config 0xF5
  7. #define BME280_Ctrl_Meas_MODE (BME280_Temperature_OSR<<5)|(BME280_Pressure_OSR<<2)|BME280_Normal_Mode
  8. #define BME280_Config_MODE (BME280_TStandBy_1000Ms<<5)|(BME280_Filter_off<<2)|BME280_Spi3W_en
  9. #define BME280_Pressure_OSR BME280_OversamplingX8
  10. #define BME280_Temperature_OSR BME280_OversamplingX16
  11. #define BME280_Humidity_OSR BME280_OversamplingX16
  12. #define BME280_OversamplingX1 0x01
  13. #define BME280_OversamplingX2 0x02
  14. #define BME280_OversamplingX4 0x03
  15. #define BME280_OversamplingX8 0x04
  16. #define BME280_OversamplingX16 0x05
  17. #define BME280_Sleep_Mode 0x00
  18. #define BME280_Forced_Mode 0x01
  19. #define BME280_Normal_Mode 0x03
  20. #define BME280_TStandBy_1000Ms 0x05
  21. #define BME280_Filter_off 0x00
  22. #define BME280_Spi3W_en 0x00
  1. void BME280_Init(void)//BME280初始化
  2. {
  3. //IIC初始化
  4. gpio_init(GPIOB,GPIO_Pin_6,GPO_P,1);//PB6推挽输出——SDA
  5. gpio_init(GPIOB,GPIO_Pin_7,GPO_P,1);//PB7推挽输出——SCL
  6. delay_ms(20);
  7. //检测芯片ID
  8. bme280ID = IIC_Read_Reg(BME280_ADDRESS,BME280_CHIP_ID);
  9. while(bme280ID != BME280_DEFAULT_CHIP_ID);
  10. IIC_Write_Reg(BME280_ADDRESS,BME280_Ctrl_Hum,BME280_Humidity_OSR);
  11. IIC_Write_Reg(BME280_ADDRESS,BME280_Ctrl_Meas,BME280_Ctrl_Meas_MODE);
  12. IIC_Write_Reg(BME280_ADDRESS,BME280_Config,BME280_Config_MODE);
  13. //校准数据
  14. trimming_values();
  15. }

读取 Trimming data:

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

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

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

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

  1. //读取数值
  2. void BME280_GetData(float *pressure,float *temperature,float *humility)
  3. {
  4. u8 data[8];
  5. u32 press_t,temp_t,hum_t;
  6. //校正
  7. signed long int temp_cal;
  8. unsigned long int press_cal,hum_cal;
  9. IIC_Read_Buff(BME280_ADDRESS,0xF7,8,&data[0]);
  10. press_t = (data[0]<<12)|(data[1]<<4)|(data[2]>>4);
  11. temp_t = (data[3]<<12)|(data[4]<<4)|(data[5]>>4);
  12. hum_t = (data[6]<<8)|data[7];
  13. temp_cal = (double)calibration_T(temp_t) / 100.0;
  14. press_cal = (double)calibration_P(press_t) / 25600.0;
  15. hum_cal = (double)calibration_H(hum_t) / 1024.0;
  16. *temperature = temp_cal;
  17. *pressure = press_cal;
  18. *humility = hum_cal;
  19. }

数值校正函数:

  1. //返回温度值,单位为度degree,输出值若为“5123”等价于51.23度
  2. signed long int calibration_T(signed long int adc_T)
  3. {
  4. signed long int var1, var2, T;
  5. var1 = ((((adc_T >> 3) - ((signed long int)dig_T1<<1))) * ((signed long int)dig_T2)) >> 11;
  6. var2 = (((((adc_T >> 4) - ((signed long int)dig_T1)) * ((adc_T>>4) - ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14;
  7. t_fine = var1 + var2;
  8. T = (t_fine * 5 + 128) >> 8;
  9. return T;
  10. }
  1. //返回大气压值,单位为Pa
  2. //输出值若为“24674867” 等于 24674867/256 = 96386.2Pa = 963862hPa
  3. unsigned long int calibration_P(signed long int adc_P)
  4. {
  5. int64_t var1, var2,P;
  6. var1 = ((int64_t)t_fine) - 128000;
  7. var2 = var1 * var1 * (int64_t)dig_P6;
  8. var2 = var2 + ((var1*(int64_t)dig_P5)<<17);
  9. var2 = var2 + (((int64_t)dig_P4) <<35);
  10. var1 = ((var1 * var1 * (int64_t)dig_P3) >> 8) + ((var1 * (int64_t)dig_P2) << 12);
  11. var1 = (((((int64_t)1)<<47)+var1))*((int64_t)dig_P1)>>33;
  12. if (var1 == 0) return 0;
  13. P = 1048576-adc_P;
  14. P = (((P<<31)-var2)*3125)/var1;
  15. var1 = (((int64_t)dig_P9) * (P>>13) * (P>>13))>>25;
  16. var2 = (((int64_t)dig_P8) * P) >> 19;
  17. P = ((P + var1 + var2) >> 8) + (((int64_t)dig_P7)<<4);
  18. return (unsigned long int)P;
  19. }
  1. //输出值为"47445",代表 47445/1021 = 46.333%RH
  2. unsigned long int calibration_H(signed long int adc_H)
  3. {
  4. int64_t v_x1_u32r;
  5. v_x1_u32r=(t_fine-((int64_t)76800));
  6. 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*(
  7. (int64_t)dig_H6))>>10)*(((v_x1_u32r*((int64_t)dig_H3))>>11)+((int64_t)32768)))>>10)+((int64_t)2097152))*((int64_t)
  8. dig_H2)+8192)>>14));
  9. v_x1_u32r=(v_x1_u32r-(((((v_x1_u32r>>15)*(v_x1_u32r>>15))>>7)*((int64_t)dig_H1))>>4));
  10. v_x1_u32r=(v_x1_u32r<0?0:v_x1_u32r);
  11. v_x1_u32r=(v_x1_u32r>419430400?419430400:v_x1_u32r);
  12. return (uint32_t)(v_x1_u32r>>12);
  13. }

最终结果:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/293178
推荐阅读
相关标签
  

闽ICP备14008679号