BMP390高精度压力传感器数据读取与处理(基于STM32)

        BMP390是BOSCH公司的一款高精度压力传感器(参考网址:https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/pressure-sensors-bmp390.html),其主要参数如下图所示,通信方式为I2C与SPI方式,最大供电电压为3.6V,相对精度为±3Pa(700hPa~1100hPa),绝对精度为±50Pa(300hPa~1100hPa)

         我们主要通过I2C进行通信,其硬件参考电路如下图所示,其中R1,R2为上拉电阻,阻值为4.7kΩ,C1,C2为旁路电容,容值为100 nF,CSB引脚拉高,SDO引脚为从机地址的选取引脚,接地时地址为0x76(01110110),当接高时地址为0x77(01110111)

        I2C的通信方式,大家可以自行查阅,或者参考我以前的博客SPL06的底层代码,https://blog.csdn.net/qq_40598185/article/details/119347845。大同小异。为了大家方便复制,这里给出I2C的底层驱动代码,使用的是正点原子的底层驱动代码。(myiic.c)

#include "myiic.h"
#include "delay.h"
 
//初始化I2C
void IIC_Init(void)
{					     
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_15); 	//SET the Pins to high level
}
//产生I2C起始信号(即START信号)
void IIC_Start(void)
{
	SDA_OUT();   
	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停止信号(即STOP信号)
void IIC_Stop(void)
{
	SDA_OUT();
	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;
	delay_us(4);							   	
}
//等待应答信号
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	SDA_IN();      
	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;	   
	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;
}					 				     
//I2C发送一个字节
//返回从机有无应答
//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);
			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();
    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();
	else
			IIC_Ack();  
	return receive;
}

        其头文件如下(myiic.h):


#ifndef __MYIIC_H
#define __MYIIC_H
#include "sys.h"
 
//IO方向设置
 
#define SDA_IN()  {GPIOB->CRH&=0X0FFFFFFF;GPIOB->CRH|=(u32)8<<28;}
#define SDA_OUT() {GPIOB->CRH&=0X0FFFFFFF;GPIOB->CRH|=(u32)3<<28;}
 
//IO口操作函数	 
#define IIC_SCL    PBout(13) //SCL
#define IIC_SDA    PBout(15) //输出SDA	 
#define READ_SDA   PBin(15)  //输入SDA 
 
//I2C所有操作函数
void IIC_Init(void);                //初始化I2C的IO口				 
void IIC_Start(void);				//发送IIC开始信号
void IIC_Stop(void);	  			//发送IIC停止信号
void IIC_Send_Byte(u8 txd);			//I2C发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//I2C读取一个字节
u8 IIC_Wait_Ack(void); 				//I2C等待ACK信号
void IIC_Ack(void);					//I2C发送ACK信号
void IIC_NAck(void);				//I2C不发送ACK信号
 
void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);	  
#endif

         寄存器地址分布如下图所示,由于我们没有用到FIFO,所以关于FIFO的寄存器配置都不需要关注(只列出我们需要关注的寄存器)。

        寄存器的配置如下所示,相关寄存器的详细说明请查看手册,这里压强测量使用的是最高精度测量,没有使用IIR滤波器。

u8 BMP390_Init(void)
{
	u8 BMP390_ID;
	BMP390_Write_Byte(CMD_Addr,0xB6);//RESET
	delay_ms(100);
	BMP390_ID = BMP390_Read_Byte(CHIP_ID_Addr);//Read the CHIP_ID-0x60
	BMP390_Write_Byte(PWR_CTRL_Addr,0x33);//Set Working mode and state of sensor
	BMP390_Write_Byte(IF_CONF_Addr,0x00);//Serial interface settings
	BMP390_Write_Byte(INT_CTRL_Addr,0x02);//Set interrupt config
	BMP390_Write_Byte(OSR_Addr,0x15);//Set the PM-RATE and PM-PRC,Set the TMPI-RATE and TMP-PRC
	BMP390_Write_Byte(ODR_Addr,0x04);//Set the configuration of the output data rates by means of setting the subdivision/subsampling.
	BMP390_Write_Byte(CONFIG_Addr,0x00);//IIR filter coeffcients
	return BMP390_ID;
}

         同样的,BMP390有校正参数需要读取与相应的计算,BMP390的校准参数表如下所示,最后标注出了是否有符号以及校准参数相应的位数。一共有11个压强校准参数与3个温度校准参数。

       在参数读取之后,需要对其进行一定的处理,处理方法如下图所示:

          其最后的参数计算如下图所示(温度计算流程):

   其最后的参数计算如下图所示(压强计算流程):

         最后BMP390的相关程序如下所示(BMP390.c):

