N76E003 BMP180
N76E003 BMP180N76E003 BMP180
N76E003 BMP180
BMP180.C文件

#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
#include "bmp180.h"


#include  <math.h>    //Keil library  
#include  <stdlib.h>  //Keil library  
#include  <stdio.h>   //Keil library	
#include  <INTRINS.H> //Keil library 

#define   uchar unsigned char
#define   uint unsigned int	


#define	BMP085_SlaveAddress   0xee	  //定义器件在IIC总线中的从地址                               
#define OSS 0	// Oversampling Setting (note: code is not set up to use other OSS values)



long  temperature;//温度值
long  pressure;		//压力值
long  height;			//相对海拔高度值
	
int  dis_data;                         

short ac1;
short ac2; 
short ac3; 
unsigned short ac4;
unsigned short ac5;
unsigned short ac6;
short b1; 
short b2;
short mb;
short mc;
short md;



void Delay5us() //5us延时(不怎么准)
{
    nop;
 nop; nop; nop; nop; nop; nop; nop; nop;
	    nop;
 nop; nop; nop; nop; nop; nop; nop; nop;
	    nop;
 nop; nop; nop; nop; nop; nop; nop; nop;
	    nop;
 nop; nop; nop; nop; nop; nop; nop; nop;
	    nop;
 nop; nop; nop; nop; nop; nop; nop; nop;
	
}

/**************************************
起始信号
**************************************/
void BMP085_Start()
{
    SDA = 1;                    //拉高数据线
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    SDA = 0;                    //产生下降沿
    Delay5us();                 //延时
    SCL = 0;                    //拉低时钟线
}

///**************************************
//停止信号
//**************************************/
void BMP085_Stop()
{
    SDA = 0;                    //拉低数据线
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    SDA = 1;                    //产生上升沿
    Delay5us();                 //延时
}

///**************************************
//发送应答信号
//入口参数:ack (0:ACK 1:NAK)
//**************************************/
void BMP085_SendACK(bit ack)
{
    SDA = ack;                  //写应答信号
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    SCL = 0;                    //拉低时钟线
    Delay5us();                 //延时
}

///**************************************
//接收应答信号
//**************************************/
bit BMP085_RecvACK()
{
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    CY = SDA;                   //读应答信号
    SCL = 0;                    //拉低时钟线
    Delay5us();                 //延时

    return CY;
}

///**************************************
//向IIC总线发送一个字节数据
//**************************************/
void BMP085_SendByte(unsigned char dat)
{
    unsigned char i;

    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;              //移出数据的最高位
        SDA = CY;               //送数据口
        SCL = 1;                //拉高时钟线
        Delay5us();             //延时
        SCL = 0;                //拉低时钟线
        Delay5us();             //延时
    }
    BMP085_RecvACK();
}

///**************************************
//从IIC总线接收一个字节数据
//**************************************/
unsigned char BMP085_RecvByte()
{
    unsigned char i;
    unsigned char dat = 0;

    SDA = 1;                    //使能内部上拉,准备读取数据,
    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;
        SCL = 1;                //拉高时钟线
        Delay5us();             //延时
        dat |= SDA;             //读数据               
        SCL = 0;                //拉低时钟线
        Delay5us();             //延时
    }
    return dat;
}


////*********************************************************
////读出BMP085内部数据,连续两个
////*********************************************************
short Multiple_read(uchar ST_Address)
{   
	uchar msb, lsb;
	short _data;
    BMP085_Start();                          //起始信号
    BMP085_SendByte(BMP085_SlaveAddress);    //发送设备地址+写信号
    BMP085_SendByte(ST_Address);             //发送存储单元地址
    BMP085_Start();                          //起始信号
    BMP085_SendByte(BMP085_SlaveAddress+1);         //发送设备地址+读信号

    msb = BMP085_RecvByte();                 //BUF[0]存储
    BMP085_SendACK(0);                       //回应ACK
    lsb = BMP085_RecvByte();     
		BMP085_SendACK(1);                       //最后一个数据需要回NOACK

    BMP085_Stop();                           //停止信号
    Timer0_Delay1ms(5);
    _data = msb << 8;
		_data |= lsb;	
	return _data;
}
////********************************************************************
//读函数数据
//**********************************************************************
long bmp085ReadTemp(void)
{
    BMP085_Start();                  //起始信号
    BMP085_SendByte(BMP085_SlaveAddress);   //发送设备地址+写信号
    BMP085_SendByte(0xF4);	          // write register address
    BMP085_SendByte(0x2E);       	// write register data for temp
    BMP085_Stop();                   //发送停止信号
		Timer0_Delay1ms(10);	// max time is 4.5ms	
		return (long) Multiple_read(0xF6);
}
////*************************************************************
//读气压数据
//**************************************************************
long bmp085ReadPressure(void)
{
	long pressure = 0;

    BMP085_Start();                   //起始信号
    BMP085_SendByte(BMP085_SlaveAddress);   //发送设备地址+写信号
    BMP085_SendByte(0xF4);	          // write register address
    BMP085_SendByte(0x34);       	  // write register data for pressure
    BMP085_Stop();                    //发送停止信号
	  Timer0_Delay1ms(10);	                  // max time is 4.5ms
	
	pressure = Multiple_read(0xF6);
	pressure &= 0x0000FFFF;
	
	return pressure;	
}

