传感器系列之4.2气压传感器

4.2 气压传感实验

一、实验目的

  1. 掌握LPC2378芯片的编程方法
  2. 掌握气压传感器的使用方法
  3. 掌握气压传感器在实际中的应用

二、实验材料

  1. 具有USB 串口通讯的PC 机1 台
  2. ADS1.2 集成开发软件1 套
  3. J-Link-ARM 仿真器及软件1 套
  4. NXP LPC2378 实验节点板1 个
  5. LCD 显示实验板1 个
  6. BMP085数字气压传感器模块1个

三、实验原理

  振动传感器实验环境由PC机(安装有Windows XP操作系统、ADS1.2集成开发环境和J-Link-ARM-V410i仿真器)、J-Link-ARM仿真器、NXP LPC2378实验节点板、振动传感器、实验模块和LCD显示实验模块组成,如图4.2.1所示。

这里写图片描述
图4.2.1 传感器实验环境

1.拓展知识

(1)气体压力传感器简介
  气体传感器是一种将气体的成份、浓度等信息转换成可以被人员、仪器仪表、计算机等利用的信息的装置!气体传感器一般被归为化学传感器的一类,尽管这种归类不一定科学。气体传感器包括:半导体气体传感器、电化学气体传感器、催化燃烧式气体传感器、热导式气体传感器、红外线气体传感器等。

(2)气体传感器的分类
1)半导气体传感器
  这种类型的传感器在气体传感器中约占60%,根据其机理分为电导型和非电导型,电导型中又分为表面型和容积控制型.   

2)固体电解质气体传感器
  这种传感器元件为离子对固体电解质隔膜传导,称为电化学池,分为阳离子传导和阴离子传导,是选择性强的传感器,研究较多达到实用化的是氧化锆固体电解质传感器,其机理是利用隔膜两侧两个电池之间的电位差等于浓差电池的电势。稳定的氧化铬固体电解质传感器已成功地应用于钢水中氧的测定和发动机空燃比成分测量等。为弥补固体电解质导电的不足,近几年来在固态电解质上燕镀一层气体敏膜,把围周环境中存在的气体分子数量和介质中可移动的粒子数量联系起来。

3)接触燃烧式气体传感器
  接触燃烧式传感器适用于可燃性气H2、CO、CH4的检测。可燃气体接触表面催化剂Pt 、Pd 时燃烧、破热,燃烧热与气体浓富有关。这类传感器的应用面广、体积小、结构简单、稳定性好,缺点是选择性差。

4)电化学气体传感器
电化学方式的气体传感器常用的有两种
( 1 )恒电位电解式传感器是将被测气体在特定电场下电离,由流经的电解电流测出气体浓度,这种传感器灵敏度高,改变电位可选择的检洌气体,对毒性气体检测有重要作用。
( 2) 原电池式气体传感器在KOH电解质溶液中,pt —Pb或Ag —Pb 电极构成电池,已成功用于检测O2,其灵敏度高,缺点是透水逸散吸潮,电极易中毒。

5)光学气体传感嚣
( 1 ) 直接吸收式气体传感器:红外线气体传感器是典型的吸收式光学气体传感器,是根据气体分别具有各自固有的光谱吸收谱检测气体成分,非分散红外吸收光谱对SO2、CO、C O2、NO等气体具有较高的灵敏度。另外紫外吸收、非分散紫外线吸收、相关分光、二次导数、自调制光吸收法对NO、N O2 SO2、C H( CH4) 等气体具有较高的灵敏度。   
( 2 ) 光反应气体传感器:光反应气体传感器是利用气体反应产生色变引起光强度吸收等光学特性改变,传感元件是理想的,但是气体光感变化受到限制,传感器的自由度小。  

2.BMP085电路及特性简介

  如图4.2.2所示,为本次试验所用气压传感器BMP085的芯片控制引脚图。

这里写图片描述
图 4.2.2气压传感器引脚接线图
这里写图片描述
图4.2.3气压传感器的实物图。