#include "BMP390.h"

void BMP390_Write_Byte(u8 addr,u8 data)
{
  IIC_Start();
	IIC_Send_Byte(BMP390_Write);
	IIC_Wait_Ack();
	IIC_Send_Byte(addr);
	IIC_Wait_Ack();
	IIC_Send_Byte(data);
	IIC_Wait_Ack();
	IIC_Stop();
}

u8 BMP390_Read_Byte(u8 addr)
{
	u8 BMP390_Data;
	
	IIC_Start();
	IIC_Send_Byte(BMP390_Write);
	IIC_Wait_Ack();
	IIC_Send_Byte(addr);
	IIC_Wait_Ack();

	IIC_Start();// start again
	IIC_Send_Byte(BMP390_Read);
	IIC_Wait_Ack();
	BMP390_Data = IIC_Read_Byte(0);
	IIC_Stop();
	return BMP390_Data;
}
u8 BMP390_Init(void)
{
	u8 BMP390_ID;
	BMP390_Write_Byte(CMD_Addr,0xB6);//RESET
	delay_ms(100);
	BMP390_ID = BMP390_Read_Byte(CHIP_ID_Addr);//Read the CHIP_ID-0x60
	BMP390_Write_Byte(PWR_CTRL_Addr,0x33);//Set Working mode and state of sensor
	BMP390_Write_Byte(IF_CONF_Addr,0x00);//Serial interface settings
	BMP390_Write_Byte(INT_CTRL_Addr,0x02);//Set interrupt config
	BMP390_Write_Byte(OSR_Addr,0x15);//Set the PM-RATE and PM-PRC,Set the TMPI-RATE and TMP-PRC
	BMP390_Write_Byte(ODR_Addr,0x04);//Set the configuration of the output data rates by means of setting the subdivision/subsampling.
	BMP390_Write_Byte(CONFIG_Addr,0x00);//IIR filter coeffcients
	return BMP390_ID;
}

u32 Temperature_Read(void)
{
	u8 Temp_MSB,Temp_CSB,Temp_LSB;
	u32 Temperature;
	Temp_MSB = BMP390_Read_Byte(TMP_B2_Addr);
	Temp_CSB = BMP390_Read_Byte(TMP_B1_Addr);
	Temp_LSB = BMP390_Read_Byte(TMP_B0_Addr);
    Temperature = (Temp_MSB<<16)+(Temp_CSB<<8)+Temp_LSB;
	return Temperature;
}

u32 Pressure_Read(void)
{
	u8 Pressure_MSB,Pressure_CSB,Pressure_LSB;
	u32 Pressure;
    Pressure_MSB = BMP390_Read_Byte(PSR_B2_Addr);
	Pressure_CSB = BMP390_Read_Byte(PSR_B1_Addr);
	Pressure_LSB = BMP390_Read_Byte(PSR_B0_Addr);
	Pressure = (Pressure_MSB<<16)+(Pressure_CSB<<8)+Pressure_LSB;
	return Pressure;
}

