來到本文章,相信您對BMP180的使用存在某些疑惑,或者想要學習使用BMP180,或許本文将幫助您完成對BMP180的學習和控制!
BMP180可以用來幹什麼?
長話短說,通過閱讀手冊我們知道BMP180可以為我們提供溫度和氣壓資料的測量與檢測,通過對氣壓資料的進一步加工,可以計算出海拔高度資訊。
BMP180該怎麼用?
BMP180做為一個獨立的晶片,能夠為我們提供氣壓和溫度資訊的測量。對于任何一個獨立的子產品,我們可以将它想象成一個黑盒,可以為我們提供一些資訊,而不需要考慮其内部是怎麼實作的,隻需要和它進行溝通(通信)即可獲得我們想要知道的東西。
-
如何與BMP180取得聯系?
作為一個人,我們想要彼此之間的想法,語言是溝通的管道,内容就是載體。比如國語便是語言的一種規範。但不同地區的人存在不同的方言,發音用詞都有所差異,但是隻要彼此都承認這種規範(常常說聽得懂彼此的話),便可以取得有效的溝通,到達交換資訊的目的。而想要與BMP180取得聯系,我就必須遵循IIc通訊協定(一個隻能了解IIc得小家夥),是以IIc通訊協定便是與BMP180溝通的規範。接下來讓我們來看一看什麼是IIc通訊協定!
-
讓我們來看看什麼是IIc通訊協定!
IIc是通訊協定是基于IIc總線的通訊規範,總線包括兩根雙向信号線,一根是資料線(SDA),一根是時鐘線(SCL ),在總線上可以挂接多個裝置,利用裝置位址的方式來識别不同的器件。那麼請你記住:BMP180在這個總線上的位址是0xEE。依據IIc通訊協定所規定的時序,一位一位将資料傳送完畢。如果你還沒有接觸過IIc通訊協定,可以參考有關IIc的文檔進行學習,以下是IIc通訊協定的詳細介紹。
https://www.nxp.com.cn/docs/en/user-guide/UM10204.pdf
-
讓我們用51單片機實作軟體模拟IIc進行通訊
我們使用子產品化程式設計的思想實作對BMP180的驅動,請大概閱讀實作IIc的頭檔案,你不用完全了解每一行代碼的意思,能夠利用頭檔案提供的四個函數進行基本的通訊即可。
/***********************************************************
本程式實作了軟體模拟IIC通訊,資料傳送時,先傳送最高位(MSB)
每一個被傳送的位元組後面都必須跟随一位應答位(即一幀共有9位)
作者聯系方式:1932857334 By QQ
***********************************************************/
#ifndef _IIC_INCLUDE_H_
#define _IIC_INCLUDE_H_
/* 引用51标準頭檔案 */
#include <reg52.h>
/* 自定義宏 */
#define IIc_write 0 //IIc寫方向位
#define IIc_read 1 //IIc讀方向位
#define IIc_WaitTime 4 //時序時間控制IIc速度
/* IIC通訊協定接口聲明 */
sbit SDA = P1^0; //時鐘總線
sbit SCL = P1^1; //資料總線
/* 函數聲明 */
void IIc_Start(void); //IIc起始信号發生函數
void IIc_Stop(void); //IIc終止信号發生函數
unsigned char IIc_ReadByte(bit ACK); //IIc接收一位元組資料 傳回一位元組資料 并發送應答信号
bit IIc_SendByte(unsigned char Data); //IIc發送一位元組資料 發送一位元組資料 并傳回應答信号
#endif /*_IIC_INCLUDE_H_*/
如果說頭檔案是一張宏圖,向外界展示了自身的功能與實力,那麼C檔案便是默默奉獻的員工,将宏圖裡的想法一一實作,接下來我們再來來看看這些員工吧,你可以完全不用關心他們是怎麼工作的,今後我們隻會使用提供給外界的函數。
#include "IIc.h"
#include "Delay.h"
#define SET 1
#define RESET 0
/* 釋放IIc總線 */
static void IIc_ReleaseWire(void)
{
SCL = RESET;//下拉資料線
SDA = SET;//上拉資料線
}
/* IIc接收應答信号函數 傳回應答信号 */
static bit IIc_ReadACK(void)
{
bit ACK;//應答标志位
SCL = SET;//拉高時鐘總線 準備讀取應答信号
ACK = SDA;//擷取應答信号
IIc_ReleaseWire(); //釋放總線
if(!ACK)
return SET;//應答傳回1
return RESET;//傳回非應答
}
/* IIc應答發生信号函數 主機發送應答信号 */
static void IIc_SendACK(bit ACK)
{
SDA = ~ACK;//裝載應答信号
SCL = SET;//拉高時鐘線 發送應答信号
Delay_Us(IIc_WaitTime);//保持穩定
IIc_ReleaseWire();//釋放總線
}
/* IIc起始信号發生函數 */
void IIc_Start(void)
{ //時鐘線處于高電平期間,資料線由高到低進行變化
SCL = SET;
SDA = SET;
Delay_Us(IIc_WaitTime);//高電平期間
SDA = RESET;
IIc_ReleaseWire();//釋放總線
}
/* IIc終止信号發生函數 */
void IIc_Stop(void)
{ //時鐘線處于高電平期間,資料線由低到高進行變化
SDA = RESET;
SCL = SET;
Delay_Us(IIc_WaitTime); //高電平期間
SDA = SET;
Delay_Us(IIc_WaitTime); //低電平期間
//終止之後,兩根線均處于高電平狀态,IIc通訊進入空閑狀态
}
/* IIc接收一位元組資料 傳回一位元組資料并發送應答信号 */
unsigned char IIc_ReadByte(bit ACK)
{
unsigned char index,Data=0;//定義資料變量
for(index=0;index<8;index++)//循環讀取一位元組資料
{
SCL = SET;//拉高時鐘線 準備讀取資料
Data <<= 1;//資料右移
if(SDA) Data |=0x01;//讀取1 否則為0
IIc_ReleaseWire(); //釋放總線
}
IIc_SendACK(ACK);//發送應答信号
return Data;//傳回資料
}
/* IIc發送一位元組資料并傳回應答信号 */
bit IIc_SendByte(unsigned char Data)
{
unsigned char index;//for循環變量
for(index=0;index<8;index++)//循環發送一位元組資料
{
if(Data&0x80)
SDA = SET;
else
SDA = RESET;
SCL = SET;//拉高資料線,發送一位資料
Delay_Us(IIc_WaitTime);//穩定資料,確定讀取
Data <<= 1;//資料右移
IIc_ReleaseWire(); //釋放總線
}
return IIc_ReadACK();//讀取從機應答信号
}
-
是時候拜訪寄存器了!
說了那麼多,是時候和寄存器打交道了。控制BMP180的唯一方法便是讀寫内部的寄存器,利用IIc通訊協定通路寄存器的方法是:BMP180位址+寄存器位址(詳細可以參考手冊或者參考代碼)。在BMP180内部擁有28個可以為我們提供資訊的寄存器,請因為數量而不要擔心,耐心的看一看每個寄存器的功能。他們分别是三個資料輸出寄存器(out_xlsb、out_lsb、out_msb)、控制寄存器(ctrl_meas)、複位寄存器(soft_reset)、ID寄存器、22個資料校正EEPROM。每一個寄存器都有自己的辨別,通常叫做位址,通過下面這個表格來看看他們的位址都是啥?
-
這些寄存器有啥用?
資料輸出寄存器:它屬于隻讀寄存器,我們通過讀取寄存器裡面的資料可以獲得有關溫度和氣壓的原始資料。注意是原始資料,需要通過EEROM中的資料進行補償計算才能得到我們想要的資訊。
控制寄存器:它屬于可讀可寫的寄存器,通過控制寄存器中的某些位,我們可以控制讓BMP180執行溫度轉換和氣壓轉換,以及氣壓轉換精度。
ID寄存器:這是一個隻讀寄存器,裡面存儲了固定的0x55,可以用來進行識别裝置。
校正資料寄存器:22位元組的校正參數,用來校正原始資料,不同的器件可能校正參數不相等。
-
是時候來看看BMP180的宏圖了!
同樣的道理,你可以不用關心内部怎麼實作的,利用頭檔案提供的函數即可實作我們想要的功能。利用BMP180_Init() 對器件執行初始化操作,然後就可以利用BMP180_GetTemperature()來獲得溫度資訊,BMP180_GetAirPressure()來獲得氣壓資訊,BMP180_GetElevation()來獲得海拔資訊,在後期使用這些資料的時候一定要定期使用BMP180_UpData()來将傳感器的資料重新整理到緩沖區裡面,否則每次獲得的都是相同的資料,同時在運用他們的時候請注意他們的機關!
/***********************************************************
本程式實作了對氣壓傳感器BMP180的基本操作
可以進行溫度、氣壓、海拔資料資訊的測量及計算
作者聯系方式:1932857334 By QQ
***********************************************************/
#ifndef _INCLUDE_BMP180_H_
#define _INCLUDE_BMP180_H_
/* 裝置位址 */
#define BMP180_Address 0xEE
/* 部分寄存器位址宏定義 */
#define ID_Address 0xD0
#define MSB_Address 0xF6
#define LSB_Address 0xF7
#define XLSB_Address 0xF8
#define Cotrol_Address 0xF4
#define SOFT_RESET_Address 0xE0
/* 内部标志符 */
#define BMP180_ID 0x55
#define BMP180_SCO 0x20
#define BMP180_TEMP_CON 0x0E
#define BMP180_AIRP_CON 0x14
#define BMP180_SOFT_RESET 0xB6
/* 氣壓采集精度 */
#define U_L_P 0x00 //低功耗
#define STANDARD 0x01 //标準
#define HIGH_RES 0x02 //高分辨率
#define U_H_RES 0x03 //超高分辨率
#define OSS U_H_RES
/* 氣壓傳感器BMP180資料結構體 */
typedef struct {
/* BMP180 EEPROM中的資料 */
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;
/* 補償值 */
long B5;
/* 溫度氣壓原始值 */
long UP; //氣壓原始值
long UT; //溫度原始值
/* 溫度和氣壓與海拔 */
float Temp;//溫度 機關攝氏度
float AirP;//氣壓 機關帕斯卡
float Height;//海拔高度 機關米
}BMP180;
/* 函數聲明 */
bit BMP180_Init(void);//氣壓傳感器初始化操作
void BMP180_UpData(void);//重新整理氣壓傳感器資料
float BMP180_GetElevation(void);//獲得海拔資料 機關:M
float BMP180_GetAirPressure(void);//獲得氣壓資料 機關:Pa
float BMP180_GetTemperature(void);//獲得溫度資料 機關:攝氏度
#endif /*_INCLUDE_BMP180_H_*/
細心的小夥伴可能發現在裡面都沒有看到IIc的身影,它哪裡去了呢?
原來通過子產品化程式設計已經一步步把每一個闆塊進行的封裝,這樣可以讓我們的程式具有很好的移植性,假設有一天需要将51的代碼移植到32上面,隻需要将IIc的驅動進行更改(原頭檔案的内容不改變,改變實作方式——C檔案),不需要對BMP180的操作驅動進行任何修改即可完成移植,大大的提高了工作效率。或者有一個新的項目需要基于BMP180來實作,那麼我們可以直接使用這一份代碼,在新的闆塊裡運用函數接口來實作新的功能!
比如:我們需要顯示氣壓資訊,隻需要先讀取氣壓,然後顯示就結束了,是不是很友善?
寫在最後的話
非常感謝你的閱讀,希望能夠幫助到你,需要詳細的了解如果有任何建議都可以私信我,後續将逐漸完善一些常用子產品的時候心得,如果有需要的可以評論優先安排哈哈哈~~