21ic电子技术开发论坛 单片机与嵌入式系统 Megawin(笙泉)单片机 bmp280 单片机代码实现
发新帖我要提问
返回列表
打印
[应用方案]

bmp280 单片机代码实现

[复制链接]
615|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chenci2013|  楼主 | 2023-11-18 20:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


#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);

}


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

100

主题

6221

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部