void Parameter_Reading(int *Pressure_Para,int *Temperature_Para)
{
	u8 Temp_Config0,Temp_Config1,Temp_Config2,Temp_Config3,Temp_Config4;
	u8 Press_Config0,Press_Config1,Press_Config2,Press_Config3,Press_Config4;
	u8 Press_Config5,Press_Config6,Press_Config7,Press_Config8,Press_Config9;
	u8 Press_Config10,Press_Config11,Press_Config12,Press_Config13,Press_Config14;
  u8 Press_Config15;	
	//Temperature coefficients
	Temp_Config0 = BMP390_Read_Byte(NVM_PAR_T1_L_Addr);
	Temp_Config1 = BMP390_Read_Byte(NVM_PAR_T1_H_Addr);
	Temp_Config2 = BMP390_Read_Byte(NVM_PAR_T2_L_Addr);
	Temp_Config3 = BMP390_Read_Byte(NVM_PAR_T2_H_Addr);
	Temp_Config4 = BMP390_Read_Byte(NVM_PAR_T3_Addr);
	Temperature_Para[0] = (Temp_Config1<<8)+Temp_Config0;//T1
	Temperature_Para[1] = (Temp_Config3<<8)+Temp_Config2;//T2
	Temperature_Para[2] = Temp_Config4;//T3
	if(Temperature_Para[2]&0x80) Temperature_Para[2] = Temperature_Para[2]-Total_Number_8;
	//Pressure coefficients
	Press_Config0 = BMP390_Read_Byte(NVM_PAR_P1_L_Addr);
	Press_Config1 = BMP390_Read_Byte(NVM_PAR_P1_H_Addr);
	Press_Config2 = BMP390_Read_Byte(NVM_PAR_P2_L_Addr);
	Press_Config3 = BMP390_Read_Byte(NVM_PAR_P2_H_Addr);
	Press_Config4 = BMP390_Read_Byte(NVM_PAR_P3_Addr);
	Press_Config5 = BMP390_Read_Byte(NVM_PAR_P4_Addr);
	Press_Config6 = BMP390_Read_Byte(NVM_PAR_P5_L_Addr);
	Press_Config7 = BMP390_Read_Byte(NVM_PAR_P5_H_Addr);
	Press_Config8 = BMP390_Read_Byte(NVM_PAR_P6_L_Addr);
	Press_Config9 = BMP390_Read_Byte(NVM_PAR_P6_H_Addr);
	Press_Config10 = BMP390_Read_Byte(NVM_PAR_P7_Addr);
	Press_Config11 = BMP390_Read_Byte(NVM_PAR_P8_Addr);
	Press_Config12 = BMP390_Read_Byte(NVM_PAR_P9_L_Addr);
	Press_Config13 = BMP390_Read_Byte(NVM_PAR_P9_H_Addr);
	Press_Config14 = BMP390_Read_Byte(NVM_PAR_P10_Addr);
	Press_Config15 = BMP390_Read_Byte(NVM_PAR_P11_Addr);
	//Coefficient P1
	Pressure_Para[0] = (Press_Config1<<8)+Press_Config0;//P1
	if(Pressure_Para[0]&0x8000) Pressure_Para[0] = Pressure_Para[0] - Total_Number_16;//P1
	//Coefficient P2
	Pressure_Para[1] = (Press_Config3<<8)+Press_Config2;//P2
	if(Pressure_Para[1]&0x8000) Pressure_Para[1] = Pressure_Para[1] - Total_Number_16;//P2
	//Coefficient P3
	Pressure_Para[2] = Press_Config4;//P3
	if(Pressure_Para[2]&0x80) Pressure_Para[2] = Pressure_Para[2] - Total_Number_8;//P3
	//Coefficient P4
	Pressure_Para[3] = Press_Config5;//P4
	if(Pressure_Para[3]&0x80) Pressure_Para[3] = Pressure_Para[3] - Total_Number_8;//P4
	//Coefficient P5
	Pressure_Para[4] = (Press_Config7<<8)+Press_Config6;//P5
	//Coefficient P6
	Pressure_Para[5] = (Press_Config9<<8)+Press_Config8;//P6
	//Coefficient P7
	Pressure_Para[6] = Press_Config10;//P7
	if(Pressure_Para[6]&0x80) Pressure_Para[6] = Pressure_Para[6] - Total_Number_8;//P7
	//Coefficient P8
	Pressure_Para[7] = Press_Config11;//P8
	if(Pressure_Para[7]&0x80) Pressure_Para[7] = Pressure_Para[7] - Total_Number_8;//P8
	//Coefficient P9
	Pressure_Para[8] = (Press_Config13<<8)+Press_Config12;//P9
	if(Pressure_Para[8]&0x8000) Pressure_Para[8] = Pressure_Para[8] - Total_Number_16;//P9
	//Coefficient P10
	Pressure_Para[9] = Press_Config14;//P10
	if(Pressure_Para[9]&0x80) Pressure_Para[9] = Pressure_Para[9] - Total_Number_8;//P10
	//Coefficient P11
	Pressure_Para[10] = Press_Config15;//P11
	if(Pressure_Para[10]&0x80) Pressure_Para[10] = Pressure_Para[10] - Total_Number_8;//P11
}
double Correcting_Pressure(u32 Pressure,int *Pressure_Para,double Corr_Temperature)
{
	  double PAR_P1,PAR_P2,PAR_P3,PAR_P4,PAR_P5;
	  double PAR_P6,PAR_P7,PAR_P8,PAR_P9,PAR_P10,PAR_P11;
	  double Corr_Pressure,partial_data1,partial_data2,partial_data3,partial_data4;
	  double partial_out1,partial_out2;
	  PAR_P1 = (Pressure_Para[0]-Total_Number_14)/Total_Number_20;
	  PAR_P2 = (Pressure_Para[1]-Total_Number_14)/Total_Number_29;
	  PAR_P3 = Pressure_Para[2]/Total_Number_32;
	  PAR_P4 = Pressure_Para[3]/Total_Number_32/Total_Number_5;
	  PAR_P5 = Pressure_Para[4]/Total_Number_Neg_3;
	  PAR_P6 = Pressure_Para[5]/Total_Number_6;
	  PAR_P7 = Pressure_Para[6]/Total_Number_8;
	  PAR_P8 = Pressure_Para[7]/Total_Number_15;
	  PAR_P9 =  Pressure_Para[8]/Total_Number_32/Total_Number_16;
	  PAR_P10 =  Pressure_Para[9]/Total_Number_32/Total_Number_16;
	  PAR_P11 =  Pressure_Para[10]/Total_Number_32/Total_Number_32/Total_Number_1;
	  //Calculation
	  partial_data1 = PAR_P6*Corr_Temperature;
	  partial_data2 = PAR_P7*Corr_Temperature*Corr_Temperature;
	  partial_data3 = PAR_P8*Corr_Temperature*Corr_Temperature*Corr_Temperature;
	  partial_out1 = PAR_P5+partial_data1+partial_data2+partial_data3;
	
	  partial_data1 = PAR_P2*Corr_Temperature;
	  partial_data2 = PAR_P3*Corr_Temperature*Corr_Temperature;
	  partial_data3 = PAR_P4*Corr_Temperature*Corr_Temperature*Corr_Temperature;
	  partial_out2 = (double)(Pressure)*(PAR_P1+partial_data1+partial_data2+partial_data3);
		
	  partial_data1 = (double)(Pressure)*(double)(Pressure);
	  partial_data2 = PAR_P9+PAR_P10*Corr_Temperature;
	  partial_data3 = partial_data1*partial_data2;
	  partial_data4 = partial_data3+(double)(Pressure)*(double)(Pressure)*(double)(Pressure)*PAR_P11;
	  Corr_Pressure = partial_out1+partial_out2+partial_data4;
		return Corr_Pressure;
}

