#include "BMP180.h"
#include "delay.h"
//PA6--SCL PA7--SDA
//I2C总线初始化
//配置SDA信号线为输入模式
u8 BMP_communication_sta = 1;
void BMP180_SDA_Input_Mode()
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = BMP180_SDA;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(BMP180_I2C_PORT, &GPIO_InitStructure);
}
//配置SDA信号线为输出模式
void BMP180_SDA_Output_Mode()
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = BMP180_SDA;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(BMP180_I2C_PORT, &GPIO_InitStructure);
}
void BMP180_SDA_Output( uint16_t val )
{
if ( val ) {
GPIO_SetBits(BMP180_I2C_PORT,BMP180_SDA);
} else {
GPIO_ResetBits(BMP180_I2C_PORT,BMP180_SDA);
}
}
//
uint8_t BMP180_SDA_Input()
{
return GPIO_ReadInputDataBit(BMP180_I2C_PORT, BMP180_SDA);
}
//
void BMP180_SCL_Output( uint16_t val )
{
if ( val ) {
GPIO_SetBits(BMP180_I2C_PORT,BMP180_SCL);
} else {
GPIO_ResetBits(BMP180_I2C_PORT,BMP180_SCL);
}
}
//延时程序
void BMP180_delay1(unsigned int n)
{
unsigned int i;
for ( i=0;i<n;++i);
}
//I2C总线启动
void BMP180_I2CStart(void)
{
BMP180_SDA_Output(1);BMP180_delay1(500);
BMP180_SCL_Output(1);BMP180_delay1(500);
BMP180_SDA_Output(0);BMP180_delay1(500);
BMP180_SCL_Output(0);BMP180_delay1(500);
}
//I2C总线停止
void BMP180_I2CStop(void)
{
BMP180_SCL_Output(0); BMP180_delay1(500);
BMP180_SDA_Output(0); BMP180_delay1(500);
BMP180_SCL_Output(1); BMP180_delay1(500);
BMP180_SDA_Output(1); BMP180_delay1(500);
}
//等待应答
unsigned char BMP180_I2CWaitAck(void)
{
unsigned short cErrTime = 5;
BMP180_SDA_Input_Mode();
BMP180_delay1(500);
BMP180_SCL_Output(1);
BMP180_delay1(500);
while(BMP180_SDA_Input())
{
cErrTime--;
BMP180_delay1(500);
if (0 == cErrTime)
{
BMP180_SDA_Output_Mode();
BMP_communication_sta = 0;
BMP180_I2CStop();
return 0;
}
}
BMP180_SDA_Output_Mode();
BMP180_SCL_Output(0);
BMP180_delay1(500);
return 1;
}
//发送应答位
void BMP180_I2CSendAck(void)
{
BMP180_SDA_Output(0);
BMP180_delay1(500);
BMP180_delay1(500);
BMP180_SCL_Output(1);
BMP180_delay1(500);
BMP180_SCL_Output(0);
BMP180_delay1(500);
}
//
void BMP180_I2CSendNotAck(void)
{
BMP180_SDA_Output(1);
BMP180_delay1(500);
BMP180_SCL_Output(1);
BMP180_delay1(500);
BMP180_SCL_Output(0);
BMP180_delay1(500);
}
//通过I2C总线发送一个字节数据
void BMP180_I2CSendByte(unsigned char cSendByte)
{
unsigned char i = 8;
while (i--)
{
BMP180_SCL_Output(0);
BMP180_delay1(500);
BMP180_SDA_Output(cSendByte & 0x80);
BMP180_delay1(500);
cSendByte += cSendByte;
BMP180_delay1(500);
BMP180_SCL_Output(1);
BMP180_delay1(500);
}
BMP180_SCL_Output(0);
BMP180_delay1(500);
}
//从I2C总线接收一个字节数据
unsigned char BMP180_I2CReceiveByte(void)
{
unsigned char i = 8;
unsigned char cR_Byte = 0;
BMP180_SDA_Input_Mode();
while (i--)
{
cR_Byte += cR_Byte;
BMP180_SCL_Output(0);
BMP180_delay1(500);
BMP180_delay1(500);
BMP180_SCL_Output(1);
BMP180_delay1(500);
cR_Byte |= BMP180_SDA_Input();
}
BMP180_SCL_Output(0);
BMP180_delay1(500);
BMP180_SDA_Output_Mode();
return cR_Byte;
}
//单字节写入BMP180内部数据
void BMP180_Write(u8 REG_Address, u8 data)
{
BMP180_I2CStart();
BMP180_I2CSendByte(BMP180_Address);
BMP180_I2CWaitAck();
BMP180_I2CSendByte(REG_Address);
BMP180_I2CWaitAck();
BMP180_I2CSendByte(data);
BMP180_I2CWaitAck();
BMP180_I2CStop();
delay_ms(1);
}
//单字节读取BMP180内部数据********************************
u8 BMP180_Read_Single(u8 REG_Address)
{
u8 data;
BMP180_I2CStart(); //起始信号
BMP180_I2CSendByte(BMP180_Address); //发送设备地址+写信号
BMP180_I2CWaitAck();
BMP180_I2CSendByte(REG_Address); //发送存储单元地址
BMP180_I2CWaitAck();
BMP180_I2CStart(); //起始信号
BMP180_I2CSendByte(BMP180_Address | 0x01); //发送设备地址+读信号
BMP180_I2CWaitAck();
data=BMP180_I2CReceiveByte(); //读出寄存器数据
BMP180_I2CSendNotAck();
BMP180_I2CStop(); //停止信号
BMP180_delay1(500);
return data;
}
//读出BMP180内部数据,连续两个
//*********************************************************
u16 BMP180_Read_Multiple(u8 REG_Address)
{
u8 MSB, LSB;
u16 data;
BMP180_I2CStart(); //起始信号
BMP180_I2CSendByte(BMP180_Address); //发送设备地址+写信号
BMP180_I2CWaitAck();
BMP180_I2CSendByte(REG_Address); //发送存储单元地址
BMP180_I2CWaitAck();
BMP180_I2CStart(); //起始信号
BMP180_I2CSendByte(BMP180_Address | 0x01); //发送设备地址+读信号
BMP180_I2CWaitAck();
MSB = BMP180_I2CReceiveByte(); //BUF[0]存储
BMP180_I2CSendAck(); ; //回应ACK
LSB = BMP180_I2CReceiveByte();
BMP180_I2CSendNotAck(); //最后一个数据需要回NOACK
BMP180_I2CStop(); //停止信号
BMP180_delay1(500);
data = MSB << 8 | LSB;
return data;
}
int16_t AC1,AC2,AC3,B1,B2,MB,MC,MD;
uint16_t AC4,AC5,AC6;
void BMP180_ReadCalvalue(void)
{
AC1 = BMP180_Read_Multiple(0xAA);
AC2 = BMP180_Read_Multiple(0xAC);
AC3 = BMP180_Read_Multiple(0xAE);
AC4 = BMP180_Read_Multiple(0xB0);
AC5 = BMP180_Read_Multiple(0xB2);
AC6 = BMP180_Read_Multiple(0xB4);
B1 = BMP180_Read_Multiple(0xB6);
B2 = BMP180_Read_Multiple(0xB8);
MB = BMP180_Read_Multiple(0xBA);
MC = BMP180_Read_Multiple(0xBC);
MD = BMP180_Read_Multiple(0xBE);
}
long BMP180_ReadTemp(void)
{
BMP180_Write(CTRL_MEAS, 0x2E); //Max. conversion time 4.5ms
delay_ms(5);
return (int64_t)BMP180_Read_Multiple(OUT_MSB);
}
//*************************************************************
long BMP180_ReadPressure(void)
{
u16 pressure = 0;
BMP180_Write(CTRL_MEAS, 0x34); //Max. conversion time 4.5ms
delay_ms(5);
pressure = BMP180_Read_Multiple(OUT_MSB);
pressure &= 0x0000FFFF;
return (int64_t)pressure;
}
//获得BMP180的温度和气压值
#define OSS 0
void Read_BMP180_Date(u16 *Temp, u32 *Press, u32 *altitude)
{
int64_t X1,X2,X3,B3,B5,B6,B7,P,tmp,pre;
uint64_t B4;
tmp = BMP180_ReadTemp();
pre = BMP180_ReadPressure();
//计算温度 temp in 0.1°C
X1 = (tmp - AC6) * AC5 >> 15; //X1 = (UT - AC6) * AC5 / 2^15
X2 = (MC << 11) / (X1 + MD); //X2 = MC * 2^11 / (X1 + MD)
B5 = X1 + X2; //B5 = X1 + X2
*Temp = (B5 + 8) >> 4; //T = (B5 + 8) / 2^4
//计算压强 press in Pa
B6 = B5 - 4000;
X1 = (B2 * (B6 * B6 >> 12)) >> 11;
X2 = AC2 * B6 >> 11;
X3 = X1 + X2;
B3 = ((AC1 * 4 + X3) + 2)/4;
X1 = AC3 * B6 >> 13;
X2 = (B1 * (B6 * B6 >> 12)) >> 16;
X3 = ((X1 + X2) + 2) >> 2;
B4 = (AC4 * (X3 + 32768)) >> 15;
B7 = ((uint64_t) pre - B3) * (50000 >> OSS);
if( B7 < 0x80000000)
P = (B7 * 2) / B4 ;
else
P = (B7 / B4) * 2;
X1 = (P >> 8) * (P >> 8);
X1 = (X1 * 3038) >> 16;
X2 = (-7357 * P) >> 16;
*Press = P + ((X1 + X2 + 3791) >> 4);
*altitude = *Press;
*altitude = (101325 - (float)*altitude) / 100 * 843;// 1hPa = 8.43m
}
//读SHT30状态
u8 Read_BMP180_ID(void)
{
BMP180_ReadCalvalue();
return BMP180_Read_Single(BMP180_ID);
}
void BMP180_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(BMP180_RCC, ENABLE);
GPIO_InitStructure.GPIO_Pin = BMP180_SDA | BMP180_SCL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // **
GPIO_Init(BMP180_I2C_PORT, &GPIO_InitStructure);
GPIO_SetBits(BMP180_I2C_PORT,BMP180_SDA);