bmp085要点Word文档下载推荐.docx
《bmp085要点Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《bmp085要点Word文档下载推荐.docx(12页珍藏版)》请在冰豆网上搜索。
同样,要获得气压数据,必须先向控制寄存器(地址0xF4)写0x34,然后等待至少4.5ms,才可以从地址0xF6和0xF7读取16位的气压数据,若要扩展分辨率,还可继续读取0xF8(XLSB)扩展16位数据到19位。
获取到的数据还要根据EEPROM中的校准数据来进行补偿后才能用,EEPROM的数据读取可根据上图中的地址来进行,地址从0xAA~0xBF,具体的补偿算法可参看官方的数据手册,这里就不赘述了。
下面以一个例子来看一下BMP085的具体应用。
例子:
利用单片机读取来自BMP085的温度和气压数据,并把它们通过LCD1602显示出来。
BMP085的SDA、SCL端分别接到ATMega16的TWI端(PC1、PC0),EOC和XCLR端悬空,LCD1602的接法与前面的一致。
参考代码如下。
#include<
iom16.h>
//=========================定义从器件地址和读写方式=============================
#definerd_device_add0xef//即11101111,1110111是BMP085器件的固定地址,最后的1表示对从器件进行读操作
#definewr_device_add0xee//即11101110,1110111是BMP085器件的固定地址,最后的0表示对从器件时行写操作
//===============================TWI状态定义==================================
#defineSTART0x08
#defineRE_START0x10
#defineMT_SLA_ACK0x18
#defineMT_SLA_NOACK0x20
#defineMT_DATA_ACK0x28
#defineMT_DATA_NOACK0x30
#defineMR_SLA_ACK0x40
#defineMR_SLA_NOACK0x48
#defineMR_DATA_ACK0x50
#defineMR_DATA_NOACK0x58
//=============================常用TWI操作定义================================
#defineStart()(TWCR=(1<
<
TWINT)|(1<
TWSTA)|(1<
TWEN))
#defineStop()(TWCR=(1<
TWSTO)|(1<
#defineWait(){while(!
(TWCR&
(1<
TWINT)));
}
#defineTestAck()(TWSR&
0xf8)
#defineSetAck()(TWCR|=(1<
TWEA))
#defineSetNoAck()(TWCR&
=~(1<
#defineTwi()(TWCR=(1<
#defineWrite8Bit(x){TWDR=(x);
TWCR=(1<
TWEN);
//============引脚电平的宏定义===============
#defineLCM_RS_1PORTB_Bit0=1//RS脚输出高电平
#defineLCM_RS_0PORTB_Bit0=0//RS脚输出低电平
#defineLCM_RW_1PORTB_Bit1=1//RW脚输出高电平
#defineLCM_RW_0PORTB_Bit1=0//RW脚输出低电平
#defineLCM_EN_1PORTB_Bit2=1//EN脚输出高电平
#defineLCM_EN_0PORTB_Bit2=0//EN脚输出低电平
#defineDataPortPORTA//PORTA为数据端口
#defineBusy0x80//忙信号
//==============定义全局变量================
unsignedcharge,shi,bai,qian,wan,shiwan;
//显示变量
unsignedcharReadTemp[2];
//接收到的温度数据缓冲区
unsignedcharReadPressure[2];
//接收到的气压数据缓冲区
intac1;
intac2;
intac3;
unsignedintac4;
unsignedintac5;
unsignedintac6;
intb1;
intb2;
intmb;
intmc;
intmd;
//==============定义显示字符串================
constunsignedcharstr0[]={"
T:
.C"
};
//显示温度
constunsignedcharstr1[]={"
P:
.Kpa"
//显示气压
//===============1mS延时===================
voiddelay_1ms(void)
{
unsignedinti;
for(i=1;
i<
(unsignedint)(8*143-2);
i++)
;
//=============n*1mS延时===============
voiddelay_nms(unsignedintn)
{
unsignedinti=0;
while(i<
n)
{delay_1ms();
i++;
}
//===============IIC总线写n个字节(成功返回0,失败返回1)=====================
unsignedcharI2C_Write(unsignedcharRomAddress,unsignedchar*buf,unsignedcharlen)
unsignedchari;
Start();
//启动I2C总线
Wait();
//等待回应
if(TestAck()!
=START)
return1;
//若回应的不是启动信号,则失败返回1
Write8Bit(wr_device_add);
//写I2C从器件地址、写方向
=MT_SLA_ACK)
//若回应的不是ACK信号,则失败返回值1
Write8Bit(RomAddress);
//写BMP085的ROM地址
=MT_DATA_ACK)
//若回应的不是ACK信号则失败返回值1
for(i=0;
len;
{
Write8Bit(buf[i]);
//写数据到BMP085的ROM中
{return1;
}//若回应的不是ACK信号则失败返回值1
delay_nms(10);
Stop();
//停止I2C总线
//延时等待BMP085写完
return0;
//写入成功,返回值0
//====================IIC总线读n个字节(成功返回0,失败返回1)=========================
unsignedcharI2C_Read(unsignedcharRomAddress,unsignedchar*buf,unsignedcharlen)
=START)
=MT_SLA_ACK)
//若回应的不是ACK信号,则失败返回值1
//重新启动I2C总线
=RE_START)
//若回应的不是重复启动信号,则失败返回1
Write8Bit(rd_device_add);
//写I2C从器件地址、读方向
=MR_SLA_ACK)
Twi();
//启动I2C读方式
SetAck();
//设置接收自动应答
*(buf+i)=TWDR;
//把连续读取的len个字节数据依次存入对应的地址单元(数组)中
SetNoAck();
//读数据的最后一位后紧跟的是无应答
//成功返回值0
//================检测LCD忙信号子函数================
voidWaitForEnable(void)
unsignedcharval;
DataPort=0xff;
//数据线电平拉高
LCM_RS_0;
//选择指令寄存器
LCM_RW_1;
//选择写方式
__asm("
NOP"
);
//调用汇编指令延时一个空指令周期,等待稳定
LCM_EN_1;
//使能端拉高电平
//调用汇编指令延时两个空指令周期,等待稳定
DDRA=0x00;
//改变数据线方向成输入
val=PINA;
//读取数据
while(val&
Busy)
//当DB7位为1时表示忙,循环检测
LCM_EN_0;
//忙信号结束,拉低使能端电平
DDRA=0xff;
//改变数据线方向成输出
//================写数据到LCD子函数=================
voidLcdWriteData(unsignedchardataW)//写数据dataW到LCD中
WaitForEnable();
//检测忙信号
LCM_RS_1;
//选择数据寄存器
LCM_RW_0;
//选择读方式
DataPort=dataW;
//把显示数据送到数据线上
//拉低使能端,执行写入动作
//================写命令到LCD子函数================
voidLcdWriteCommand(unsignedcharCMD,unsignedcharAttribc)//写命令CMD到LCD中,Arribc为1时检测忙信号,否则不检测
if(Attribc)
DataPort=CMD;
//把命令数据送到数据线上
//调用汇编指令延时一个空指令周期,等待稳定
//================显示光标定位子函数================
voidLocateXY(charposx,charposy)//定位位置到地址x列y行
unsignedchartemp;
temp=posx&
0x0f;
//屏蔽高4位,限定x坐标的范围为0~15
posy&
=0x01;
//屏蔽高7位,限定y坐标的范围为0~1
if(posy)
temp|=0x40;
//若要显示的是第二行,则地址码+0x40,因为第二行起始地址为0x40
temp|=0x80;
//指令码为地址码+0x80,因为写DDRAM时DB7恒为1(即0x80)
LcdWriteCommand(temp,1);
//把temp写入LCD中,检测忙信号
//===========显示指定座标的一个字符子函数============
voidDisplayOneChar(unsignedcharx,unsignedchary,unsignedcharWdata)//在x列y行处显示变量Wdata中的一个字符
LocateXY(x,y);
//定位要显示的位置
LcdWriteData(Wdata);
//将要显示的数据Wdata写入LCD
//==========显示指定座标的一串字符子函数===========
voidePutstr(unsignedcharx,unsignedchary,unsignedcharconst*ptr)//在x列y行处显示ptr指向的字符串
unsignedchari,j=0;
while(ptr[j]>
31)
j++;
//ptr[j]>
31时为ASCII码,j累加,计算出字符串长度
j;
DisplayOneChar(x++,y,ptr[i]);
//显示单个字符,同时x坐标递增
if(x==16)
x=0;
y^=1;
//当每行显示超过16个字符时换行继续显示
//==================LCD初始化子函数==================
voidInitLcd(void)
LcdWriteCommand(0x38,0);
//8位数据方式,双行显示,5X7字形,不检测忙信号
delay_nms(5);
//延时5ms
//重复三次
LcdWriteCommand(0x38,1);
//8位数据方式,双行显示,5X7字形,检测忙信号
LcdWriteCommand(0x08,1);
//关闭显示,检测忙信号
LcdWriteCommand(0x01,1);
//清屏,检测忙信号
LcdWriteCommand(0x06,1);
//显示光标右移设置,检测忙信号
LcdWriteCommand(0x0C,1);
//打开显示,光标不显示,不闪烁,检测忙信号
//==================转换子函数====================
voidconversion(longtemp_data)
shiwan=temp_data/100000+0x30;
temp_data=temp_data%100000;
//取余运算
wan=temp_data/10000+0x30;
temp_data=temp_data%10000;
//取余运算
qian=temp_data/1000+0x30;
temp_data=temp_data%1000;
bai=temp_data/100+0x30;
temp_data=temp_data%100;
shi=temp_data/10+0x30;
temp_data=temp_data%10;
ge=temp_data+0x30;
//===================BMP085读温度=====================
voidbmp085ReadTemp(void)
unsignedchart=0x2e;
I2C_Write(0xf4,&
t,1);
//向地址0xf4写0x2e,进行温度转换
//延时大于4.5ms
I2C_Read(0xf6,ReadTemp,2);
//从地址0xf6开始读出温度数据并存到数组ReadTemp中,共2个字节
//===================BMP085读气压=====================
voidbmp085ReadPressure(void)
unsignedchart=0x34;
//向地址0xf4写0x34,进行第一次气压转换
I2C_Read(0xf6,ReadPressure,2);
//从地址0xf6开始读出气压数据并存到数组ReadPressure中,共2个字节
//==================初始化BMP085====================
voidInit_BMP085(void)
unsignedchartemp[2];
I2C_Read(0xaa,temp,2);
ac1=(temp[0]<
8)|temp[1];
I2C_Read(0xac,temp,2);
ac2=(temp[0]<
I2C_Read(0xae,temp,2);
ac3=(temp[0]<
I2C_Read(0xb0,temp,2);
ac4=(temp[0]<
I2C_Read(0xb2,temp,2);
ac5=(temp[0]<
I2C_Read(0xb4,temp,2);
ac6=(temp[0]<
I2C_Read(0xb6,temp,2);
b1=(temp[0]<
I2C_Read(0xb8,temp,2);
b2=(temp[0]<
I2C_Read(0xba,temp,2);
mb=(temp[0]<
I2C_Read(0xbc,temp,2);
mc=(temp[0]<
8)|temp[1]