double Correcting_Temperature(u32 Temperature,int *Temperature_Para)
{	
	double Corr_Temperature,PAR_T1,PAR_T2,PAR_T3;
	double	partial_data1,parital_data2;
	
	
	PAR_T1 = Temperature_Para[0]/Total_Number_Neg_8;
	PAR_T2 = Temperature_Para[1]/Total_Number_30;
	PAR_T3 = Temperature_Para[2]/Total_Number_32/Total_Number_16;
	//Calculation
	partial_data1 = (double)(Temperature)-PAR_T1;
	parital_data2 = partial_data1*PAR_T2;
	Corr_Temperature = parital_data2+partial_data1*partial_data1*PAR_T3;
	return Corr_Temperature;
}

         其头文件如下所示(BM390.h):

#ifndef __BMP390_H
#define __BMP390_H
#include "myiic.h"
#include "sys.h"
#include "LCD.h"
#include "delay.h"
#include "stdio.h"
#include "math.h"

#define BMP390_Write 0XEE
#define BMP390_Read 0xEF

#define CHIP_ID_Addr 0x00
#define REV_ID_Addr 0x01
#define ERR_REG_Addr 0x02
#define STATUS_Addr 0x03

#define PSR_B2_Addr 0x06
#define PSR_B1_Addr 0x05
#define PSR_B0_Addr 0x04