这里写图片描述
图 4.2.4气压传感器实例简化电路图

  图4.2.5为气压传感器BMP085的组成原件的规格信息(如果没有另作规定,以下所给的值是在电压温度范围内的最大值)。

这里写图片描述
图4.2.5气压传感器BMP085参数信息表

  图4.2.6给出BMP085最大额定参数的信息。

这里写图片描述
图4.2.6BMP085最大额定参数

  BMP085作为新一代高精度气压传感器与SMD500的功能和引脚是完全兼容的。通用的SMD500/BMP085 C 代码(BMP085-SMD500-API)与SMD500也是兼容的,但是要注意器件ID。BMP085 的低功耗、低电压的电学特性使它可以很好的适用于手机、PDA、GPS 导航器 件以及户外装备上。BMP085 在低的高度噪声(merely 0.25)快速转换的情况下,表现很好。BMP085 是基于压阻效应技术的,具有稳定的电磁兼容性、高精度、线性性以及稳定性。 Bosch 公司的气压传感器(在自动控制应用领域)是世界市场上的领军,基于 200百万气压传感器的制造经验,BMP085继续了新一代的微型气压传感器。
  
  BMP085 包含电阻式压力传感器、AD 转换器、和控制单元,其中控制单元包括E2PROM 和 I2C 接口。BMP085 传送没有经过补偿的温度压力值。E2PROM 储存了 176位单独的标准数据,这些标准数据用于补偿、度依赖性和传感器其他的一些参数。UP=压力数据(16 to 19bit) UT=温度数据(0 to 15bit)
特别需要注意的是:BMP085 可以被独立的提供不同水平的 VDDA 和 VDDD 而 这在 SMD500 中不不可能的事。为了适应不同的电压水平,VDDA和VDDD 应该各接一个 100nF 的电容。

3.I2C总线

(1)I2C总线简介
  I2C 即Inter-Integrated Circuit(集成电路总线),这种总线类型是由飞利浦半导体公司在八十年代初设计出来的,主要是用来连接整体电路(ICS) ,I2C是一种多向控制总线,也就是说多个芯片可以连接到同一总线结构下,同时每个芯片都可以作为实施数据传输的控制源。这种方式简化了信号传输总线。I2C 总线用于控制器件,从 E2PROM 中读出校准数据以及当 AD 转换完成后读出测量 数据。
  
  随着大规模集成电路技术的发展,把CPU和一个单独工作系统所必需的ROM、RAM、I/O端口、A/D、D/A等外围电路集成在一个单片内而制成的单片机或微控制器愈来愈方便。目前,世界上许多公司生产单片机,品种很多。其中包括各种字长的CPU,各种容量的ROM、RAM以及功能各异的I/O接口电路等等,但是,单片机的品种规格仍然有限,所以只能选用某种单片机来进行扩展。扩展的方法有两种:一种是并行总线,另一种是串行总线。由于串行总线的连线少,结构简单,往往不用专门的母板和插座而直接用导线连接各个设备。因此,采用串行线可大大简化系统的硬件设计。PHILIPS公司早在十几年前就推出了I2C串行总线,利用该总线可实现多主机系统所需的裁决和高低速设备同步等功能。因此,这是一种高性能的串行总线。
  BMP085 有一个主清除信号(XCLR)——低电平输入,用来复位 BMP085 和初始化寄存器和控制器。器件可以通过上电复位电路(POR)自动的复位。XCLR(是器件上的一个复位引脚)在不用的情况下可以空置。

(2) I2C 接口说明书

  I2C 接口电气参数如下图所示

这里写图片描述
图4.2.7 I2C 接口电气参数

(3)器件和寄存器地址
  BMP085 模块的地址如下。器件地址的最低位 0 表示读,1 表示写,即器件地址为 0xEF 时表示读操作,器件地址为 0xEE 时表示写操作。
这里写图片描述
图4.2.8 BMP085 模块的地址如下

  这样很方便用一根 I2C 线对两个 BMP085 器件操作,你可以利用 XCLR(使能信号)使 能两个器件中的一个,二使另一个保持静默,这样就只对其中使能的那个器件进行操作 ,而 不会影响到另一个器件。

