#include "BMP390.h"
|
//#include "stm32l0xx_hal_gpio.h"
|
#include "main.h"
|
#include <stdio.h>
|
#define Offest_Pressure 0
|
|
//³õʼ»¯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
|
|
GPIO_InitTypeDef GPIO_InitStructure= {0};
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
GPIO_InitStructure.Pin = GPIO_PIN_2|GPIO_PIN_3;
|
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD ; //ÍÆÍìÊä³ö
|
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
|
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2|GPIO_PIN_3,GPIO_PIN_SET); //PB6,PB7 Êä³ö¸ß
|
}
|
//²úÉúI2CÆðʼÐźÅ(¼´STARTÐźÅ)
|
void IIC_Start(void)
|
{
|
// IIC2_SDA_OUT(); //sdaÏßÊä³ö
|
BMP390_SDA_1;
|
// delay_us(10);
|
BMP390_SCL_1;
|
delay_us(10);
|
BMP390_SDA_0;//START:when CLK is high,DATA change form high to low
|
delay_us(10);
|
BMP390_SCL_0;//ǯסI2C×ÜÏߣ¬×¼±¸·¢ËÍ»ò½ÓÊÕÊý¾Ý
|
}
|
//²úÉúI2CÍ£Ö¹ÐźÅ(¼´STOPÐźÅ)
|
void IIC_Stop(void)
|
{
|
// IIC2_SDA_OUT();//sdaÏßÊä³ö
|
BMP390_SCL_0;
|
// delay_us(10);
|
BMP390_SDA_0;//STOP:when CLK is high DATA change form low to high
|
delay_us(10);
|
BMP390_SCL_1;
|
// delay_us(10);
|
BMP390_SDA_1;//·¢ËÍI2C×ÜÏß½áÊøÐźÅ
|
delay_us(10);
|
}
|
//µÈ´ýÓ¦´ðÐźÅ
|
//·µ»ØÖµ£º1£¬½ÓÊÕÓ¦´ðʧ°Ü
|
// 0£¬½ÓÊÕÓ¦´ð³É¹¦
|
u8 IIC_Wait_Ack(void)
|
{
|
uint8_t ucErrTime=0;
|
// IIC2_SDA_IN(); //SDAÉèÖÃΪÊäÈë
|
BMP390_SDA_1;
|
delay_us(1);
|
BMP390_SCL_1;
|
delay_us(1);
|
|
while(BMP390_IIC2_READ_SDA)
|
{
|
ucErrTime++;
|
if(ucErrTime>250)
|
{
|
IIC_Stop();
|
return 1;
|
}
|
}
|
BMP390_SCL_0;//ʱÖÓÊä³ö0
|
return 0;
|
}
|
//²úÉúACKÓ¦´ðÐźÅ
|
void IIC_Ack(void)
|
{
|
BMP390_SCL_0;
|
// IIC2_SDA_OUT();
|
BMP390_SDA_0;
|
delay_us(10);
|
BMP390_SCL_1;
|
delay_us(10);
|
BMP390_SCL_0;
|
}
|
//²»²úÉúACKÓ¦´ðÐźÅ
|
void IIC_NAck(void)
|
{
|
BMP390_SCL_0;
|
// IIC2_SDA_OUT();
|
BMP390_SDA_1;
|
delay_us(10);
|
BMP390_SCL_1;
|
delay_us(10);
|
BMP390_SCL_0;
|
}
|
//I2C·¢ËÍÒ»¸ö×Ö½Ú
|
//·µ»Ø´Ó»úÓÐÎÞÓ¦´ð
|
//1£¬ÓÐÓ¦´ð
|
//0£¬ÎÞÓ¦´ð
|
void IIC_Send_Byte(u8 txd)
|
{
|
uint8_t t;
|
// IIC2_SDA_OUT();
|
BMP390_SCL_0;//ÀµÍʱÖÓ¿ªÊ¼Êý¾Ý´«Êä
|
for(t=0;t<8;t++)
|
{
|
if((txd&0x80)>>7)
|
{
|
BMP390_SDA_1;
|
}
|
else
|
{
|
BMP390_SDA_0;
|
}
|
|
txd <<= 1;
|
delay_us(10);
|
BMP390_SCL_1;
|
delay_us(10);
|
BMP390_SCL_0;
|
delay_us(10);
|
}
|
}
|
//¶Á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++ )
|
{
|
BMP390_SCL_0;
|
delay_us(10);
|
BMP390_SCL_1;
|
receive<<=1;
|
if(BMP390_IIC2_READ_SDA)receive++;
|
delay_us(5);
|
}
|
if (!ack)
|
IIC_NAck();//·¢ËÍnACK
|
else
|
IIC_Ack(); //·¢ËÍACK
|
return receive;
|
}
|
|
|
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,temp;
|
// IIC_Start();
|
// IIC_Send_Byte(BMP390_Write);
|
// IIC_Send_Byte(0xB6);
|
// IIC_Stop();
|
BMP390_Write_Byte(CMD_Addr,0xB6);//RESET
|
delay_ms(100);
|
BMP390_ID = BMP390_Read_Byte(CHIP_ID_Addr);//Read the CHIP_ID-0x60
|
printf("BMP390_ID:%d",BMP390_ID);
|
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
|
|
temp = BMP3_OVERSAMPLING_2X<<3|BMP3_OVERSAMPLING_32X;
|
BMP390_Write_Byte(OSR_Addr,temp);//Set the PM-RATE and PM-PRC,Set the TMPI-RATE and TMP-PRC
|
temp = BMP3_ODR_6_25_HZ;
|
BMP390_Write_Byte(ODR_Addr,temp);//Set the configuration of the output data rates by means of setting the subdivision/subsampling.
|
temp = BMP3_IIR_FILTER_COEFF_3<<1;
|
BMP390_Write_Byte(CONFIG_Addr,temp);//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 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;
|
double Correcting_Pressure(u32 Pressure,int *Pressure_Para,double Corr_Temperature)
|
{
|
|
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 Corr_Temperature,PAR_T1,PAR_T2,PAR_T3;
|
double partial_data1,parital_data2;
|
double nub;
|
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;
|
nub=PAR_T2*PAR_T1;
|
Corr_Temperature = parital_data2+partial_data1*partial_data1*PAR_T3;
|
return Corr_Temperature;
|
}
|
float Altitude;
|
double Correcting_Temp,Correcting_Press;
|
int Pressure_Para[11],Temperature_Para[3];
|
void GetPressAndHeight()
|
{
|
float Pressure,Pressure_Temp,Pres_temp;
|
float Temperature,Temperature_Temp,Temp_temp;
|
Pressure = 0;
|
Temperature = 0;
|
Pressure = Pressure_Read();
|
Temperature = Temperature_Read();
|
|
Correcting_Temp = Correcting_Temperature(Temperature,Temperature_Para);
|
Correcting_Press = Correcting_Pressure(Pressure,Pressure_Para,Correcting_Temp)+Offest_Pressure;
|
Altitude = 44330*(1-pow(Correcting_Press/101325.0,1.0/5.255));
|
// Correcting_Press = Correcting_Press/100;
|
if(Correcting_Press==0)
|
Altitude = 0;
|
|
}
|