#define TMP_B2_Addr 0x09
#define TMP_B1_Addr 0x08
#define TMP_B0_Addr 0x07

#define SENSORTIME_0_Addr 0x0C
#define SENSORTIME_1_Addr 0x0D
#define SENSORTIME_2_Addr 0x0E

#define EVENT_Addr 0x10
#define INT_CTRL_Addr 0x19
#define IF_CONF_Addr 0x1A
#define PWR_CTRL_Addr 0x1B
#define OSR_Addr 0x1C
#define ODR_Addr 0x1D
#define CONFIG_Addr 0x1F
#define CMD_Addr 0x7E

#define NVM_PAR_P11_Addr  0x45
#define NVM_PAR_P10_Addr  0x44
#define NVM_PAR_P9_H_Addr  0x43
#define NVM_PAR_P9_L_Addr  0x42
#define NVM_PAR_P8_Addr  0x41
#define NVM_PAR_P7_Addr  0x40
#define NVM_PAR_P6_H_Addr  0x3F
#define NVM_PAR_P6_L_Addr  0x3E
#define NVM_PAR_P5_H_Addr  0x3D
#define NVM_PAR_P5_L_Addr  0x3C
#define NVM_PAR_P4_Addr  0x3B
#define NVM_PAR_P3_Addr  0x3A
#define NVM_PAR_P2_H_Addr  0x39
#define NVM_PAR_P2_L_Addr  0x38
#define NVM_PAR_P1_H_Addr  0x37
#define NVM_PAR_P1_L_Addr  0x36

#define NVM_PAR_T3_Addr  0x35
#define NVM_PAR_T2_H_Addr  0x34
#define NVM_PAR_T2_L_Addr  0x33
#define NVM_PAR_T1_H_Addr  0x32
#define NVM_PAR_T1_L_Addr  0x31

#define Total_Number_32 4294967296.0
#define Total_Number_30 1073741824.0
#define Total_Number_29 536870912.0
#define Total_Number_24 16777216.0
#define Total_Number_20 1048576.0
#define Total_Number_16 65536.0
#define Total_Number_15 32768.0
#define Total_Number_14 16384.0
#define Total_Number_12 4096.0
#define Total_Number_8 256.0
#define Total_Number_6 64.0
#define Total_Number_5 32.0
#define Total_Number_1 2.0

#define Total_Number_Neg_8 0.00390625
#define Total_Number_Neg_3 0.125

u8 BMP390_Init(void);
u8 BMP390_Read_Byte(u8 addr);
u32 Temperature_Read(void);
u32 Pressure_Read(void);
void BMP390_Write_Byte(u8 addr,u8 data);
void Parameter_Reading(int *Pressure_Para,int *Temperature_Para);
double Correcting_Temperature(u32 Temperature,int *Temperature_Para);
double Correcting_Pressure(u32 Pressure,int *Pressure_Para,double Corr_Temperature);

#endif

        主函数如下,这里LCD的相关函数是正点原子的LCD函数,用于显示,需要的请自行去正点原子论坛下载。

#include "delay.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "myiic.h"
#include "BMP390.h"
#include "math.h"

