#include "bmp180.h"
#include "delay.h"
#include "math.h"
#include "led.h"
#include "usart.h"
//存储BMP180数据的结构
_bmp180 bmp180;
//BMP180初始化
//使用IIC端口初始化
void BMP_Init(void)
{
IIC_Init();
}
///写一个数据BMP180
void BMP_WriteOneByte(uint8_t WriteAddr,uint8_t DataToWrite)
{
IIC_Start();
IIC_Send_Byte(0xEE);///发送个字节(地址 Module address 0cEE)
IIC_Wait_Ack();/等待
IIC_Send_Byte(WriteAddr);//发送字节地址
IIC_Wait_Ack();
IIC_Send_Byte(DataToWrite);//发送字节地址中的数据
IIC_Wait_Ack();
IIC_Stop();
}
//从BMP180读一个字节数据
uint8_t BMP_ReadOneByte(uint8_t ReadAddr)
{
uint8_t data = 0;
IIC_Start();
IIC_Send_Byte(0xEE);
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr);
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(0xEF); ///将读取的字节存储到下一个地址(0xef)中去
IIC_Wait_Ack();
data = IIC_Read_Byte(1); ////阅读地址总字节
IIC_Stop();
return data;
}
//从BMP180读16位数据
short BMP_ReadTwoByte(uint8_t ReadAddr)
{
short data;
uint8_t msb,lsb;
IIC_Start();
IIC_Send_Byte(0xEE);///发送字节(地址为 Module address 0cEE)
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr);
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(0xEF);///将读取的字节存储到下一个地址(0xef)中去
IIC_Wait_Ack();
msb = IIC_Read_Byte(1)///读16位高八位
lsb = IIC_Read_Byte(0);//读16位的低八位
IIC_Stop();
data = msb*256 lsb;///以16位二进制数据给出data
return data;
}
//从BMP180获取计算参数
void BMP_ReadCalibrationData(void)
{
bmp180.AC1 = BMP_ReadTwoByte(0xAA);
bmp180.AC2 = BMP_ReadTwoByte(0xAC);
bmp180.AC3 = BMP_ReadTwoByte(0xAE);
bmp180.AC4 = BMP_ReadTwoByte(0xB0);
bmp180.AC5 = BMP_ReadTwoByte(0xB2);
bmp180.AC6 = BMP_ReadTwoByte(0xB4);
bmp180.B1= BMP_ReadTwoByte(0xB6);
bmp180.B2= BMP_ReadTwoByte(0xB8);
bmp180.MB= BMP_ReadTwoByte(0xBA);
bmp180.MC= BMP_ReadTwoByte(0xBC);
bmp180.MD= BMP_ReadTwoByte(0xBE);
}
//从BMP180读取未修正的温度
long BMP_Read_UT(void)
{
long temp = 0;
BMP_WriteOneByte(0xF4,0x2E);
delay_ms(5);
temp = (long)BMP_ReadTwoByte(0xF6);
return temp;
}
//从BMP180读取未修正的大气压力
long BMP_Read_UP(void)
{
long pressure = 0;
BMP_WriteOneByte(0xF4,0x34);
delay_ms(5);
pressure = (long)BMP_ReadTwoByte(0xF6);
//pressure = pressure BMP_ReadOneByte(0xf8);
pressure &= 0x0000FFFF; //位运算,将pressure高八位清0,低八位保留
return pressure;
}
//用获取的参数对温度和大气压进行修正,并计算海拔
void BMP_UncompemstatedToTrue(void)
{
bmp180.UT = BMP_Read_UT()实际温度值只有-78度 海拔超过2500米(延迟变化无用)
bmp180.UT = BMP_Read_UT()正确读取两次温度值
bmp180.UP = BMP_Read_UP()
/**--得到温度值--**/
bmp180.X1 = ((bmp180.UT - bmp180.AC6) * bmp180.AC5) >> 15;
bmp180.X2 = (((long)bmp180.MC) << 11) / (bmp180.X1 bmp180.MD);
bmp180.B5 = bmp180.X1 bmp180.X2;
bmp180.Temp= (bmp180.B5 8) >> 4;
/**--得到气压值--**/
bmp180.B6 = bmp180.B5 - 4000;
bmp180.X1 = ((long)bmp180.B2 * (bmp180.B6 * bmp180.B6 >> 12)) >> 11;
bmp180.X2 = ((long)bmp180.AC2) * bmp180.B6 >> 11;
bmp180.X3 = bmp180.X1 bmp180.X2;
bmp180.B3 = ((((long)bmp180.AC1) * 4 bmp180.X3) 2) /4;
bmp180.X1 = ((long)bmp180.AC3) * bmp180.B6 >> 13;
bmp180.X2 = (((long)bmp180.B1) *(bmp180.B6*bmp180.B6 >> 12)) >>16;
bmp180.X3 = ((bmp180.X1 bmp180.X2) 2) >> 2;
bmp180.B4 = ((long)bmp180.AC4) * (unsigned long)(bmp180.X3 32768) >> 15;
bmp180.B7 = ((unsigned long)bmp180.UP - bmp180.B3) * 50000;
if(bmp180.B7 < 0x80000000)
{
bmp180.p = (bmp180.B7 * 2) / bmp80.B4;
}
else
{
bmp180.p = (bmp180.B7 / bmp180.B4) * 2;
}
bmp180.X1 = (bmp180.p >> 8) * (bmp180.p >>8);
bmp180.X1 = (((long)bmp180.X1) * 3038) >> 16;
bmp180.X2 = (-7357 * bmp180.p) >> 16;
bmp180.p = bmp180.p + ((bmp180.X1 + bmp180.X2 + 3791) >> 4);
/**--得到海拔高度--**/
bmp180.altitude = 44330 * (1-pow(((bmp180.p) / 101325.0),(1.0/5.255)));
}
/**--串口显示读取到的数据--**/
void Show_Read_Data(void)
{
u8 ID = 0;
u16 i=0;
ID = BMP_ReadOneByte(0xd0);
BMP_UncompemstatedToTrue();
printf("ID = %d\t temp = %d.%dC\t Pressure = %ldPa\t Altitude = %.5fm\r\n",ID,bmp180.Temp/10,bmp180.Temp%10,bmp180.p,bmp180.altitude);
i++;
delay_ms(1000);
if(i==1)
{
LED0=!LED0;//灯闪烁,提示系统正在运行
i=0;
}
}