(4)I2C协议
  I2C接口协议是一个特殊总线信号协议。有 Start(S)(开始信号)、Stop(P)(结束信号)、 二进制数据三不分组成,如下图。开始时,SCL 高,SDA 下降沿。之后,发送从器件地址。 在 7 位的地址位之后,是控制读写位,选择读写操作,如上图。当从器件识别到与其对应的 地址信息后,将向主机发送一个应答信号——在第 9 个时钟周期拉低 SDA。在停止时,SCL 保持高电平,SDA 上升沿。

这里写图片描述
图4.2.9 I2C接口协议

4.使用过程

(1)数据转换
  开始温度值 UT 测量和开始压强值 UP 测量的时序图如下。在开始信号之后,主机发送 器件地址(写),寄存器地址和控制寄存器数据。 BMP085 没接收到八位数据就向主机发送 应答信号主机在收到最后一个应答信号后发送停止信号。

这里写图片描述
图4.2.10 BMP085)数据转换

  控制寄存器不同内部 oversampling-setting 的值如下图:同时,并不需要等待最大的转化时间之后再读取数据。可以利用器件的输出管脚 EOC(转换完毕信号)来检查转化是否完毕。逻辑 1 表示转换完成,逻辑 0 表示转换正在进行。 在转换完成后 BMP085 就自动切换到待命模式。
这里写图片描述
图4.2.11oversampling-setting 值

  同时,并不需要等待最大的转化时间之后再读取数据。可以利用器件的输出管脚 EOC (转换完毕信号)来检查转化是否完毕。逻辑 1 表示转换完成,逻辑 0 表示转换正在进行。 在转换完成后 BMP085 就自动切换到待命模式。
(2)读取 AD 转换器的结果和 E2PROM 中的数据
为了读出温度数据 UT(0-15bit)、压强数据(16-19bit)和 E2PROM 中的数据,操作步骤如下:
1) 在开始信号之后,主机发送模块的地址写命令和寄存器地址 。寄存器地址选择读寄存器:E2PROM 数据寄存器:0xAA—0xBF。温度或者压强值 UT 或 UP 0xF6(MSB) 0xF7(LSB)可选择 0xF8(XLSB)
2) 之后,主机发送从新开始信号,接着是器件读地址,然后收到从器件发来的应答信号。然后 BMP085 首先发送高 8 数据,主机收到数据后返回给 BMP085 一个应答信号,之后,BMP085 发送低 8 位数据。之后主机发送 not ack 信号和最后的停止信号。
3) 为了选择高分辨率,地址为 0xF8 的 XLSB 寄存器可以被读取,扩展 16 位数据到 19 位, 参考 Bosch 公司提供的 BMP085-SMD500-API 程序。

这里写图片描述
图4.2.12 读取 AD 转换器的结果和 E2PROM 中的数据

