- #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; //顯示測試
- /**
- * @brief 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);
- }
復制代碼
- #ifndef __BMP280_H__
- #define __BMP280_H__
- void BMP280_WriteByte(unsigned char WordAddress,Data);
- unsigned char BMP280_ReadByte(unsigned char WordAddress);
- void BMP280_INIT();
- void BMP280_ReadADC(void);
- #endif
復制代碼
|