一、前言
BMP280 是一款由 Bosch Sensortec 生产的小型、高精度的气压和温度传感器,广泛应用于环境监测、天气预报、室内外导航、无人机飞行控制、物联网设备等领域。它是继 BMP180 和 BMP183 之后的下一代气压传感器,性能更高,功耗更低。
二、简介
主要特性
- 气压传感器:
- 测量范围:300 至 1100 hPa(百帕,单位用于衡量气压的标准单位)。
- 分辨率:最小可达 1 Pa(帕斯卡)。
- 精度:±1 hPa(气压精度)。
- 适合用于气压计、气象站和高度计等设备中。
- 温度传感器:
- 测量范围:-40°C 至 +85°C。
- 精度:±1.0°C。
- 适合环境监测、气象研究以及设备温度控制。
- 低功耗设计:
- I2C 和 SPI 接口:
- 校准数据:
- 传感器出厂时会进行内部校准,确保高精度测量。
- 提供温度和气压的校准系数,用于后期数据的补偿计算。
- 小型封装:
- 封装尺寸小,通常为 3.6 mm x 3.8 mm,非常适合空间受限的应用。
- 低重量,适合嵌入到便携设备中。
三、资料获取
关注微信公众号--星之援工作室 发送关键字(BMP280)
代码含重要注释,开源,可自行移植
➡️➡️
四、设备使用
实现效果
连接好线 打开串口工具 即可输出获取的数据
接线
连线
VCC - 3.3
GND - GND
SCL - PB6
SAD - PB7
四、代码编写
main.c
实现函数调用
/*--------------------------------------------------------*
* *
* 星之援网络科技工作室学习资料v1.0 *
* 时间:2024.11.14 *
* 程序介绍:按键实验 *
* 实现效果:BMP280大气压强读取 *
* *
*--------------------------------------------------------*
连线
VCC - 3.3
GND - GND
SCL - PB6
SAD - PB7
*/
#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "usart.h"
#include "bmp280.h"
int main(void)
{
float bmp280_temp;
float bmp280_press;
float bmp280_humi;
float high;
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
// LED 端口初始化
LED_GPIO_Config();
// 串口初始化
uart_init(115200);
// 初始化模拟 I2C 和 BMP280
IIC_Init();
bme280Init();
printf("init okn");
while(1)
{
bme280GetData(&bmp280_press,&bmp280_temp,&high);
// 处理数据,比如通过UART发送
// 在这里可以使用 UART 输出温度和气压,或者进行其他操作
printf("bmp280_press: %.2f hParn",bmp280_press);
delay_ms(100);
printf("bmp280_temp: %.2f Crn",bmp280_temp);
delay_ms(100);
printf("bmp280_high : %.2f Mrnrn",high);
// 等待1s
delay_ms(1000);
}
}
bmp280.c
实现IIC配置和读取 ,实现BMP280读取
#include "bmp280.h"
#include "delay.h"
#include "math.h"
#include "usart.h"
#include "stdio.h"
unsigned long int hum_raw, temp_raw, pres_raw;
signed long int t_fine;
// 预定义函数原型
static float bme280PressureToAltitude(float* pressure/*, float* groundPressure, float* groundTemp*/);
void writeReg(uint8_t reg_address, uint8_t data);
void readData(void);
void readTrim(void);
// 传感器的校准系数
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;
// 初始化设置BME280传感器
void setup()
{
uint8_t osrs_t = 1; // 温度超采样 x 1
uint8_t osrs_p = 1; // 气压超采样 x 1
uint8_t osrs_h = 1; // 湿度超采样 x 1
uint8_t mode = 3; // 正常模式
uint8_t t_sb = 5; // 温度待机时间 1000ms
uint8_t filter = 0; // 关闭滤波器
uint8_t spi3w_en = 0; // 3线SPI禁用
// 控制测量寄存器和配置寄存器的值设置
uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;
uint8_t config_reg = (t_sb << 5) | (filter << 2) | spi3w_en;
uint8_t ctrl_hum_reg = osrs_h;
// 写入寄存器
writeReg(0xF2, ctrl_hum_reg); // 湿度控制寄存器
writeReg(0xF4, ctrl_meas_reg); // 控制测量寄存器
writeReg(0xF5, config_reg); // 配置寄存器
readTrim(); // 读取校准数据
}
// 读取传感器的校准数据(从寄存器获取)
void readTrim(void)
{
uint8_t data[32];
// I2C读取传感器的校准数据
iicDevRead(BME280_ADDRESS, 0x88, 24, &data[0]);
iicDevRead(BME280_ADDRESS, 0xA1, 1, &data[24]);
iicDevRead(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) | (0x0F & data[29]);
dig_H5 = (data[30] << 4) | ((data[29] >> 4) & 0x0F);
dig_H6 = data[31];
}
// 向BME280写入一个字节数据
void writeReg(uint8_t reg_address, uint8_t data)
{
iicDevWriteByte(BME280_ADDRESS, reg_address, data);
}
// 读取BME280的原始数据
void readData(void)
{
u8 data[8];
// 从数据寄存器读取原始数据
iicDevRead(BME280_ADDRESS, 0xF7, 8, data);
pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
hum_raw = (data[6] << 8) | data[7];
}
// 温度校准函数
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;
}
// 气压校准函数
unsigned long int calibration_P(signed long int adc_P)
{
signed long int var1, var2;
unsigned long int P;
// 根据原始气压值和校准参数进行计算
var1 = (((signed long int)t_fine) >> 1) - (signed long int)64000;
var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * ((signed long int)dig_P6);
var2 = var2 + ((var1 * ((signed long int)dig_P5)) << 1);
var2 = (var2 >> 2) + (((signed long int)dig_P4) << 16);
var1 = (((dig_P3 * (((var1 >> 2) * (var1 >> 2)) >> 13)) >> 3) + ((((signed long int)dig_P2) * var1) >> 1)) >> 18;
var1 = ((((32768 + var1)) * ((signed long int)dig_P1)) >> 15);
// 避免除以零
if (var1 == 0)
{
return 0;
}
// 根据校准后的参数计算气压值
P = (((unsigned long int)(((signed long int)1048576) - adc_P) - (var2 >> 12))) * 3125;
if (P < 0x80000000)
{
P = (P << 1) / ((unsigned long int)var1);
}
else
{
P = (P / (unsigned long int)var1) * 2;
}
var1 = (((signed long int)dig_P9) * ((signed long int)(((P >> 3) * (P >> 3)) >> 13))) >> 12;
var2 = (((signed long int)(P >> 2)) * ((signed long int)dig_P8)) >> 13;
P = (unsigned long int)((signed long int)P + ((var1 + var2 + dig_P7) >> 4));
return P;
}
// 湿度校准函数
unsigned long int calibration_H(signed long int adc_H)
{
signed long int v_x1;
// 根据湿度原始数据和校准参数进行计算
v_x1 = (t_fine - ((signed long int)76800));
v_x1 = (((((adc_H << 14) - (((signed long int)dig_H4) << 20) - (((signed long int)dig_H5) * v_x1)) + ((signed long int)16384)) >> 15) *
(((((((v_x1 * ((signed long int)dig_H6)) >> 10) * (((v_x1 * ((signed long int)dig_H3)) >> 11) + ((signed long int)32768))) >> 10) + ((signed long int)2097152)) *
((signed long int)dig_H2) + 8192) >> 14));
v_x1 = v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((signed long int)dig_H1)) >> 4);
if (v_x1 < 0) v_x1 = 0;
if (v_x1 > 419430400) v_x1 = 419430400;
return (unsigned long int)(v_x1 >> 12);
}
void bme280Init(void)
{
IIC_Init(); /*初始化I2C*/
delay_ms(20);
setup();
}
void bme280GetData(float* pressure,float* temperature,float* asl)
{
double temp_act = 0.0, press_act = 0.0;
signed long int temp_cal;
unsigned long int press_cal;
readData();
temp_cal = calibration_T(temp_raw);
press_cal = calibration_P(pres_raw);
// hum_cal = calibration_H(hum_raw);
temp_act = (double)temp_cal / 100.0;
press_act = (double)press_cal / 100.0;
//hum_act = (double)hum_cal / 1024.0;
// printf("temp_raw:%ldrn",temp_raw);
// printf("pres_raw:%ldrn",pres_raw);
// printf("hum_raw:%ldrn",hum_raw);
*temperature=temp_act; /*单位度*/
*pressure=press_act; /*单位hPa*/
//*humidity=hum_act;
*asl=bme280PressureToAltitude(pressure); /*转换成海拔*/
}
/*
* Converts pressure to altitude above sea level (ASL) in meters
*/
static float bme280PressureToAltitude(float* pressure/*, float* groundPressure, float* groundTemp*/)
{
if (*pressure>0)
{
return((pow((1015.7f/ *pressure),CONST_PF)-1.0f)*(FIX_TEMP+273.15f))/0.0065f;
}
else
{
return 0;
}
}
//初始化IIC
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( SCL_GPIO_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin=SCL_GPIO_PIN|SDA_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(SCL_GPIO_PORT,&GPIO_InitStructure);
IIC_SCL=1;
IIC_SDA=1;
}
// 配置双向I/O端口为输出态
static void SDA_OUT()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(SDA_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = SDA_GPIO_PIN; // PC.10 DATA
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(SDA_GPIO_PORT, &GPIO_InitStructure); // 初始化GPIOC.10
}
// 配置双向I/O端口为输入态
static void SDA_IN()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(SDA_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = SDA_GPIO_PIN; // PC.10 DATA
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(SDA_GPIO_PORT, &GPIO_InitStructure); // 初始化GPIOC.10
}
//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0; //START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL=0; //钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void IIC_Stop(void)
{
SDA_OUT(); //sda线输出
IIC_SCL=0;
IIC_SDA=0; //STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL=1;
IIC_SDA=1; //发送I2C总线结束信号
delay_us(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0; //时钟输出0
return 0;
}
//产生ACK应答
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//不产生ACK应答
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0; //拉低时钟开始数据传输
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2); //对TEA5767这三个延时都是必须的
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN(); //SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
if (!ack)
IIC_NAck(); //发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}
//从指定地址读出一个数据
//ReadAddr:开始读数的地址
//返回值 :读到的数据
u8 iicDevReadByte(u8 devaddr,u8 addr)
{
u8 temp=0;
IIC_Start();
IIC_Send_Byte(devaddr); //发送器件写命令
IIC_Wait_Ack();
IIC_Send_Byte(addr); //发送低地址
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(devaddr|1); //发送器件读命令
IIC_Wait_Ack();
temp=IIC_Read_Byte(0);
IIC_Stop(); //产生一个停止条件
return temp;
}
//连续读多个字节
//addr:起始地址
//rbuf:读数据缓存
//len:数据长度
void iicDevRead(u8 devaddr,u8 addr,u8 len,u8 *rbuf)
{
int i=0;
IIC_Start();
IIC_Send_Byte(devaddr);
IIC_Wait_Ack();
IIC_Send_Byte(addr); //地址自增
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(devaddr|1);
IIC_Wait_Ack();
for(i=0; i<len; i++)
{
if(i==len-1)
{
rbuf[i]=IIC_Read_Byte(0); //最后一个字节不应答
}
else
rbuf[i]=IIC_Read_Byte(1);
}
IIC_Stop( );
}
void iicDevReadCal1(u8 devaddr,u8 addr,u8 len,u8 *rbuf)
{
int i=0;
IIC_Start();
IIC_Send_Byte(devaddr);
IIC_Wait_Ack();
IIC_Send_Byte(0x88); //地址自增
IIC_Wait_Ack();
len=24;
for(i=0; i<len; i++)
{
if(i==len-1)
{
rbuf[i]=IIC_Read_Byte(0); //最后一个字节不应答
}
else
rbuf[i]=IIC_Read_Byte(1);
}
IIC_Stop( );
delay_us(100);
IIC_Start();
IIC_Send_Byte(0x76);
IIC_Wait_Ack();
IIC_Send_Byte(0xA1); //地址自增
IIC_Wait_Ack();
rbuf[i++]=IIC_Read_Byte(0);
IIC_Stop( );
delay_us(100);
IIC_Start();
IIC_Send_Byte(0x76);
IIC_Wait_Ack();
IIC_Send_Byte(0xE1); //地址自增
IIC_Wait_Ack();
len=32;
for(; i<len; i++)
{
if(i==len-1)
{
rbuf[i]=IIC_Read_Byte(0); //最后一个字节不应答
}
else
rbuf[i]=IIC_Read_Byte(1);
}
IIC_Stop( );
}
//连续读多个字节
//addr:起始地址
//rbuf:读数据缓存
//len:数据长度
void iicDevReadCal(u8 devaddr,u8 addr,u8 len,bme280Calib *bme280Ctype)
{
int i=0;
u8 rbuf[32];
IIC_Start();
IIC_Send_Byte(devaddr);
IIC_Wait_Ack();
IIC_Send_Byte(0x88); //地址自增
IIC_Wait_Ack();
len=24;
for(i=0; i<len; i++)
{
if(i==len-1)
{
rbuf[i]=IIC_Read_Byte(0); //最后一个字节不应答
}
else
rbuf[i]=IIC_Read_Byte(1);
}
IIC_Stop( );
delay_us(100);
IIC_Start();
IIC_Send_Byte(devaddr);
IIC_Wait_Ack();
IIC_Send_Byte(0xA1); //地址自增
IIC_Wait_Ack();
rbuf[i++]=IIC_Read_Byte(0);
IIC_Stop( );
delay_us(100);
IIC_Start();
IIC_Send_Byte(devaddr);
IIC_Wait_Ack();
IIC_Send_Byte(0xE1); //地址自增
IIC_Wait_Ack();
len=32;
for(; i<len; i++)
{
if(i==len-1)
{
rbuf[i]=IIC_Read_Byte(0); //最后一个字节不应答
}
else
rbuf[i]=IIC_Read_Byte(1);
}
IIC_Stop( );
bme280Ctype->dig_T1=(rbuf[1] << 8) | rbuf[0];
bme280Ctype->dig_T2=(rbuf[3] << 8) | rbuf[2];
bme280Ctype->dig_T3=(rbuf[5] << 8) | rbuf[4];
bme280Ctype->dig_P1=(rbuf[7] << 8) | rbuf[6];
bme280Ctype->dig_P2=(rbuf[9] << 8) | rbuf[8];
bme280Ctype->dig_P3=(rbuf[11]<< 8) | rbuf[10];
bme280Ctype->dig_P4=(rbuf[13]<< 8) | rbuf[12];
bme280Ctype->dig_P5=(rbuf[15]<< 8) | rbuf[14];
bme280Ctype->dig_P6=(rbuf[17]<< 8) | rbuf[16];
bme280Ctype->dig_P7=(rbuf[19]<< 8) | rbuf[18];
bme280Ctype->dig_P8=(rbuf[21]<< 8) | rbuf[20];
bme280Ctype->dig_P9=(rbuf[23]<< 8) | rbuf[22];
bme280Ctype->dig_H1=rbuf[24];
bme280Ctype->dig_H2=(rbuf[26]<< 8) | rbuf[25];
bme280Ctype->dig_H3=rbuf[27];
bme280Ctype->dig_H4=(rbuf[28]<< 4) | (0x0F & rbuf[29]);
bme280Ctype->dig_H5=(rbuf[30] << 4) | ((rbuf[29] >> 4) & 0x0F);
bme280Ctype->dig_H6=rbuf[31];
}
//从指定地址写入一个数据
//WriteAddr :写入数据的目的地址
//DataToWrite:要写入的数据
void iicDevWriteByte(u8 devaddr,u8 addr,u8 data)
{
IIC_Start();
IIC_Send_Byte(devaddr); //发送器件写命令
IIC_Wait_Ack();
IIC_Send_Byte(addr); //发送低地址
IIC_Wait_Ack();
IIC_Send_Byte(data); //发送字节
IIC_Wait_Ack();
IIC_Stop(); //产生一个停止条件
}
//连续写多个字节
//addr:起始地址
//wbuf:写数据缓存
//len:数据的长度
void iicDevWrite(u8 devaddr,u8 addr,u8 len,u8 *wbuf)
{
int i=0;
IIC_Start();
IIC_Send_Byte(devaddr);
IIC_Wait_Ack();
IIC_Send_Byte(addr); //地址自增
IIC_Wait_Ack();
for(i=0; i<len; i++)
{
IIC_Send_Byte(wbuf[i]);
IIC_Wait_Ack();
}
IIC_Stop( );
}
bmp280.h
配置函数
#ifndef __BMP280_H
#define __BMP280_H
#include "stm32f10x.h"
#include "sys.h"
#include "stdbool.h"
#define SCL_GPIO_PORT GPIOB /* GPIO端口 */
#define SCL_GPIO_CLK RCC_APB2Periph_GPIOB /* GPIO端口时钟 */
#define SCL_GPIO_PIN GPIO_Pin_6 /* 连接到SCL时钟线的GPIO */
#define SDA_GPIO_PORT GPIOB /* GPIO端口 */
#define SDA_GPIO_CLK RCC_APB2Periph_GPIOB /* GPIO端口时钟 */
#define SDA_GPIO_PIN GPIO_Pin_7 /* 连接到SCL时钟线的GPIO */
//IO操作函数
#define IIC_SCL PBout(6) //SCL
#define IIC_SDA PBout(7) //SDA
#define READ_SDA PBin(7) //输入SDA
// BME280的I2C地址,通常为0xEC
#define BME280_ADDRESS 0XEC
#define BME280_ADDR (0x76)
#define BME280_DEFAULT_CHIP_ID (0x60)
#define BME280_CHIP_ID (0xD0) /* Chip ID Register */
#define BME280_RST_REG (0xE0) /* Softreset Register */
#define BME280_CTRL_HUM (0xF2) /* Ctrl Humidity Register */
#define BME280_STAT_REG (0xF3) /* Status Register */
#define BME280_CTRL_MEAS_REG (0xF4) /* Ctrl Measure Register */
#define BME280_CONFIG_REG (0xF5) /* Configuration Register */
#define BME280_PRESSURE_MSB_REG (0xF7) /* Pressure MSB Register */
#define BME280_PRESSURE_LSB_REG (0xF8) /* Pressure LSB Register */
#define BME280_PRESSURE_XLSB_REG (0xF9) /* Pressure XLSB Register */
#define BME280_TEMPERATURE_MSB_REG (0xFA) /* Temperature MSB Reg */
#define BME280_TEMPERATURE_LSB_REG (0xFB) /* Temperature MSB Reg */
#define BME280_TEMPERATURE_XLSB_REG (0xFC) /* Temperature XLSB Reg */
#define BME280_HUMIDITY_MSB_REG (0xFD) /* Humidity MSB Reg */
#define BME280_HUMIDITY_LSB_REG (0xFE) /* Humidity LSB Reg */
#define BME280_SLEEP_MODE (0x00)
#define BME280_FORCED_MODE (0x01)
#define BME280_NORMAL_MODE (0x03)
#define BME280_TEMPERATURE_CALIB_DIG_T1_LSB_REG (0x88)
#define BME280_PRESSURE_TEMPERATURE_CALIB_DATA_LENGTH (32)
#define BME280_DATA_FRAME_SIZE (8)
#define BME280_OVERSAMP_SKIPPED (0x00)
#define BME280_OVERSAMP_1X (0x01)
#define BME280_OVERSAMP_2X (0x02)
#define BME280_OVERSAMP_4X (0x03)
#define BME280_OVERSAMP_8X (0x04)
#define BME280_OVERSAMP_16X (0x05)
#define CONST_PF 0.1902630958 //(1/5.25588f) Pressure factor
#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.
typedef struct
{
u16 dig_T1; /* calibration T1 data */
s16 dig_T2; /* calibration T2 data */
s16 dig_T3; /* calibration T3 data */
u16 dig_P1; /* calibration P1 data */
s16 dig_P2; /* calibration P2 data */
s16 dig_P3; /* calibration P3 data */
s16 dig_P4; /* calibration P4 data */
s16 dig_P5; /* calibration P5 data */
s16 dig_P6; /* calibration P6 data */
s16 dig_P7; /* calibration P7 data */
s16 dig_P8; /* calibration P8 data */
s16 dig_P9; /* calibration P9 data */
u8 dig_H1; /* calibration H1 data */
s16 dig_H2; /* calibration H2 data */
u8 dig_H3; /* calibration H3 data */
s16 dig_H4; /* calibration H4 data */
s16 dig_H5; /* calibration H5 data */
u8 dig_H6; /* calibration H6 data */
s32 t_fine; /* calibration t_fine data */
} bme280Calib;
// BMP280
void bme280Init(void);
void bme280GetData(float* pressure,float* temperature,float* asl);
//IIC所有操作函数
void IIC_Init(void); //初始化IIC的IO口
void IIC_Start(void); //发送IIC开始信号
void IIC_Stop(void); //发送IIC停止信号
void IIC_Send_Byte(u8 txd); //IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack); //IIC读取一个字节
u8 IIC_Wait_Ack(void); //IIC等待ACK信号
void IIC_Ack(void); //IIC发送ACK信号
void IIC_NAck(void); //IIC不发送ACK信号
void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);
u8 iicDevReadByte(u8 devaddr,u8 addr); /*读一字节*/
void iicDevWriteByte(u8 devaddr,u8 addr,u8 data); /*写一字节*/
void iicDevRead(u8 devaddr,u8 addr,u8 len,u8 *rbuf); /*连续读取多个字节*/
void iicDevWrite(u8 devaddr,u8 addr,u8 len,u8 *wbuf); /*连续写入多个字节*/
void iicDevReadCal(u8 devaddr,u8 addr,u8 len,bme280Calib *bme280Ctype);
void iicDevReadCal1(u8 devaddr,u8 addr,u8 len,u8 *rbuf);
#endif // __BMP280_H
五、参考
STM32驱动BMP280模块https://blog.csdn.net/bdjsm_hh/article/details/107623788?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522fe7a480a09ea26ca74d82092835ed6ec%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=fe7a480a09ea26ca74d82092835ed6ec&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-107623788-null-null.142%5Ev100%5Epc_search_result_base9&utm_term=BMP280%20stm32%E9%A9%B1%E5%8A%A8&spm=1018.2226.3001.4187
联系方式 微信号:13648103287