(3)测量温度和压力

  1. 微控制器发送开始信号开始温度或者压力测量,经过转换时间(4.5ms)器结果值可以通过 I2C 接口读出。为了将温度的单位换算成℃和将压力的单位换算成 hPa,E2PROM中的标准数据应该被使用。这些标准数据可以从BMP085中的 E2PROM 中通过 I2C 接口读出。(这些标准数据应该在初始化程序的时候就读出,方便后面的计算)采样速率最高可以提升128次每秒钟,用于那些动态测量。正是由于这样,温度测量的速度只能达到每秒一次,也就是说在同一个采样周期中可以采128次压力值和一次温度值,并且这些值在用完后就被刷新掉了。(PS:貌似是把 128 次压力值和一次温度值打成一 个包,当成一个整体用的意思。)通过选择不同的模式,可以在功耗、速度及分辨率之间协调。具体选择见下表。
  2. 噪音数据被计算为 10 个数据点的标准偏差。为了得到更多的有关噪声特点的信息,可以查 看相关具体应用的信息“在气压传感器应用中的噪声”。所有的模式可以在一个较高的速度下执行 ,例如,在传输速度为 128 次每秒的水平上, 电流消耗的增长与传输速度的增长成比例。这样噪声可以用软件的方法进一步降低。


    这里写图片描述
    图4.2.13噪声偏差

  3. 校准系数
      176 位的 E2PROM 被划分为 11 个字,每个字 16 位(11*16=176)。这样就包含了 11 个校准系数。每个器件模块都有自己单独的校准系数。在第一次计算温度压力数据之前,控制 器应该先读出读出 E2PROM 中的数据。(就是前面说的先读出校准数据,然后再开始采集数据)数据通信的准确性可以通过检查没有字的值是 0 和 0xFFFF 来确定。(PS:貌似意思是 E2PROM 中的值没有 0 和 0xFFFF,如果读出这些值就是错的)


    这里写图片描述
    图4.2.14标准系数

  4. 计算压力和温度
      低功耗,水平,高度,高分辨率可以通过 oversampling_setting(0,1,2,3) C 语言程序来选择。通用 SMD500/BMP085 代码可以很好的兼容 SMD500 和自动识别出器件 ID。因此, SMD500 可以被 BMP085 代替,而不用改变软硬件设计。Calculation of true temperature and pressure in step of 1Pa and temperature in step of 0.1℃(计算真实的温度和压强)下面的表格展示了详细的关于温度压强测量的算法。这个算法的 c 代码顾客可以通过购买 Bosch 公司提供的 BMP085-SMD500-api 来获得。 具体算法见英文文档第 12 页。
    这里写图片描述
    图4.2.15算法流程图
  5. 计算绝度高度
      用测量的大气压强 P 和海平面大气压强 Po 来计算当地海拔高度 。(例如,当地大气 压 1013.25hPa)海拔高度以米为单位,可以用下面的公式计算出来。
    这里写图片描述

      就是说,大气压强每改变 1hPa,海拔高度增加 8.43m。 3.7 计算海平面处的大气压强。已知测量出来的当地大气压强和当地绝对海拔高度可以计算出海平面出的大气压强。因此,海拔高度每变化 10m 大气压强变化 1.2hPa。公式如下:
    这里写图片描述

四、实验内容

1.实验器材连线
本实验所使用的振动传感器实物图如图4.1.7所示。

这里写图片描述
图4.1.7振动传感器模块

将振动传感模块安装到开发板上,然后用JLINK仿真器的一端用USB接口与电脑相连,一端的20Pin的JTAG引脚与NXP LPC2378节点板的J2相连,并给NXP LPC2378节点板上电,如图4.1.8所示。
这里写图片描述
图4.1.8 振动传感器模块电路接口

2.气压传感器运行测试
(1) 打开工程Shake.mcp,编辑主程序文件Main.c。

uint8 sndBuf[30];
    short AC1,AC2,AC3;
    unsigned short AC4,AC5,AC6;
    short B1,B2;
    short MB,MC,MD;
    long UT,UP;
    long X1,X2,X3,T,tmp,tmp2;
    long B3,B5,B6,B7;
    unsigned long B4;
    long p;
    short oss;
    //I2C初始化
    I2C_Init(10000); // I2C配置及端口初始化
    IRQEnable();                             
//设置LCD屏幕引脚   
    PINSEL3=PINSEL3 & 0x00000000;
    IO1DIR=IO1DIR|0x05700000;