////**************************************************************

////初始化BMP180,根据需要请参考pdf进行修改**************
void Init_BMP085()
{
	ac1 = Multiple_read(0xAA);
	ac2 = Multiple_read(0xAC);
	ac3 = Multiple_read(0xAE);
	ac4 = Multiple_read(0xB0);
	ac5 = Multiple_read(0xB2);
	ac6 = Multiple_read(0xB4);
	b1 =  Multiple_read(0xB6);
	b2 =  Multiple_read(0xB8);
	mb =  Multiple_read(0xBA);
	mc =  Multiple_read(0xBC);
	md =  Multiple_read(0xBE);
}

////*****************************************************
//数据转换函数
//*******************************************************
void bmp085Convert()
{
	unsigned int ut;
	unsigned long up,b4, b7;
	long x1, x2,x3; 
	long b5,b6,b3;
	long p;

	
	ut = bmp085ReadTemp();	   // 读取温度
	up = bmp085ReadPressure();  // 读取压强
	x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
	x2 = ((long) mc << 11) / (x1 + md);
	b5 = x1 + x2;
	temperature = ((b5 + 8) >> 4);

  b6 = b5 - 4000;
  // Calculate B3
  x1 = (b2 * (b6 * b6)>>12)>>11;
  x2 = (ac2 * b6)>>11;
  x3 = x1 + x2;
  b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
  
  // Calculate B4
  x1 = (ac3 * b6)>>13;
  x2 = (b1 * ((b6 * b6)>>12))>>16;
  x3 = ((x1 + x2) + 2)>>2;
  b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
  
  b7 = ((unsigned long)(up - b3) * (50000>>OSS));
  if (b7 < 0x80000000)
    p = (b7<<1)/b4;
  else
    p = (b7/b4)<<1;
    
  x1 = (p>>8) * (p>>8);
  x1 = (x1 * 3038)>>16;
  x2 = (-7357 * p)>>16;
 pressure = p+((x1 + x2 + 3791)>>4);
	
	height=(101325-pressure)*9;//转化得到绝对高度
}

以下是BMP180的头文件

#ifndef _bmp180_h_
#define _bmp180_h_


extern	long  temperature;
extern 	long  pressure;
extern  long  height;

void Init_BMP085();//初始化BMP180
void bmp085Convert();//数据转换

#endif

主程序——通过串口0发送温度与气压数据
(PS:定时器1不要再BMP180中使用,会造成串口1无法使用)

#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
#include "BMP180.h"

#define uint unsigned int
#define uchar unsigned  char

uchar abc[14];

void main (void)
{
	int i; 
 	Set_All_GPIO_Quasi_Mode;
	LED=1;
	set_P06;//初始化串口1管脚
    set_P07;   
	
//----------串口1、串口0配置----------------   
    	InitialUART0_Timer1(9600);
		EA = 1;		//开启总中断
		while(1)
		{
						Init_BMP085();//初始化BMP180
						bmp085Convert();//数据转换
						abc[3]=0x54;//字符“T”
						abc[4]=temperature/100+48;
						abc[5]=temperature%100/10+48;
						abc[6]=0x2e;//字符“.”
						abc[7]=temperature%10+48;
						
						abc[8]=0x50;//P
						abc[9]=pressure/10000+48;
						abc[10]=pressure%10000/1000+48;
						abc[11]=pressure%1000/100+48;
						for(i=3;i<12;i++)
						{
							Send_Data_To_UART0(abc[i]);//发送温度与气压
						}		
		}
	}

N76E003 BMP180
因为我的程序是进入低功耗模式,每小时自动唤醒一次,进行测量,所以前面还有湿度数据,请自动忽略。(经测量温度数据与DHT11接近,气压数据小米3自带的气压计接近)

PS:keil编译器记得将内存模式调到Large,否则在数据转换时的long型数据可能会报错。
N76E003 BMP180

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-28
  • 2021-11-28
猜你喜欢
  • 2021-05-10
  • 2021-10-19
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-12
  • 2022-01-21
相关资源
相似解决方案