#define Average_Times 6
#define Standard_atmospheric_pressure 101325.0
#define Offest_Pressure 0
 int main(void)
 {	 
	u8 t=0;
	u8 i;
	u8 Config;
	u8 lcd_id[12];			
	u8 BMP390_ID;
	u32 Altitude_Temp,Alti_temp;
	u32 Temperature,Temperature_Temp,Temp_temp;
	u32 Pressure,Pressure_Temp,Pres_temp;
	int Pressure_Para[11],Temperature_Para[3];
	float Altitude;
	double Correcting_Temp,Correcting_Press;
	//Delay initialization	  
	delay_init();	    	 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	
	// USART->115200
	uart_init(115200);	 	
	//IIC initialization
	IIC_Init();
	//LCD initialization
	LCD_Init();
	LCD_Clear(WHITE); 
	sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//½«LCD ID´òÓ¡µ½lcd_idÊý×é¡\
	//show initialization
    POINT_COLOR=BLUE;	 
	LCD_ShowString(30,20,240,24,16,"Pressure Measurement");
	POINT_COLOR=RED;
    LCD_ShowString(30,44,240,24,12,"Device ID:");
	LCD_ShowString(30,56,240,24,12,"Mode:Temperature and Pressure");	
	LCD_ShowString(30,68,240,24,16,"Pressure:");
	LCD_ShowString(30,84,240,24,12,"Temperature:");
	LCD_ShowString(30,96,240,24,12,"Altitude:");
	LCD_ShowString(30,108,240,24,12,"Sensor:");
	LCD_ShowString(30,120,240,24,12,"Sensor Config Status:");
	LCD_ShowString(30,132,240,24,12,"Number of Reads:");
	//SPL06_Init
	BMP390_ID = BMP390_Init();
	Parameter_Reading(Pressure_Para,Temperature_Para);
	LCD_ShowxNum(91,44,BMP390_ID,3,12,0);
	//Judge the relevant state of the sensor
	Config = BMP390_Read_Byte(ERR_REG_Addr);
	if(Config&0x01) LCD_ShowString(73,108,240,24,12,"Fatal Error");
	else LCD_ShowString(73,108,240,24,12,"No errors.");
	if((Config>>1)&0x01) LCD_ShowString(157,120,240,24,12,"Failed.");
	else LCD_ShowString(157,120,240,24,12,"Successful.");
  while(1) 
	{	
		Pressure = 0;
		Temperature = 0;
		for (i=0;i<Average_Times;i++)
		{
			Config = BMP390_Read_Byte(STATUS_Addr);
			while(1)
			{
				if(((Config>>5)&0x01) && ((Config>>6)&0x01) && i == 0)
				{
					Pressure = Pressure_Read();
					Temperature = Temperature_Read();
                    LCD_ShowString(30,144,240,24,12,"                  ");					
					LCD_ShowString(30,144,240,24,12,"Data is ready!");
					break;
				}
				else if(((Config>>5)&0x01) && ((Config>>6)&0x01) && i > 0)
				{
					Pressure = Pressure + Pressure_Read();
					Temperature = Temperature + Temperature_Read();
					LCD_ShowString(30,144,240,24,12,"                  ");
					LCD_ShowString(30,144,240,24,12,"Data is ready!");
					break;				
				}
				else
				{
					LCD_ShowString(30,144,240,24,12,"                  ");
					LCD_ShowString(30,144,240,24,12,"Data is not ready!");
					break;
				}
			}
			delay_ms(100);
	  }
		Pressure = Pressure/Average_Times;
		Temperature = Temperature/Average_Times;
		Correcting_Temp = Correcting_Temperature(Temperature,Temperature_Para);	
		Correcting_Press = Correcting_Pressure(Pressure,Pressure_Para,Correcting_Temp)+Offest_Pressure;	
		Altitude = 44330*(1-pow(Correcting_Press/Standard_atmospheric_pressure,1.0/5.255));	
		//show the Correcting Pressure
		Pressure_Temp = Correcting_Press*10;
		Pres_temp = Pressure_Temp/10;
		LCD_ShowxNum(102,68,Pres_temp,7,16,0);
		LCD_ShowString(159,68,240,24,16,".");
		Pres_temp = Pressure_Temp%10;
		LCD_ShowxNum(168,68,Pres_temp,1,16,0);
		LCD_ShowString(177,68,240,24,16,"Pa");
		//show the Correcting Temperature
		Temperature_Temp = Correcting_Temp*10;
		Temp_temp = Temperature_Temp/10;
		LCD_ShowxNum(103,84,Temp_temp,4,12,0);
		LCD_ShowString(128,84,240,24,12,".");
		Temp_temp = Temperature_Temp%10;
		LCD_ShowxNum(135,84,Temp_temp,1,12,0);
		LCD_ShowString(143,84,240,24,12,"Centigrade");
		//show the altitude
		Altitude_Temp = Altitude*10;
		Alti_temp = Altitude_Temp/10;
		LCD_ShowxNum(85,96,Alti_temp,4,12,0);
		LCD_ShowString(110,96,240,24,12,".");
		Alti_temp = Altitude_Temp%10;
		LCD_ShowxNum(117,96,Alti_temp,1,12,0);
		LCD_ShowString(130,96,240,24,12,"m");
		// count the reading times
		t++;
		LCD_ShowxNum(127,132,t,3,12,0);				
 } 
}

        测试结果如下表所示:

压强测试结果
标准压强(Pa)测试压强(Pa)
3000030029
5000050042
7000070060
8000080071
9000090081
100000100088

### 如何在 STM32 上使用 BMP390L 传感器 #### 初始化过程 为了使STM32能够BMP390L气压传感器正常工作,初始化阶段至关重要。这涉及到设置通信协议(通常是I2C或SPI),并配置必要的寄存器来启动传感器的操作模式。 ```c #include "bmp3.h" #include "stm32f4xx_hal.h" // 定义全局变量用于存储设备句柄 struct bmp3_dev dev; void bmp390l_init(void){ /* 设置 I2C 或 SPI 接口 */ dev.intf = BMP3_I2C_INTF; // 假设已定义好的 I2C 句柄为 hi2c1 dev.read = i2c_read; // 自定义的 I2C/SPI 读函数指针 dev.write = i2c_write; // 自定义的 I2C/SPI 写函数指针 dev.delay_ms = delay_func; // 用户自定义延时函数 dev.dev_id = BMP3_I2C_ADDR_PRIM; // 主要地址 dev intf_ptr = (void *)&hi2c1; // 将 HAL 的 I2C 结构体传入 } ``` 上述代码展示了如何通过调用`i2c_read`, `i2c_write`以及`delay_func`这些由用户自行实现的辅助函数完成对BMP390L的基础设定[^3]。 #### 获取压力和温度数据 一旦完成了初始化流程,就可以利用提供的API去请求最新的测量结果: ```c int8_t get_pressure_temperature(float *pressure, float *temperature){ struct bmp3_sensor_data data; int8_t rslt = bmp3_get_sensor_data(BMP3_PRESS_TEMP, &data, &dev); if(rslt == BMP3_OK){ *pressure = data.pressure / 100.0f; // 单位转换 Pa -> hPa *temperature = data.temperature; // 温度单位 °C } return rslt; } ``` 这段代码片段说明了怎样从BMP390L中提取当前的压力和温度数值,并进行了简单的单位调整以便更直观地理解所获得的数据。 #### 示例应用:定期打印传感器读数 下面是一个完整的例子,它会每隔一秒向串行端口发送一次来自BMP390L的新鲜采样值。 ```c int main(void){ HAL_Init(); SystemClock_Config(); // 系统时钟配置省略... bmp390l_init(); while(1){ static uint32_t last_time = 0; if(HAL_GetTick() - last_time >= 1000){ // 每秒执行一次 last_time = HAL_GetTick(); float pressure, temperature; if(get_pressure_temperature(&pressure, &temperature) == BMP3_OK){ printf("Pressure: %.2fhPa Temperature:%.2f°C\n", pressure, temperature); }else{ printf("Failed to read sensor.\n"); } } } } ``` 此部分演示了一个简单的时间循环机制,在每次迭代期间都会尝试更新显示面板上的信息,如果成功则输出最新测得的压力和气温;反之,则提示错误消息。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值