//屏幕初始化    
    RESET0;     //复位                           
    delay(50);
    RESET1;                     
    delay(100); 
    lcd_init();
    delay(20);
    LCD_Frame();



    DispAscStr(0,12,"Pressure",8,&xpos,&ypos);
    DispChnStr(xpos,ypos,"模块测试",4,&xpos,&ypos);

    //读出E2PROM中的校准数据
    //从0地址开始存放,一共读取22个字节
    //见器件和寄存器地址,oxee为写操作,oxef为读操作
    I2C_ReadNByte(0xee,1,0xaa,&sndBuf[0],22);
    //以下过程完成
    /*
    AC1(0xAA,0XAB)  (16BIT)
    AC2(0xAC,0XAD)  (16BIT)
    AC3(0xAE,0XAF)  (16BIT)
    AC4(0xB0,0XB1)  (16BIT)
    AC5(0xB2,0XB3)  (16BIT)
    AC6(0xB4,0XB5)  (16BIT)
    B1(0xB6,0XB7)   (16BIT)
    B2(0xBB,0XB9)   (16BIT)
    MB(0xBA,0XBB)   (16BIT)
    MC(0xBC,0XBD)   (16BIT)
    MD(0xBE,0XBF)   (16BIT)
    */
    AC1=sndBuf[0]<<8;
    AC1+=sndBuf[1];
    AC2=sndBuf[2]<<8;
    AC2+=sndBuf[3];
    AC3=sndBuf[4]<<8;
    AC3+=sndBuf[5];
    AC4=sndBuf[6]<<8;
    AC4+=sndBuf[7];
    AC5=sndBuf[8]<<8;
    AC5+=sndBuf[9];
    AC6=sndBuf[10]<<8;
    AC6+=sndBuf[11];

    B1=sndBuf[12]<<8;
    B1+=sndBuf[13];
    B2=sndBuf[14]<<8;
    B2+=sndBuf[15];
    MB=sndBuf[16]<<8;
    MB+=sndBuf[17];
    MC=sndBuf[18]<<8;
    MC+=sndBuf[19];
    MD=sndBuf[20]<<8;
    MD+=sndBuf[21];

    delay(1000);

    while(1)
    {
         /*
            以下步骤完成如下工作:
            //读未补偿的温度值
            //(write 0x2e into reg 0xf4,wait 4.5ms)
            读取温度,需要向控制寄存器0xf4中写入0x2e,
            还需要等待4.5ms以上
            read red 0xf6(MSB),0xf7(LSB)
            UT=MSB << 8 + LSB
         */

        sndBuf[0]=0x2E;
        I2C_WriteNByte(0xee,1,0xF4,&sndBuf[0],1);
        delay(1000);

        //才可以从Oxf6或者0xf7中读取转换后的16位温度数据
        I2C_ReadNByte(0xee,1,0xF6,&sndBuf[0],2);
        UT=sndBuf[0]<<8;
        UT+=sndBuf[1];

        /*
         读未补偿的压力值
         需要向0xfe中写入0x34,延时至少4.5ms
         write 0x34+(oss<<6) into reg 0xf4,wait 4.5ms
         then read reg 0xf6(MSB),0XF7(LSB),0XF8(XLSB)
         UP=(MSB<<16+LSB<<8+XLSB)>>(8-0ss)
        */
        oss=0;
        sndBuf[0]=0x34;
        sndBuf[0]+=oss<<6;
        I2C_WriteNByte(0xee,1,0xF4,&sndBuf[0],1);
        delay(1000);
        //再从0xf6或者0xf7中读取16位的气压信息
        I2C_ReadNByte(0xee,1,0xF6,&sndBuf[0],3);
        UP=sndBuf[0]<<16;
        UP+=sndBuf[1]<<8;
        UP+=sndBuf[2];
        UP=UP>>(8-oss);

        /*计算实际温度值

            X1=(UT-AC6)*AC5/2^15;
            X2=MC*2^11/(X1+MD)
            B5=X1+X2
            T=(B5+8)/2^4
        */
        X1=UT-AC6;
        X1*=AC5;
        tmp=pow(2,15);
        X1/=tmp;

        //X2=MC*2^11/(X1+MD);
        X2=MC;
        tmp=pow(2,11);
        X2*=tmp;
        X2/=(X1+MD);

        B5=X1+X2;
        //T=(B5+8)/2^4;
        T=B5+8;
        tmp=pow(2,4);
        T/=tmp;

        /*计算实际压力值
            B6=B5-4000
            X1=(B2*(B6*B6/2^12))/2^11
            X3=X1+X2
            B3=((AC1*4+X3)<<0ss+2)/4
            X1=AC3*B6/2^13
            X2=(B1*(B6*B6/2^12))/2^16
            X3=((X1+X2)+2)/2^12
            B4=AC4*(unsigned long)(x3+32768)/2^15
            B7=((unsigned long)UP-B3)*(50000>>oss)
            IF(B7<0X80000000){P=(B7*2)/B4}
            ELSE  {P=(B7/B4)*2}
            X1=(P/2^8)*(P/2^8)
            X1=(X1*3038)/2^16
            X2=(-7357*P)/2^16
            P=P+(X1+X2+3791)/2^4
         */
        B6=B5-4000;
        tmp=pow(2,12);
        tmp2=pow(2,11);
        X1=(B2*(B6*B6/tmp))/tmp2;
        tmp=pow(2,11);
        X2=AC2;
        X2=(X2&0x0000ffff);
        X2*=B6;
        X2/=tmp;
        X3=X1+X2;
        //B3=((AC1*4+X3)<<oss+2)/4;
        B3=(AC1*4+X3)<<oss;
        B3+=2;
        B3/=4;

        tmp=pow(2,13);
        X1=AC3;
        X1=(X1&0x0000ffff);
        X1*=B6;
        X1/=tmp;
        tmp=pow(2,12);
        tmp2=pow(2,16);
        X2=(B1*(B6*B6/tmp))/tmp2;
        X3=((X1+X2)+2)/(2*2);
        tmp=pow(2,15);
        B4=AC4*(unsigned long)(X3+32768)/tmp;
        //B7=((unsigned long)UP-B3)*(50000>>oss);
        B7=50000>>oss;
        B7*=((unsigned long)UP-B3);
        if(B7<0x80000000)
        {
            //p=(B7*2)/B4;
            p=B7;
            //p=p&0x0000ffff;
            p*=2;
            p/=B4;

        }
        else
        {
            //p=(B7/B4)*2;
            p=B7;
            //p=p&0x0000FFFF;
            p/=B4;
            p*=2;
        }
        tmp=pow(2,8);
        X1=(p/tmp)*(p/tmp);
        tmp2=pow(2,16);
        X1=(X1*3038)/tmp2;
        X2=(-7357*p)/tmp2;
        tmp=pow(2,4);
        p=p+(X1+X2+3791)/tmp;

        /*
            以下过程为将获得的温度和压力转换为显示屏输出
        */

        //输出温度***.***
        sndBuf[10]=T/100+'0';
        sndBuf[11]=T%100/10+'0';
        sndBuf[12]='.';
        sndBuf[13]=T%10+'0';
        DispAscStr(0,40,&sndBuf[10],4,&xpos,&ypos);
        //输出压力***.**kpa(千帕斯卡)
        sndBuf[9]=p/100000+'0';
        sndBuf[10]=p%100000/10000+'0';
        sndBuf[11]=p%10000/1000+'0';
        sndBuf[12]='.';
        sndBuf[13]=p%1000/100+'0';
        sndBuf[14]=p%100/10+'0';
        sndBuf[15]=p%10+'0';
        sndBuf[16]='k';
        sndBuf[17]='P';
        sndBuf[18]='a';
        DispAscStr(0,100,&sndBuf[9],10,&xpos,&ypos);
        delay(2000);
    }

