
-
UID:828474
-
- 注册时间2011-04-14
- 最后登录2026-08-06
- 在线时间3775小时
-
-
访问TA的空间加好友用道具
- 发帖
- 13086
- M币
- 7080
- 专家
- 48
- 粉丝
- 10374
|
大字报:BMP280只有气压和温度测量,BME280支持气压、温度、湿度测量,淘宝买的模块都是BMP,但给的手册是BME,显示支持湿度,被坑了一波,还纳闷咋读不出来湿度。百度也是坑爹,想下个BMP的手册找半天都搞不定,博世官网也找不到,还是谷歌要脸,第一条就是官网提供的pdf。 这两天在测试stm32的硬件I2C,正好有个气压模块,接口支持I2C和SPI,就玩玩I2C。软硬件环境: Keil5,stm32f103cbt6,硬件I2C2,stm32cubemx,HAL库。相关设置: 串口1 ,波特率115200 因为主要是测试硬件I2C,所以这里就不再详细描述I2C的实现细节,直接贴代码,代码中加了不少注释,就不做过多描述了,在这里给广大如我一般的菜鸟提个建议,一定要学会看E文手册,因为光大网友贴教程贴文章时都会有意无意漏掉一些自己觉着不重要的东西,可能就是这些东西让你走向失败。 因为不打算写什么教程,所以简单扯几句完事,就当一个留档,以后再玩的时候可以直接拿来用 BMP280头文件- #ifndef __BMP280_H
- #define __BMP280_H
- #include "stm32f1xx_hal.h"
- #include "i2c.h"
- /*****************************配置区****************************/
- //I2C超时
- #define TIMEOUT 200
- #define ADDR 0xec
- //温度过采样
- #define osrs_t 1
- //湿度过采样
- #define osrs_h 1
- //压力过采样
- #define osrs_p 1
- //工作模式(1或2:被动模式,测量完毕进入休眠,需要再次测量时重新设置model=1)
- #define mode 3
- //主动模式时的转换间隔(4:0.5s)
- #define t_sb 4
- //滤波器(0:关闭)
- #define filter 0
- /*******************************配置区*****************************/
- //速率/滤波控制寄存器
- #define config t_sb<<5|filter<<2
- //测量控制寄存器
- #define ctrl_meas osrs_t<<5|osrs_p<<2|mode
- void BMP280Init(void);
- uint8_t BMP280CheckStatus(void);
- void BMP280ReadTrim(void);
- void BMP280StartMeasure(void);
- double BMP280CompensateP(int32_t adc_P);
- double BMP280ReadP(void);
- double BME280CompensateT(int32_t adc_T);
- double BMP280ReadT(void);
- double BMP280CompensateH(int32_t adc_H);
- double BMP280ReadH(void);
- #endif
BMP280 .c文件 - #include "stm32f1xx_hal.h"
- #include "i2c.h"
- #include "BMP280.h"
- 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;
- int32_t t_fine;
- void BMP280Init(void)
- {
- uint8_t tData;
- //软件复位
- tData=0xb6;
- HAL_I2C_Mem_Write(&hi2c2,ADDR,0xe0,1,&tData,1,TIMEOUT);
- HAL_Delay(50);
-
- //id校验 0x58
- //uint8_t id=0;
- //HAL_I2C_Mem_Read(&hi2c2,ADDR,0xd0,1,&id,1,TIMEOUT);
-
- if(osrs_t!=0)
- {
- tData=osrs_h;
- HAL_I2C_Mem_Write(&hi2c2,ADDR,0xf2,1,&tData,1,TIMEOUT);
- }
-
- tData=ctrl_meas;
- HAL_I2C_Mem_Write(&hi2c2,ADDR,0xf4,1,&tData,1,TIMEOUT);
-
-
- if(mode==3)
- {
- tData=config;
- HAL_I2C_Mem_Write(&hi2c2,ADDR,0xf5,1,&tData,1,TIMEOUT);
- }
- BMP280ReadTrim();
- }
- //检查设备转换状态(1:转换完毕,0:正在转换)
- uint8_t BMP280CheckStatus(void)
- {
- uint8_t rData;
- HAL_I2C_Mem_Read(&hi2c2,ADDR,0xf3,1,&rData,1,TIMEOUT);
- return (rData&0x40)?0:1;
- }
- //读取校准值
- void BMP280ReadTrim(void)
- {
- uint8_t rData[24];
- HAL_I2C_Mem_Read(&hi2c2,ADDR,0x88,1,rData,24,TIMEOUT);
- dig_T1 = (rData[1] << 8) | rData[0];
- dig_T2 = (rData[3] << 8) | rData[2];
- dig_T3 = (rData[5] << 8) | rData[4];
- dig_P1 = (rData[7] << 8) | rData[6];
- dig_P2 = (rData[9] << 8) | rData[8];
- dig_P3 = (rData[11]<< 8) | rData[10];
- dig_P4 = (rData[13]<< 8) | rData[12];
- dig_P5 = (rData[15]<< 8) | rData[14];
- dig_P6 = (rData[17]<< 8) | rData[16];
- dig_P7 = (rData[19]<< 8) | rData[18];
- dig_P8 = (rData[21]<< 8) | rData[20];
- dig_P9 = (rData[23]<< 8) | rData[22];
- HAL_I2C_Mem_Read(&hi2c2,ADDR,0xa1,1,rData,1,TIMEOUT);
- dig_H1=rData[0];
- HAL_I2C_Mem_Read(&hi2c2,ADDR,0xe1,1,rData,7,TIMEOUT);
-
- dig_H2 = (rData[1]<< 8) | rData[0];
- dig_H3 = rData[2];
- dig_H4 = (rData[4]<< 4) | (0x0F & rData[3]);
- dig_H5 = (rData[5] << 4) | ((rData[4] >> 4) & 0x0F);
- dig_H6 = rData[6];
- }
- void BMP280StartMeasure(void)
- {
- uint8_t tData;
- uint8_t rData;
- if(mode==1||mode==2)
- {
-
- if(osrs_t!=0)
- {
- HAL_I2C_Mem_Read(&hi2c2,ADDR,0xf2,1,&rData,1,TIMEOUT);
- tData=osrs_h;
- HAL_I2C_Mem_Write(&hi2c2,ADDR,0xf2,1,&tData,1,TIMEOUT);
- HAL_I2C_Mem_Read(&hi2c2,ADDR,0xf2,1,&rData,1,TIMEOUT);
- }
- tData=ctrl_meas;
- HAL_I2C_Mem_Write(&hi2c2,ADDR,0xf4,1,&tData,1,TIMEOUT);
-
- }
- }
- //气压计算
- double BMP280CompensateP(int32_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;
- }
- //气压读取
- double BMP280ReadP(void)
- {
- int32_t temp;
- uint8_t rData[3];
- while(!BMP280CheckStatus());
- HAL_I2C_Mem_Read(&hi2c2,ADDR,0xf7,1,rData,3,TIMEOUT);
-
- temp=(rData[0] << 12) | (rData[1] << 4) | (rData[2] >> 4);
- return BMP280CompensateP(temp);
- }
- //温度计算
- double BME280CompensateT(int32_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 = (int32_t)(var1 + var2);
- T = (var1 + var2) / 5120.0;
- return T;
- }
- //温度读取
- double BMP280ReadT(void)
- {
- int32_t temp;
- uint8_t rData[3];
- while(!BMP280CheckStatus());
- HAL_I2C_Mem_Read(&hi2c2,ADDR,0xfa,1,rData,3,TIMEOUT);
-
- temp=(rData[0] << 12) | (rData[1] << 4) | (rData[2] >> 4);
- return BME280CompensateT(temp);
- }
- //湿度计算
- double BMP280CompensateH(int32_t adc_H)
- {
- double var_H;
- var_H = (((double)t_fine) - 76800.0);
- var_H = (adc_H - (((double)dig_H4) * 64.0 + ((double)dig_H5) / 16384.0 * var_H)) *
- (((double)dig_H2) / 65536.0 * (1.0 + ((double)dig_H6) / 67108864.0 * var_H *
- (1.0 + ((double)dig_H3) / 67108864.0 * var_H)));
- var_H = var_H * (1.0 - ((double)dig_H1) * var_H / 524288.0);
- if (var_H > 100.0)
- var_H = 100.0;
- else if (var_H < 0.0)
- var_H = 0.0;
- return var_H;
- }
- //湿度读取
- double BMP280ReadH(void)
- {
- int32_t temp;
- uint8_t rData[2];
- while(!BMP280CheckStatus());
- HAL_I2C_Mem_Read(&hi2c2,ADDR,0xfd,1,rData,2,TIMEOUT);
-
- temp=(rData[0] << 8) |rData[1];
- return BMP280CompensateH(temp);
- }
使用方法:先调用BMP280Init() 初始化,会设置相关寄存器.每次使用结果前调用BMP280StartMeasure()执行一次测量任务(被动模式每次测量都要调用一下,主动模式会定时自动测量,不过函数有判断,直接调用就好)BMP280ReadP()//读取并计算气压值BMP280ReadT()//读取并计算温度值 BMP280ReadH()//读取并计算湿度值,BME280有效,BMP280无湿度测量功能。
|