找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2130|回复: 2
打印 上一主题 下一主题
收起左侧

STM32+BME280测量大气压强源程序

[复制链接]
跳转到指定楼层
楼主
ID:747099 发表于 2021-3-22 13:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include <math.h>
  2. #include "delay.h"
  3. #include "myiic.h"
  4. #include "stdio.h"

  5. #define BME280_ADDRESS 0XEC
  6. unsigned long int hum_raw,temp_raw,pres_raw;
  7. signed long int t_fine;

  8. static float bme280PressureToAltitude(float* pressure/*, float* groundPressure, float* groundTemp*/);
  9. void writeReg(uint8_t reg_address, uint8_t data);
  10. void readData(void);
  11. void readTrim(void);


  12. uint16_t dig_T1;
  13. int16_t dig_T2;
  14. int16_t dig_T3;
  15. uint16_t dig_P1;
  16. int16_t dig_P2;
  17. int16_t dig_P3;
  18. int16_t dig_P4;
  19. int16_t dig_P5;
  20. int16_t dig_P6;
  21. int16_t dig_P7;
  22. int16_t dig_P8;
  23. int16_t dig_P9;
  24. int8_t  dig_H1;
  25. int16_t dig_H2;
  26. int8_t  dig_H3;
  27. int16_t dig_H4;
  28. int16_t dig_H5;
  29. int8_t  dig_H6;

  30. void setup()
  31. {
  32.     uint8_t osrs_t = 1;             //Temperature oversampling x 1
  33.     uint8_t osrs_p = 1;             //Pressure oversampling x 1
  34.     uint8_t osrs_h = 1;             //Humidity oversampling x 1
  35.     uint8_t mode = 3;               //Normal mode
  36.     uint8_t t_sb = 5;               //Tstandby 1000ms
  37.     uint8_t filter = 0;             //Filter off
  38.     uint8_t spi3w_en = 0;           //3-wire SPI Disable
  39.    
  40.     uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;
  41.     uint8_t config_reg    = (t_sb << 5) | (filter << 2) | spi3w_en;
  42.     uint8_t ctrl_hum_reg  = osrs_h;
  43.    
  44.     writeReg(0xF2,ctrl_hum_reg);
  45.     writeReg(0xF4,ctrl_meas_reg);
  46.     writeReg(0xF5,config_reg);
  47.     readTrim();                    //
  48. }

  49. void readTrim(void)
  50. {
  51.     uint8_t data[32];
  52.        
  53.         iicDevRead(BME280_ADDRESS,0x88,24,&data[0]);
  54.         iicDevRead(BME280_ADDRESS,0xA1,1,&data[24]);
  55.         iicDevRead(BME280_ADDRESS,0xE1,7,&data[25]);

  56.     dig_T1 = (data[1] << 8) | data[0];
  57.     dig_T2 = (data[3] << 8) | data[2];
  58.     dig_T3 = (data[5] << 8) | data[4];
  59.     dig_P1 = (data[7] << 8) | data[6];
  60.     dig_P2 = (data[9] << 8) | data[8];
  61.     dig_P3 = (data[11]<< 8) | data[10];
  62.     dig_P4 = (data[13]<< 8) | data[12];
  63.     dig_P5 = (data[15]<< 8) | data[14];
  64.     dig_P6 = (data[17]<< 8) | data[16];
  65.     dig_P7 = (data[19]<< 8) | data[18];
  66.     dig_P8 = (data[21]<< 8) | data[20];
  67.     dig_P9 = (data[23]<< 8) | data[22];
  68.     dig_H1 = data[24];
  69.     dig_H2 = (data[26]<< 8) | data[25];
  70.     dig_H3 = data[27];
  71.     dig_H4 = (data[28]<< 4) | (0x0F & data[29]);
  72.     dig_H5 = (data[30] << 4) | ((data[29] >> 4) & 0x0F);
  73.     dig_H6 = data[31];   
  74.    
  75. }

  76. void writeReg(uint8_t reg_address, uint8_t data)
  77. {
  78.         iicDevWriteByte(BME280_ADDRESS,reg_address,data);  
  79. }


  80. void readData(void)
  81. {
  82.     u8 data[8];
  83.         iicDevRead(BME280_ADDRESS,0xF7,8,data);
  84.     pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
  85.     temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
  86.     hum_raw  = (data[6] << 8) | data[7];
  87. }


  88. signed long int calibration_T(signed long int adc_T)
  89. {
  90.    
  91.     signed long int var1, var2, T;
  92.     var1 = ((((adc_T >> 3) - ((signed long int)dig_T1<<1))) * ((signed long int)dig_T2)) >> 11;
  93.     var2 = (((((adc_T >> 4) - ((signed long int)dig_T1)) * ((adc_T>>4) - ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14;
  94.    
  95.     t_fine = var1 + var2;
  96.     T = (t_fine * 5 + 128) >> 8;
  97.     return T;
  98. }

  99. unsigned long int calibration_P(signed long int adc_P)
  100. {
  101.     signed long int var1, var2;
  102.     unsigned long int P;
  103.     var1 = (((signed long int)t_fine)>>1) - (signed long int)64000;
  104.     var2 = (((var1>>2) * (var1>>2)) >> 11) * ((signed long int)dig_P6);
  105.     var2 = var2 + ((var1*((signed long int)dig_P5))<<1);
  106.     var2 = (var2>>2)+(((signed long int)dig_P4)<<16);
  107.     var1 = (((dig_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((signed long int)dig_P2) * var1)>>1))>>18;
  108.     var1 = ((((32768+var1))*((signed long int)dig_P1))>>15);
  109.     if (var1 == 0)
  110.     {
  111.         return 0;
  112.     }   
  113.     P = (((unsigned long int)(((signed long int)1048576)-adc_P)-(var2>>12)))*3125;
  114.     if(P<0x80000000)
  115.     {
  116.        P = (P << 1) / ((unsigned long int) var1);   
  117.     }
  118.     else
  119.     {
  120.         P = (P / (unsigned long int)var1) * 2;   
  121.     }
  122.     var1 = (((signed long int)dig_P9) * ((signed long int)(((P>>3) * (P>>3))>>13)))>>12;
  123.     var2 = (((signed long int)(P>>2)) * ((signed long int)dig_P8))>>13;
  124.     P = (unsigned long int)((signed long int)P + ((var1 + var2 + dig_P7) >> 4));
  125.     return P;
  126. }

  127. unsigned long int calibration_H(signed long int adc_H)
  128. {
  129.     signed long int v_x1;
  130.    
  131.     v_x1 = (t_fine - ((signed long int)76800));
  132.     v_x1 = (((((adc_H << 14) -(((signed long int)dig_H4) << 20) - (((signed long int)dig_H5) * v_x1)) +
  133.               ((signed long int)16384)) >> 15) * (((((((v_x1 * ((signed long int)dig_H6)) >> 10) *
  134.               (((v_x1 * ((signed long int)dig_H3)) >> 11) + ((signed long int) 32768))) >> 10) + (( signed long int)2097152)) *
  135.               ((signed long int) dig_H2) + 8192) >> 14));
  136.    v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((signed long int)dig_H1)) >> 4));
  137.    v_x1 = (v_x1 < 0 ? 0 : v_x1);
  138.    v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);
  139.    return (unsigned long int)(v_x1 >> 12);   
  140. }

  141. void bme280Init(void)
  142. {       
  143.         IIC_Init();                                                                           /*初始化I2C*/
  144.     delay_ms(20);
  145.         setup();
  146. }

  147. void bme280GetData(float* pressure,float* temperature,float* humidity,float* asl)
  148. {
  149.     double temp_act = 0.0, press_act = 0.0,hum_act=0.0;
  150.     signed long int temp_cal;
  151.     unsigned long int press_cal,hum_cal;
  152.     readData();
  153.        
  154.     temp_cal = calibration_T(temp_raw);
  155.     press_cal = calibration_P(pres_raw);
  156.     hum_cal = calibration_H(hum_raw);
  157.     temp_act = (double)temp_cal / 100.0;
  158.     press_act = (double)press_cal / 100.0;
  159.     hum_act = (double)hum_cal / 1024.0;

  160.         printf("temp_raw:%ld\r\n",temp_raw);
  161.         printf("pres_raw:%ld\r\n",pres_raw);
  162.         printf("hum_raw:%ld\r\n",hum_raw);

  163.         *temperature=temp_act;                                                     /*单位度*/
  164.         *pressure=press_act;                                                           /*单位hPa*/       
  165.         *humidity=hum_act;
  166.         *asl=bme280PressureToAltitude(pressure);                                       /*转换成海拔*/       
  167. }

  168. #define CONST_PF 0.1902630958                                                       //(1/5.25588f) Pressure factor
  169. #define FIX_TEMP 25                                                                               // Fixed Temperature. ASL is a function of pressure and temperature, but as the temperature changes so much (blow a little towards the flie and watch it drop 5 degrees) it corrupts the ASL estimates.
  170.                                                                                                                // TLDR: Adjusting for temp changes does more harm than good.
  171. /*
  172. * Converts pressure to altitude above sea level (ASL) in meters
  173. */
  174. static float bme280PressureToAltitude(float* pressure/*, float* groundPressure, float* groundTemp*/)
  175. {
  176.     if (*pressure>0)
  177.     {
  178.         return((pow((1015.7f/ *pressure),CONST_PF)-1.0f)*(FIX_TEMP+273.15f))/0.0065f;
  179.     }
  180.     else
  181.     {
  182.         return 0;
  183.     }
  184. }