(2) 温度监控试验.
试验内容是当温度超过25度时,显示”temp high”。修改main.c中while ( 1){}如下面代码区所示。

  while(1)
    {
        sndBuf[0]=0x2E;
        I2C_WriteNByte(0xee,1,0xF4,&sndBuf[0],1);
        delay(1000);
        //才可以从Oxf6或者0xf7中读取转换后的16位温度数据
        I2C_ReadNByte(0xee,1,0xF6,&sndBuf[0],2);
        UT=sndBuf[0]<<8;
        UT+=sndBuf[1];
        X1=UT-AC6;
        X1*=AC5;
        tmp=pow(2,15);
        X1/=tmp;

        //X2=MC*2^11/(X1+MD);
        X2=MC;
        tmp=pow(2,11);
        X2*=tmp;
        X2/=(X1+MD);

        B5=X1+X2;
        //T=(B5+8)/2^4;
        T=B5+8;
        tmp=pow(2,4);
        T/=tmp;
        //输出温度***.***
        sndBuf[10]=T/100+'0';
        sndBuf[11]=T%100/10+'0';
        sndBuf[12]='.';
        sndBuf[13]=T%10+'0';
        DispAscStr(0,40,&sndBuf[10],4,&xpos,&ypos);
        if(T>250)
              DispAscStr(0,100,"temp high",9,&xpos,&ypos);
        delay(2000);
    }

