#include <REGX52.H>
#include "I2C.h"
#include"LCD1602.h"
#define BMP280_ADDRESS 0xEE //BMP280 I2C地址
typedef long BMP280_S32_t;
typedef unsigned long BMP280_U32_t;
BMP280_S32_t var1, var2, T;
BMP280_S32_t t_fine;
BMP280_U32_t p;
static unsigned short dig_T1,dig_P1;
static short dig_T2,dig_T3,dig_P2,dig_P3,dig_P4,dig_P5,dig_P6,dig_P7,dig_P8,dig_P9;
static long adc_T,adc_P,TEMP,PRESS;
unsigned char temp_xlsb,temp_lsb,temp_msb,press_xlsb,press_lsb,press_msb;
unsigned int dis_p1,dis_p2; //显示测试
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] BMP280写入一个字节
* @param WordAddress 要写入字节的地址
* @param Data 要写入的数据
* @retval 无
*/
void BMP280_WriteByte(unsigned char WordAddress,Data)
{
I2C_Start();
I2C_SendByte(BMP280_ADDRESS);
I2C_ReceiveAck();
I2C_SendByte(WordAddress);
I2C_ReceiveAck();
I2C_SendByte(Data);
I2C_ReceiveAck();
I2C_Stop();
}
/**
* @brief BMP280读取一个字节
* @param WordAddress 要读出字节的地址
* @retval 读出的数据
*/
unsigned char BMP280_ReadByte(unsigned char WordAddress)
{
unsigned char Data;
I2C_Start();
I2C_SendByte(BMP280_ADDRESS);
I2C_ReceiveAck();
I2C_SendByte(WordAddress);
I2C_ReceiveAck();
I2C_Start();
I2C_SendByte(BMP280_ADDRESS|0x01);
I2C_ReceiveAck();
Data=I2C_ReceiveByte();
I2C_SendAck(1);
I2C_Stop();
return Data;
}
short ym(short bm) //利用补码计算源码公式
{
short mid;
if(bm&0x8000) //如果符号位不为零
{
mid=((~bm)|0x8000)+1;
return mid;
}
else return bm;
}
void BMP280_INIT()
{
BMP280_WriteByte(0xF4,0xB7); //设置16倍过采样和一般模式
BMP280_WriteByte(0xF5,0x80); //设置待机间隔时间,过滤器,三线spi使能
//开始读取补偿数据
dig_T1=BMP280_ReadByte(0x88);
dig_T1<<=8;
dig_T1+=BMP280_ReadByte(0x89);
dig_T2=BMP280_ReadByte(0x8A);
dig_T2<<=8;
dig_T2+=BMP280_ReadByte(0x8B);
dig_T3=BMP280_ReadByte(0x8C);
dig_T3<<=8;
dig_T3+=BMP280_ReadByte(0x8D);
dig_P1=BMP280_ReadByte(0x8E);
dig_P1<<=8;
dig_P1+=BMP280_ReadByte(0x8F);
dig_P2=BMP280_ReadByte(0x90);
dig_P2<<=8;
dig_P2+=BMP280_ReadByte(0x91);
dig_P3=BMP280_ReadByte(0x92);
dig_P3<<=8;
dig_P3+=BMP280_ReadByte(0x93);
dig_P4=BMP280_ReadByte(0x94);
dig_P4<<=8;
dig_P4+=BMP280_ReadByte(0x95);
dig_P5=BMP280_ReadByte(0x96);
dig_P5<<=8;
dig_P5+=BMP280_ReadByte(0x97);
dig_P6=BMP280_ReadByte(0x98);
dig_P6<<=8;
dig_P6+=BMP280_ReadByte(0x99);
dig_P7=BMP280_ReadByte(0x9A);
dig_P7<<=8;
dig_P7+=BMP280_ReadByte(0x9B);
dig_P8=BMP280_ReadByte(0x9C);
dig_P8<<=8;
dig_P8+=BMP280_ReadByte(0x9D);
dig_P9=BMP280_ReadByte(0x9E);
dig_P9<<=8;
dig_P9+=BMP280_ReadByte(0x9F);
dig_T1=ym(dig_T1);
dig_T2=ym(dig_T2);
dig_T3=ym(dig_T3);
dig_P1=ym(dig_P1);
dig_P2=ym(dig_P2);
dig_P3=ym(dig_P3);
dig_P4=ym(dig_P4);
dig_P5=ym(dig_P5);
dig_P6=ym(dig_P6);
dig_P7=ym(dig_P7);
dig_P8=ym(dig_P8);
dig_P9=ym(dig_P9);
//LCD_ShowHexNum(2,1,dig_T2,4); //测试语句
//LCD_ShowHexNum(2,6,dig_P1,4);
//LCD_ShowHexNum(2,11,dig_P9,4);
}
void BMP280_ReadADC(void)
{
I2C_Start();
I2C_SendByte(BMP280_ADDRESS);
I2C_ReceiveAck();
I2C_SendByte(0xF7);
I2C_ReceiveAck();
I2C_Start();
I2C_SendByte(BMP280_ADDRESS|0x01);
I2C_ReceiveAck();
press_msb=I2C_ReceiveByte();
I2C_SendAck(0);
press_lsb=I2C_ReceiveByte();
I2C_SendAck(0);
press_xlsb=I2C_ReceiveByte();
I2C_SendAck(0);
temp_msb=I2C_ReceiveByte();
I2C_SendAck(0);
temp_lsb=I2C_ReceiveByte();
I2C_SendAck(0);
temp_xlsb=I2C_ReceiveByte();
I2C_SendAck(1);
I2C_Stop(); //突发读取所有原始数据
adc_T=0;
adc_T|=temp_msb<<12;
adc_T=adc_T|(temp_lsb<<4);
adc_T=adc_T|(temp_xlsb>>4); //20位温度原始数据存储到adc_T中
adc_P=0;
adc_P=BMP280_ReadByte(0xFA)<<12;
adc_P=adc_P+BMP280_ReadByte(0xFB)<<4;
adc_P=adc_P+BMP280_ReadByte(0xFC)>>4; //20位温度原始数据存储到adc_P中
//LCD_ShowHexNum(2,1,adc_T,4); LCD_ShowHexNum(2,6,adc_P,4); //测试语句
//校准语句
// Returns temperature in DegC, resolution is 0.01 DegC. Output value of “5123” equals 51.23 DegC.
// t_fine carries fine temperature as global value
var1=((((adc_T>>3)-((BMP280_S32_t)dig_T1<<1)))*((BMP280_S32_t)dig_T2))>>11;
var2=(((((adc_T>>4)-((BMP280_S32_t)dig_T1))*((adc_T>>4)-((BMP280_S32_t)dig_T1)))>>12)*((BMP280_S32_t)dig_T3))>>14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
TEMP=T;
// Returns pressure in Pa as unsigned 32 bit integer. Output value of “96386” equals 96386 Pa = 963.86 hPa
//BMP280_S32_t var1, var2;
var1=(((BMP280_S32_t)t_fine)>>1)-(BMP280_S32_t)64000;
var2=(((var1>>2)*(var1>>2))>>11 )*((BMP280_S32_t)dig_P6);
var2=var2+((var1*((BMP280_S32_t)dig_P5))<<1);
var2=(var2>>2)+(((BMP280_S32_t)dig_P4)<<16);
var1=(((dig_P3*(((var1>>2)*(var1>>2))>>13))>>3)+((((BMP280_S32_t)dig_P2)*var1)>>1))>>18;
var1=((((32768+var1))*((BMP280_S32_t)dig_P1))>>15);
if (var1 == 0)
{
PRESS=0; // avoid exception caused by division by zero
}
p = (((BMP280_U32_t)(((BMP280_S32_t)1048576)-adc_P)-(var2>>12)))*3125;
if (p<0x80000000)
{
p = (p<<1)/((BMP280_U32_t)var1);
}
else
{
p=(p/(BMP280_U32_t)var1)*2;
}
var1=(((BMP280_S32_t)dig_P9)*((BMP280_S32_t)(((p>>3)*(p>>3))>>13)))>>12;
var2=(((BMP280_S32_t)(p>>2))*((BMP280_S32_t)dig_P8))>>13;
p=(BMP280_U32_t)((BMP280_S32_t)p+((var1 + var2 + dig_P7)>>4));
PRESS=p;
dis_p2=PRESS%1000;
dis_p1=PRESS/1000;
LCD_ShowNum(2,1,TEMP,5);
LCD_ShowNum(2,6,dis_p1,2);LCD_ShowNum(2,8,dis_p2,3);
}