复制代码



#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "myiic.h"
#include "bme280.h"

int main(void)
{
        float bmp280_temp;
        float bmp280_press;
        float bmp280_humi;
        float high;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                            //设置中断优先级分组2
        uart_init(9600);                                                           //初始化USART
        LED_Init();                                                                //初始化LED
    IIC_Init();        
        delay_init();
        bme280Init();
    while(1)
    {
        bme280GetData(&bmp280_press,&bmp280_temp,&bmp280_humi,&high);
                delay_ms(500);
                LED0=!LED0;
                printf("bmp280_press:%.3fkPa\r\n",bmp280_press/10.0);
                delay_ms(100);
                printf("bmp280_temp:%.3fC\r\n",bmp280_temp);
                delay_ms(100);
                printf("bmp280_humidity:%.3f%%\r\n",bmp280_humi);
                delay_ms(100);
                printf("bmp280_high:%.3fm\r\n\r\n",high);
        }
}

全部资料51hei下载地址:
BME280_STM32.7z (2.28 MB, 下载次数: 76)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:442132 发表于 2022-1-17 18:47 | 只看该作者
刚好需要,借鉴一下,感谢楼主
回复

使用道具 举报

板凳
ID:921916 发表于 2022-4-15 19:57 | 只看该作者
麻烦问一下楼主,这个程序时运用串口调试吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表