目录
简介:
BMP388是一种数字传感器,其气压和温度测量基于已验证的传感原理。面积只有2.0×2.0 mm²,封装高度0.8毫米。低功耗低质3.4µA,可以在如手机、GPS模块或手表上加以运用
主控:STM32H7B0VBT6
平台:STM32CubeIDE
BMP388一片:
I2C配置:
如果硬件上没有上拉电阻,请打开GPIO的上拉电阻:
BMP388.c:
/********************************Copyright (c)**********************************\
**
** (c) Copyright 2023, Main, China, 被钢琴支配的悲惨大学生.
** All Rights Reserved
**
** By(被钢琴支配的悲惨大学生 personally owned)
** https://blog.csdn.net/m0_71226271?type=blog
**
**----------------------------------文件信息------------------------------------
** 文件名称: BMP388.c
** 创建人员: 被钢琴支配的悲惨大学生
** 创建日期: 2023-09-06
** 文档描述:基于STM32H7B0VBT6的HAL库BMP388驱动源码,使用硬件I2C
\********************************End of Head************************************/
#include<main.h>
#include<BMP388.h>
#include<i2c.h>
struct BMP388_Calib_Data_Strcut//BMP388修正系数结构体
{
double PAR_T[3];//3个温度修正系数
double PAR_P[11];//11个气压修正系数
};
struct BMP388_Calib_Data_Strcut BMP388_Calib_Data;
/*************************************************************************************************
* 函 数 名: BMP388_Read_Chip_ID
* 入口参数: 无
* 返回值:8位的出厂ID
* 函数功能: 读取出厂ID
* 说 明: 根据数据手册31页,应该是0x50
*************************************************************************************************/
uint8_t BMP388_Read_Chip_ID()
{
uint8_t I2C_Receive_Data[1];
HAL_I2C_Mem_Read(&hi2c1,BMP388_Address,BMP388_CHIP_ID,I2C_MEMADD_SIZE_8BIT,I2C_Receive_Data,1,HAL_MAX_DELAY);
return I2C_Receive_Data[0];
}
/*************************************************************************************************
* 函 数 名: BMP388_Start_Normal_Conversion
* 入口参数: 无
* 返回值:无
* 函数功能: 开启BMP388转换,使用Normal mode
* 说 明: 开启之后,BMP388进行连续转换
*************************************************************************************************/
void BMP388_Start_Normal_Conversion()
{
uint8_t I2C_Transmit_Data[1];
I2C_Transmit_Data[0]=0x33;
HAL_I2C_Mem_Write(&hi2c1,BMP388_Address,BMP388_PWR_CTRL,I2C_MEMADD_SIZE_8BIT,I2C_Transmit_Data,1,HAL_MAX_DELAY);
}
/*************************************************************************************************
* 函 数 名: BMP388_Set_Oversampling
* 入口参数: 无
* 返回值:无
* 函数功能: 设置重采样倍数
* 说 明: 重采样倍数的说明翻阅数据手册37页
*************************************************************************************************/
void BMP388_Set_Oversampling()
{
uint8_t I2C_Transmit_Data[1];
I2C_Transmit_Data[0]=0x12;//重采样倍数设置为4倍
HAL_I2C_Mem_Write(&hi2c1,BMP388_Address,BMP388_OSR,I2C_MEMADD_SIZE_8BIT,I2C_Transmit_Data,1,HAL_MAX_DELAY);
}
/*************************************************************************************************
* 函 数 名: BMP388_Set_Data_Rate
* 入口参数: 无
* 返回值:无
* 函数功能: 设置数据速率
* 说 明: 数据速率的说明翻阅数据手册37页
*************************************************************************************************/
void BMP388_Set_Data_Rate()
{
uint8_t I2C_Transmit_Data[1];
I2C_Transmit_Data[0]=0x02;//数据速率设置为50Hz
HAL_I2C_Mem_Write(&hi2c1,BMP388_Address,BMP388_ODR,I2C_MEMADD_SIZE_8BIT,I2C_Transmit_Data,1,HAL_MAX_DELAY);
}
/*************************************************************************************************
* 函 数 名: BMP388_Set_IIR_Filter
* 入口参数: 无
* 返回值:无
* 函数功能: 设置滤波器参数
* 说 明: 数据速率的说明翻阅数据手册39页
*************************************************************************************************/
void BMP388_Set_IIR_Filter()
{
uint8_t I2C_Transmit_Data[1];
I2C_Transmit_Data[0]=0X0E;//滤波器参数设置为127
HAL_I2C_Mem_Write(&hi2c1,BMP388_Address,BMP388_CONFIG,I2C_MEMADD_SIZE_8BIT,I2C_Transmit_Data,1,HAL_MAX_DELAY);
}
/*************************************************************************************************
* 函 数 名: BMP388_Softreset
* 入口参数: 无
* 返回值:无
* 函数功能: 软件复位
* 说 明: 无
*************************************************************************************************/
void BMP388_Softreset()
{
uint8_t I2C_Transmit_Data[1];
I2C_Transmit_Data[0]=0XB6;
HAL_I2C_Mem_Write(&hi2c1,BMP388_Address,BMP388_CMD,I2C_MEMADD_SIZE_8BIT,I2C_Transmit_Data,1,HAL_MAX_DELAY);
}
/*************************************************************************************************
* 函 数 名: BMP388_Get_Compensation
* 入口参数: 无
* 返回值:无
* 函数功能: 获取BMP388的修正系数存入BMP388修正系数结构体
* 说 明: 计算方式见数据手册55页
*************************************************************************************************/
void BMP388_Get_Compensation()
{
uint8_t I2C_Receive_Data[21];
HAL_I2C_Mem_Read(&hi2c1,BMP388_Address,BMP388_TRIMMING,I2C_MEMADD_SIZE_8BIT,I2C_Receive_Data,21,HAL_MAX_DELAY);//读取21个修正系数寄存器的值
BMP388_Calib_Data.PAR_T[0]=((I2C_Receive_Data[1]<<8)|I2C_Receive_Data[0])/pow(2,-8);
BMP388_Calib_Data.PAR_T[1]=((I2C_Receive_Data[3]<<8)|I2C_Receive_Data[2])/pow(2,30);
BMP388_Calib_Data.PAR_T[2]=(int8_t)I2C_Receive_Data[4]/pow(2,48);//计算3个温度修正系数
BMP388_Calib_Data.PAR_P[0]=(((int16_t)((I2C_Receive_Data[6]<<8)|I2C_Receive_Data[5]))-pow(2,14))/pow(2,20);
BMP388_Calib_Data.PAR_P[1]=(((int16_t)((I2C_Receive_Data[8]<<8)|I2C_Receive_Data[7]))-pow(2,14))/pow(2,29);
BMP388_Calib_Data.PAR_P[2]=(int8_t)I2C_Receive_Data[9]/pow(2,32);
BMP388_Calib_Data.PAR_P[3]=(int8_t)I2C_Receive_Data[10]/pow(2,37);
BMP388_Calib_Data.PAR_P[4]=((I2C_Receive_Data[12]<<8)|I2C_Receive_Data[11])/pow(2,-3);
BMP388_Calib_Data.PAR_P[5]=((I2C_Receive_Data[14]<<8)|I2C_Receive_Data[13])/pow(2,6);
BMP388_Calib_Data.PAR_P[6]=(int8_t)I2C_Receive_Data[15]/pow(2,8);
BMP388_Calib_Data.PAR_P[7]=(int8_t)I2C_Receive_Data[16]/pow(2,15);
BMP388_Calib_Data.PAR_P[8]=(int16_t)((I2C_Receive_Data[18]<<8)|I2C_Receive_Data[17])/pow(2,48);
BMP388_Calib_Data.PAR_P[9]=(int8_t)I2C_Receive_Data[19]/pow(2,48);
BMP388_Calib_Data.PAR_P[10]=(int8_t)I2C_Receive_Data[20]/pow(2,65);//计算11个温度修正系数
}
/*************************************************************************************************
* 函 数 名: BMP388_Config_Init
* 入口参数: 无
* 返回值:无
* 函数功能: BMP388配置初始化,并获取修正系数
* 说 明: 无
*************************************************************************************************/
void BMP388_Config_Init()
{
BMP388_Set_Oversampling();//设置重采样倍数:4倍
BMP388_Set_IIR_Filter();//设置滤波器系数:127
BMP388_Set_Data_Rate();//设置数据速率:50Hz
BMP388_Start_Normal_Conversion();//设置转换模式:Normal Mode
BMP388_Get_Compensation();//获取修正系数
}
/*************************************************************************************************
* 函 数 名: BMP388_Waiting_For_Conversion_OK
* 入口参数: 无
* 返回值:无
* 函数功能: 以阻塞方式等待转换完成
* 说 明: 无
*************************************************************************************************/
void BMP388_Waiting_For_Conversion_OK()
{
uint8_t I2C_Receive_Data[1];
HAL_I2C_Mem_Read(&hi2c1,BMP388_Address,BMP388_STATUS,I2C_MEMADD_SIZE_8BIT,I2C_Receive_Data,1,HAL_MAX_DELAY);//读取转换状态寄存器
while(1)
{
uint8_t Temperature_Status=(I2C_Receive_Data[0]&0x40)>>6;//转换状态寄存器的第6位为1代表温度转换完成
uint8_t Pressure_Status=(I2C_Receive_Data[0]&0x20)>>5;//转换状态寄存器的第5位为1代表气压转换完成
if(Temperature_Status&&Pressure_Status)
{
break;
}
}
}
/*************************************************************************************************
* 函 数 名: BMP388_Read_Pressure_Temperature
* 入口参数: Pressure气压指针,Temperature温度指针
* 返回值:无
* 函数功能: 读取原始的气压温度数据,并修正。
* 说 明: 无
*************************************************************************************************/
void BMP388_Read_Pressure_Temperature(double *Pressure,double *Temperature)
{
uint8_t I2C_Receive_Data[6];
BMP388_Waiting_For_Conversion_OK();//等待温度气压转换完成
HAL_I2C_Mem_Read(&hi2c1,BMP388_Address,BMP388_DATA_0,I2C_MEMADD_SIZE_8BIT,I2C_Receive_Data,6,HAL_MAX_DELAY);//读取原始温度气压数据
uint32_t Pressure_Integer=(I2C_Receive_Data[2]<<16)|(I2C_Receive_Data[1]<<8)|I2C_Receive_Data[0];
uint32_t Temperature_Integer=(I2C_Receive_Data[5]<<16)|(I2C_Receive_Data[4]<<8)|I2C_Receive_Data[3];//转化为24位温度气压数据
/*******根据温度气压修正数据开始修正******/
double T_partial_data1=(double)(Temperature_Integer-BMP388_Calib_Data.PAR_T[0]);
double T_partial_data2=T_partial_data1*BMP388_Calib_Data.PAR_T[1];
*Temperature=T_partial_data2+T_partial_data1*T_partial_data1*BMP388_Calib_Data.PAR_T[2];//温度修正
double P_partial_data1=BMP388_Calib_Data.PAR_P[5]*(*Temperature);
double P_partial_data2=BMP388_Calib_Data.PAR_P[6]*(*Temperature)*(*Temperature);
double P_partial_data3=BMP388_Calib_Data.PAR_P[7]*(*Temperature)*(*Temperature)*(*Temperature);
double P_partial_out1=BMP388_Calib_Data.PAR_P[4]+P_partial_data1+P_partial_data2+P_partial_data3;
P_partial_data1=BMP388_Calib_Data.PAR_P[1]*(*Temperature);
P_partial_data2=BMP388_Calib_Data.PAR_P[2]*(*Temperature)*(*Temperature);
P_partial_data3=BMP388_Calib_Data.PAR_P[3]*(*Temperature)*(*Temperature)*(*Temperature);
double P_partial_out2=(double)(Pressure_Integer)*(BMP388_Calib_Data.PAR_P[0]+P_partial_data1+P_partial_data2+P_partial_data3);
P_partial_data1=(double)(Pressure_Integer)*(double)(Pressure_Integer);
P_partial_data2=BMP388_Calib_Data.PAR_P[8]+BMP388_Calib_Data.PAR_P[9]*(*Temperature);
P_partial_data3=P_partial_data1*P_partial_data2;
double P_partial_data4=P_partial_data3+(double)(Pressure_Integer)*(double)(Pressure_Integer)*(double)(Pressure_Integer)*BMP388_Calib_Data.PAR_P[10];
*Pressure=P_partial_out1+P_partial_out2+P_partial_data4;//气压修正
}
BMP388.h:
/********************************Copyright (c)**********************************\
**
** (c) Copyright 2023, Main, China, 被钢琴支配的悲惨大学生.
** All Rights Reserved
**
** By(被钢琴支配的悲惨大学生 personally owned)
** https://blog.csdn.net/m0_71226271?type=blog
**
**----------------------------------文件信息------------------------------------
** 文件名称: BMP388.h
** 创建人员: 被钢琴支配的悲惨大学生
** 创建日期: 2023-09-06
** 文档描述:基于STM32H7B0VBT6的HAL库BMP388驱动源码,使用硬件I2C
\********************************End of Head************************************/
#include<main.h>
#define BMP388_Address (0x76<<1) //BMP388器件地址
/*************************寄存器地址*****************************/
#define BMP388_CHIP_ID 0x00 //出厂ID寄存器地址
#define BMP388_STATUS 0X03 //转换状态寄存器地址
#define BMP388_DATA_0 0X04 //转换数据寄存器地址
#define BMP388_PWR_CTRL 0X1B //转换模式寄存器地址
#define BMP388_OSR 0X1C //重采样倍数寄存器地址
#define BMP388_ODR 0X1D //数据速率寄存器地址
#define BMP388_CONFIG 0X1F //滤波器寄存器地址
#define BMP388_TRIMMING 0X31 //修正系数寄存器地址
#define BMP388_CMD 0X7E //命令寄存器地址
/*************************API*****************************/
uint8_t BMP388_Read_Chip_ID();
void BMP388_Start_Normal_Conversion(void);
void BMP388_Set_Oversampling(void);
void BMP388_Set_Data_Rate(void);
void BMP388_Set_IIR_Filter(void);
void BMP388_Config_Init(void);
void BMP388_Get_Compensation(void);
void BMP388_Waiting_For_Conversion_OK(void);
void BMP388_Read_Pressure_Temperature(double *Pressure,double *Temperature);
测试结果:
题外话:不同于一般的传感器,BMP388出厂的时候会写入一系列修正系数,这些系数独一无二,与BMP388绑定,不同批次的片子系数不同,读取到的寄存器内部的数据只是原始数据,必须经过数据修正才能最终得出气压和温度,因此可以把精度和稳定性做得很高。