(3) 气压监控试验.
试验内容是当温度超过25度时,显示”temp high”。修改main.c中while ( 1){}如下面代码区所示。

while(1)
    {
        oss=0;
        sndBuf[0]=0x34;
        sndBuf[0]+=oss<<6;
        I2C_WriteNByte(0xee,1,0xF4,&sndBuf[0],1);
        delay(1000);
        //再从0xf6或者0xf7中读取16位的气压信息
        I2C_ReadNByte(0xee,1,0xF6,&sndBuf[0],3);
        UP=sndBuf[0]<<16;
        UP+=sndBuf[1]<<8;
        UP+=sndBuf[2];
        UP=UP>>(8-oss);
        B6=B5-4000;
        tmp=pow(2,12);
        tmp2=pow(2,11);
        X1=(B2*(B6*B6/tmp))/tmp2;
        tmp=pow(2,11);
        X2=AC2;
        X2=(X2&0x0000ffff);
        X2*=B6;
        X2/=tmp;
        X3=X1+X2;
        //B3=((AC1*4+X3)<<oss+2)/4;
        B3=(AC1*4+X3)<<oss;
        B3+=2;
        B3/=4;

        tmp=pow(2,13);
        X1=AC3;
        X1=(X1&0x0000ffff);
        X1*=B6;
        X1/=tmp;
        tmp=pow(2,12);
        tmp2=pow(2,16);
        X2=(B1*(B6*B6/tmp))/tmp2;
        X3=((X1+X2)+2)/(2*2);
        tmp=pow(2,15);
        B4=AC4*(unsigned long)(X3+32768)/tmp;
        //B7=((unsigned long)UP-B3)*(50000>>oss);
        B7=50000>>oss;
        B7*=((unsigned long)UP-B3);
        if(B7<0x80000000)
        {
            //p=(B7*2)/B4;
            p=B7;
            //p=p&0x0000ffff;
            p*=2;
            p/=B4;

        }
        else
        {
            //p=(B7/B4)*2;
            p=B7;
            //p=p&0x0000FFFF;
            p/=B4;
            p*=2;
        }
        tmp=pow(2,8);
        X1=(p/tmp)*(p/tmp);
        tmp2=pow(2,16);
        X1=(X1*3038)/tmp2;
        X2=(-7357*p)/tmp2;
        tmp=pow(2,4);
        p=p+(X1+X2+3791)/tmp;
        //输出压力***.**kpa(千帕斯卡) 
        sndBuf[9]=p/100000+'0';
        sndBuf[10]=p%100000/10000+'0';
        sndBuf[11]=p%10000/1000+'0';
        sndBuf[12]='.';
        sndBuf[13]=p%1000/100+'0';
        sndBuf[14]=p%100/10+'0';
        sndBuf[15]=p%10+'0';
        sndBuf[16]='k';
        sndBuf[17]='P';
        sndBuf[18]='a';
        DispAscStr(0,100,&sndBuf[9],10,&xpos,&ypos);
        //当气压超过80 KPA提示气压过高
         if(p>80000)
              DispAscStr(0,120,"press high",10,&xpos,&ypos);
        delay(2000);
    }
五、实验思考

1.怎样才能启动I2C总线并读取EEPROM中的内容?
2.怎样实现当温度或者气压低于某个值时或者气压和温度同时满足某个条件时发出警 告?
3.气压传感器有什么应用?

原文地址:https://www.cnblogs.com/shugen/p/6863017.html