嵌入式產(chǎn)品開發(fā)中,我們常常會(huì)有檢測(cè)環(huán)境溫度、壓力、濕度的需求。如果有一個(gè)集成有這3個(gè)傳感器的元件,無疑將是很方便的。博世的BME280就能實(shí)現(xiàn)這一要求。在這一篇中我們將討論BME280的驅(qū)動(dòng)設(shè)計(jì)與實(shí)現(xiàn)。
1 、功能概述
BME280是一款專為移動(dòng)應(yīng)用而開發(fā)的集成環(huán)境傳感器,其尺寸和低功耗是關(guān)鍵設(shè)計(jì)限制。該裝置結(jié)合了單個(gè)高線性度,高精度壓力,濕度和溫度傳感器,采用8引腳金屬蓋2.5 x 2.5 x0.93mm3LGA封裝,設(shè)計(jì)用于低電流消耗(3.6μA@ 1Hz),長(zhǎng)期穩(wěn)定性高EMC穩(wěn)健性。
1.1 、硬件描述
BME280壓力濕度溫度傳感器實(shí)現(xiàn)了高性能的溫度壓力濕度檢測(cè),包括有壓力、溫度、濕度3個(gè)傳感器和一個(gè)高精度ADC及接口邏輯,其結(jié)構(gòu)框圖如下圖所示:
濕度傳感器具有極快的響應(yīng)時(shí)間,可滿足新興應(yīng)用的性能要求,例如環(huán)境感知和寬溫度范圍內(nèi)的高精度。壓力傳感器是絕對(duì)氣壓傳感器,具有極高的精度和分辨率,噪音極低。集成的溫度傳感器經(jīng)過優(yōu)化,噪音極低,分辨率高。它主要用于壓力和濕度傳感器的溫度補(bǔ)償,也可用于估算環(huán)境溫度。
BME280壓力溫度傳感器采用了小巧的8引腳LGA封裝形式。其引腳排布就功能如下圖所示:
BME280支持全套操作模式,可靈活地優(yōu)化器件的功耗,分辨率和濾波器性能。
1.2 、通訊接口
BME280壓力溫度傳感器支持3種通訊接口方式:四線SPI、三線SPI以及I2C。在不同的接口模式下,各引腳的定義也是有差異的,關(guān)于這三種接口模式各引腳的定義如下:
對(duì)應(yīng)3種不同的接口方式,BME280壓力溫度傳感器存在三種與總線連接的方式。首先我們來看四線SPI接口方式,包括CSB片選、SCK時(shí)鐘、SDI數(shù)字輸入、SDO數(shù)字輸出。其總線連接方式如下圖:
接下來我們來看三線SPI接口方式,包括CSB片選、SCK時(shí)鐘、SDI數(shù)字輸入/SDO數(shù)字輸出。其與4線SPI的區(qū)別是數(shù)字輸入輸出使用同一引腳,第3腳就是輸入也是輸出,而第5腳浮空。其總線連接方式如下圖:
最后我們來看I2C接口方式,包括SCL時(shí)鐘、SDA數(shù)字輸入輸出。在I2C接口模式下,第2腳CSB連接到高電平,以設(shè)置BME280壓力溫度傳感器使用I2C接口。而第5腳則可以通過連接高電平或低電平來設(shè)置設(shè)備地址的最后一位,不可以浮空。所以根據(jù)第5腳電頻不同,BMP280壓力溫度傳感器的I2C設(shè)備7位地址為:0x76和0x77。其總線連接方式如下圖:
BME280壓力溫度傳感器在使用SPI接口時(shí),支持SPI模式0(CPOL=CPHA=0)和模式3(CPOL=CPHA=1)。而在使用I2C接口時(shí),支持標(biāo)準(zhǔn)模式、快速模式以及高速模式。接口的選擇實(shí)際上是通過CSB的電位實(shí)現(xiàn)的,低電平時(shí)就是SPI,高電平時(shí)就是I2C。
1.3 、內(nèi)部寄存器
對(duì)BME280壓力溫度傳感器的所有操作都是通過讀寫對(duì)應(yīng)的寄存器來實(shí)現(xiàn)的。BME280壓力溫度傳感器中所有的寄存器都是8位的。這些寄存器在存儲(chǔ)器中的地址分配如下圖所示。
在上圖并未包括系統(tǒng)保留的寄存器,這些寄存器不可以進(jìn)行寫操作,讀出來的值也是無意義的。接下來我們來詳細(xì)描述上圖中的這些寄存器。
先來看看兩個(gè)比較特殊的寄存器。首先是ID寄存器,這個(gè)寄存器是只讀的,而且其存儲(chǔ)的值也固定為0x60,用來代表設(shè)備為BME280壓力溫度傳感器。這個(gè)寄存器在系統(tǒng)上電后即可讀取。還有復(fù)位寄存器,這個(gè)寄存器是只寫的,固定向其寫0xB6來實(shí)現(xiàn)BME280壓力溫度傳感器的復(fù)位。同樣只要系統(tǒng)上電后即可以寫復(fù)位寄存器。
濕度控制寄存器用以配置濕度數(shù)據(jù)的測(cè)量精度。但是修改這個(gè)寄存器的值不會(huì)立即生效,必須對(duì)測(cè)量控制寄存器做了寫操作之后才會(huì)有效。濕度控制寄存器的各位定義如下圖:
狀態(tài)寄存器是只讀的,其實(shí)只使用了其中的兩位,這兩位分別表示數(shù)據(jù)測(cè)量是否完成和影響寄存器是否更新。下圖是狀態(tài)寄存器的詳細(xì)說明:
測(cè)量控制寄存器是可讀寫的,用以配置BME280壓力溫度傳感器數(shù)據(jù)獲取的方式。分別配置溫度采樣、壓力采樣和工作模式。工作模式有三種:休眠模式、強(qiáng)制模式、正常模式。系統(tǒng)上電后即為休眠模式,通過這一寄存器的配置可以使BME280壓力溫度傳感器進(jìn)入強(qiáng)制模式或正常模式運(yùn)行。濕度控制器修改后必須寫這個(gè)寄存器才會(huì)生效。測(cè)量控制寄存器的各位定義如下圖:
配置寄存器用于設(shè)置BME280壓力溫度濕度傳感器的速率、過濾器以及接口模式。在休眠模式下寫配置寄存器是允許的,但在正常模式下會(huì)被忽略,所以在系統(tǒng)復(fù)位后,進(jìn)入正常模式前先寫配置寄存器。配置寄存器各位的定義如下圖所示:
壓力數(shù)據(jù)寄存器存儲(chǔ)有壓力測(cè)量數(shù)據(jù)輸出的原始值。使用了三個(gè)寄存器中的20位來下存儲(chǔ)壓力數(shù)據(jù)。壓力數(shù)據(jù)寄存器各位的定義如下圖所示:
溫度數(shù)據(jù)寄存器存儲(chǔ)有溫度測(cè)量數(shù)據(jù)輸出的原始值。使用了三個(gè)寄存器中的20位來下存儲(chǔ)溫度數(shù)據(jù)。溫度數(shù)據(jù)寄存器各位的定義如下圖所示:
濕度數(shù)據(jù)寄存器存儲(chǔ)有濕度測(cè)量數(shù)據(jù)輸出的原始值。使用了兩個(gè)寄存器中的16位來下存儲(chǔ)濕度數(shù)據(jù)。濕度數(shù)據(jù)寄存器各位的定義如下圖所示:
此外還有校準(zhǔn)數(shù)據(jù)寄存器,總共是41個(gè)寄存器,存儲(chǔ)了計(jì)算壓力溫度最終值的廠家校準(zhǔn)數(shù)據(jù)。這些校準(zhǔn)寄存器的定義及地址分配如下圖所示:
我們已經(jīng)說過面向BME280壓力溫度濕度傳感器的所有操作都是基于寄存器進(jìn)行的,我們已經(jīng)了解了BME280壓力溫度濕度傳感器的各個(gè)寄存器,現(xiàn)在可以來實(shí)現(xiàn)它的操作了。
2 、驅(qū)動(dòng)設(shè)計(jì)與實(shí)現(xiàn)
上一節(jié)我們描述了BME280壓力濕度溫度傳感器的引腳功能、數(shù)據(jù)存儲(chǔ)格式以及通訊接口的基本內(nèi)容。在這一節(jié)中我們將考慮如何設(shè)計(jì)并實(shí)現(xiàn)BME280壓力濕度溫度傳感器的驅(qū)動(dòng)程序。
2.1 、對(duì)象定義
在使用一個(gè)對(duì)象之前我們需要獲得一個(gè)對(duì)象。同樣的我們想要BME280壓力濕度溫度傳感器就需要先定義BME280壓力濕度溫度傳感器的對(duì)象。
2.1.1 、對(duì)象的抽象
我們要得到BME280壓力濕度溫度傳感器對(duì)象,需要先分析其基本特性。一般來說,一個(gè)對(duì)象至少包含兩方面的特性:屬性與操作。接下來我們就來從這兩個(gè)方面思考一下BME280壓力濕度溫度傳感器的對(duì)象。
先來考慮屬性,作為屬性肯定是用于標(biāo)識(shí)或記錄對(duì)象特征的東西。我們來考慮BME280壓力濕度溫度傳感器對(duì)象屬性。BME280壓力濕度溫度傳感器的ID寄存器用于標(biāo)識(shí)設(shè)備是否為BME280;配置寄存器和測(cè)量控制寄存器都用關(guān)于系統(tǒng)配置,指示了設(shè)備的工作狀態(tài),所以我們將這幾個(gè)寄存器定義為對(duì)象的屬性。而使用的通訊接口決定了訪問BME280壓力濕度溫度傳感器的行為,所以我們需要記住這一配置;而校準(zhǔn)數(shù)據(jù)則在計(jì)算數(shù)據(jù)時(shí)所要使用的,我們也需要記住這些參數(shù),所以我們將它們也都定義為屬性。在I2C接口模式時(shí),設(shè)備地址是區(qū)分總線上設(shè)備的唯一標(biāo)志,所以我們將其定義為屬性。同樣測(cè)量數(shù)據(jù)指示了設(shè)備當(dāng)前的工作狀態(tài),我們將器作為屬性。
接著我們還需要考慮BME280壓力濕度溫度傳感器對(duì)象的操作問題。我們需要與BME280壓力濕度溫度傳感器通訊就需要向其寫數(shù)據(jù)并從其讀數(shù)據(jù),而不論是SPI接口還是I2C接口,讀寫操作都以來與具體的硬件平臺(tái),所以我們將他們作為對(duì)象的操作。此外,為控制時(shí)序,我們需要延時(shí)操作,而延時(shí)行為的實(shí)現(xiàn)亦依賴于具體的軟硬件平臺(tái),所以我們將延時(shí)也作為對(duì)象的操作。
根據(jù)上述我們對(duì)BME280壓力濕度溫度傳感器的分析,我們可以定義BME280壓力濕度溫度傳感器的對(duì)象類型如下:
1 /*定義Bme280操作對(duì)象*/
2 typedef struct BME280Object{
3 uint8_t chipID; //芯片ID
4 uint8_t bmeAddress; //I2C通訊時(shí)的設(shè)備地址
5 uint8_t config; //配置寄存器
6 uint8_t ctrlMeas; //測(cè)量控制寄存器
7 uint8_t ctrlHumi; //濕度測(cè)量控制寄存器
8 BME280PortType port; //接口選擇
9 BME280CalibParamType caliPara; //校準(zhǔn)參數(shù)
10 float temperature; //溫度值
11 float pressure; //壓力值
12 float humidity; //濕度值
13 void (*Read)(struct BME280Object *bme,uint8_t regAddress,uint8_t *rData,uint16_t rSize); //讀數(shù)據(jù)操作指針
14 void (*Write)(struct BME280Object *bme,uint8_t regAddress,uint8_t command); //寫數(shù)據(jù)操作指針
15 void (*Delayms)(volatile uint32_t nTime); //延時(shí)操作指針
16 void (*ChipSelect)(BME280CSType cs); //使用SPI接口時(shí),片選操作
17 }BME280ObjectType;
2.1.2 、對(duì)象初始化
我們知道,一個(gè)對(duì)象僅作聲明是不能使用的,我們需要先對(duì)其進(jìn)行初始化,所以這里我們來考慮BME280壓力濕度溫度傳感器對(duì)象的初始化函數(shù)。一般來說,初始化函數(shù)需要處理幾個(gè)方面的問題。一是檢查輸入?yún)?shù)是否合理;二是為對(duì)象的屬性賦初值;三是對(duì)對(duì)象作必要的初始化配置。據(jù)此我們?cè)O(shè)計(jì)BME280壓力濕度溫度傳感器對(duì)象的初始化函數(shù)如下:
1 /*實(shí)現(xiàn)BME280初始化配置*/
2 void BME280Initialization(BME280ObjectType *bme, //BMP280對(duì)象
3 uint8_t bmeAddress, //I2C接口是設(shè)備地址
4 BME280PortType port, //接口選擇
5 BME280TimeSBType t_sb, //間隔周期
6 BME280IIRFilterType filter, //過濾器
7 BME280SPI3wUseType spi3W_en, //3線SPI控制
8 BME280TempSampleType osrs_t, //溫度精度
9 BME280PresSampleType osrs_p, //壓力精度
10 BME280PowerModeType mode, //電源模式
11 BME280HumiSampleType osrs_h, //濕度精度
12 BME280Read Read, //讀數(shù)據(jù)操作指針
13 BME280Write Write, //寫數(shù)據(jù)操作指針
14 BME280Delayms Delayms, //延時(shí)操作指針
15 BME280ChipSelect ChipSelect //片選操作指針
16 )
17 {
18 uint8_t try_count = 5;
19 uint8_t regAddress=0;
20 uint8_t command=0;
21
22 if((bme==NULL)||(Read==NULL)||(Write==NULL)||(Delayms==NULL))
23 {
24 return;
25 }
26 bme->Read=Read;
27 bme->Write=Write;
28 bme->Delayms=Delayms;
29
30 bme->chipID=0x00;
31 bme->pressure=0.0;
32 bme->temperature=0.0;
33 bme->humidity=0.0;
34 bme->bmeAddress=0x00;
35 bme->port=port;
36 if(bme->port==BME280_I2C)
37 {
38 if((bmeAddress==0xEC)||(bmeAddress==0xEE))
39 {
40 bme->bmeAddress=bmeAddress;
41 }
42 bme->ChipSelect=NULL;
43 }
44 else
45 {
46 if(ChipSelect!=NULL)
47 {
48 bme->ChipSelect=ChipSelect;
49 }
50 else
51 {
52 bme->ChipSelect=BME280ChipSelectDefault;
53 }
54 }
55
56 bme->caliPara.t_fine=0;
57
58 if(!ObjectIsValid(bme))
59 {
60 return;
61 }
62
63 while(try_count--)
64 {
65 bme->chipID=ReadBME280Register(bme,REG_BME280_ID);
66 if(0x60==bme->chipID)
67 {
68 BME280SoftReset(bme);
69
70 break;
71 }
72 }
73
74 if(try_count)
75 {
76 /*配置配置寄存器:間隔周期0.5ms、IIR濾波系數(shù)16、不使用SPI3線通訊*/
77 regAddress=REG_CONFIG;
78 command=t_sb|filter|spi3W_en;
79 WriteBME280Register(bme,regAddress,command);
80
81 /*配置測(cè)量控制寄存器:溫度20位,壓力20位,電源正常模式*/
82 regAddress=REG_CTRL_MEAS;
83 command=osrs_t|osrs_p|mode;
84 WriteBME280Register(bme,regAddress,command);
85
86 /*配置濕度測(cè)量控制寄存器*/
87 regAddress=REG_CTRL_HUM;
88 command=osrs_h;
89 WriteBME280Register(bme,regAddress,command);
90
91 bme->Delayms(10);
92 bme->config=ReadBME280Register(bme,REG_CONFIG);
93 bme->Delayms(10);
94 bme->ctrlMeas=ReadBME280Register(bme,REG_CTRL_MEAS);
95 bme->Delayms(10);
96 bme->ctrlHumi=ReadBME280Register(bme,REG_CTRL_HUM);
97 bme->Delayms(10);
98
99 /*讀取校準(zhǔn)值*/
100 GetBME280CalibrationData(bme);
101 }
102 }
2.2 、對(duì)象操作
我們已經(jīng)完成了BME280壓力濕度溫度傳感器對(duì)象類型的定義和對(duì)象初始化函數(shù)的設(shè)計(jì)。但我們的主要目標(biāo)是獲取對(duì)象的信息,接下來我們還要實(shí)現(xiàn)面向BME280壓力濕度溫度傳感器的各類操作。
2.2.1 、寫寄存器
我們已經(jīng)說過了,對(duì)BME280的操作都是通過讀寫寄存器實(shí)現(xiàn)的。這里我們先來看寫寄存器。在I2C接口方式下,寫寄存器操作是在從站地址的最后一位來識(shí)別的,再加上要寫的寄存器地址和數(shù)據(jù)來實(shí)現(xiàn)的,這也是I2C協(xié)議的標(biāo)準(zhǔn)做法。其時(shí)序圖如下所示:
而在SPI接口方式下,由于SPI并未有設(shè)備地址,也不存在用從還在那地址最后為來標(biāo)記讀寫的模式。通常一些設(shè)備需要定義操作碼來實(shí)現(xiàn)讀寫區(qū)分,但BME280采取了將寄存器地址的最高位置零表示為寫。之所以可以這樣定義,是因?yàn)锽ME280寄存器地址分配的特殊性決定的。改變寄存器地址的最高位也能區(qū)分不同的寄存器,絕不會(huì)重復(fù)。在SPI接口方式下,寫寄存器的時(shí)序圖如下所示:
根據(jù)上述描述和時(shí)序圖,我們可以實(shí)現(xiàn)寫B(tài)ME280壓力濕度溫度傳感器寄存器的程序。
1 /* 向BME280寄存器寫一個(gè)字節(jié) */
2 static void WriteBME280Register(BME280ObjectType *bme,uint8_t regAddress,uint8_t command)
3 {
4 if(ObjectIsValid(bme))
5 {
6 if(bme->port==BME280_SPI)
7 {
8 regAddress&=0x7F;
9 bme->ChipSelect(BME280CS_ENABLE);
10 bme->Delayms(1);
11 bme->Write(bme,regAddress,command);
12 bme->Delayms(1);
13 bme->ChipSelect(BME280CS_DISABLE);
14 }
15 else
16 {
17 bme->Write(bme,regAddress,command);
18 }
19 }
20 }
2.2.2 、讀寄存器
讀寄存器的處理方式與寫寄存器是類似。在I2C接口方式下,將從站地址的最低位置1來表示讀。在I2C接口方式下,讀寄存器的時(shí)序圖如下所示:
而在SPI接口方式下,通過將寄存器地址的最高位置1來標(biāo)識(shí)為讀操作。事實(shí)上,所有寄存器地址的最高為都是1,所以在讀操作時(shí)實(shí)際不需要做處理。在SPI接口方式下,讀寄存器的時(shí)序圖如下所示:
根據(jù)上述描述和時(shí)序圖,我們可以實(shí)現(xiàn)讀BME280壓力溫度濕度傳感器寄存器的程序。
1 /*從BMP280寄存器讀取一個(gè)字節(jié)*/
2 static uint8_t ReadBME280Register(BME280ObjectType *bme,uint8_t regAddress)
3 {
4 uint8_t regValue=0xFF;
5
6 if(ObjectIsValid(bme))
7 {
8 if(bme->port==BME280_SPI)
9 {
10 regAddress |= 0x80;
11 bme->ChipSelect(BME280CS_ENABLE);
12 bme->Delayms(1);
13 bme->Read(bme,regAddress,®Value,1);
14 bme->Delayms(1);
15 bme->ChipSelect(BME280CS_DISABLE);
16 }
17 else
18 {
19 bme->Read(bme,regAddress,®Value,1);
20 }
21 }
22
23 return regValue;
24 }
3 、驅(qū)動(dòng)的使用
我們描述了BME280壓力濕度溫度傳感器的基本原理并實(shí)現(xiàn)了驅(qū)動(dòng)程序。我們還需要設(shè)計(jì)一個(gè)簡(jiǎn)單的應(yīng)用來驗(yàn)證這一驅(qū)動(dòng)設(shè)計(jì)是否合乎我們的要求,所以接下來我們就來設(shè)計(jì)一個(gè)簡(jiǎn)單的驗(yàn)證應(yīng)用。
3.1 、聲明并初始化對(duì)象
使用基于對(duì)象的操作我們需要先得到這個(gè)對(duì)象,所以我們先要使用前面定義的BME280壓力濕度溫度傳感器對(duì)象類型聲明一個(gè)BME280壓力濕度溫度傳感器對(duì)象變量,具體操作格式如下:
BME280ObjectType bme280;
聲明了這個(gè)對(duì)象變量并不能立即使用,我們還需要使用驅(qū)動(dòng)中定義的初始化函數(shù)對(duì)這個(gè)變量進(jìn)行初始化。這個(gè)初始化函數(shù)所需要的輸入?yún)?shù)如下:
BME280ObjectType *bme,BMP280對(duì)象
uint8_t bmeAddress,I2C接口是設(shè)備地址
BME280PortType port,接口選擇
BME280TimeSBType t_sb,間隔周期
BME280IIRFilterType filter,過濾器
BME280SPI3wUseType spi3W_en,3線SPI控制
BME280TempSampleType osrs_t,溫度精度
BME280PresSampleType osrs_p,壓力精度
BME280PowerModeType mode,電源模式
BME280HumiSampleType osrs_h,濕度精度
BME280Read Read,讀數(shù)據(jù)操作指針
BME280Write Write,寫數(shù)據(jù)操作指針
BME280Delayms Delayms,延時(shí)操作指針
BME280ChipSelect ChipSelect,片選操作指針
對(duì)于這些參數(shù),對(duì)象變量我們已經(jīng)定義了。接口選擇、間隔周期、過濾器、3線SPI控制、溫度精度、壓力精度、濕度精度、電源模式等都是枚舉量我們根據(jù)實(shí)際情況輸入即可。而使用I2C接口時(shí)需要的設(shè)備地址,也按具體地址給入就好。主要的是我們需要定義幾個(gè)函數(shù),并將函數(shù)指針作為參數(shù)。這幾個(gè)函數(shù)的類型如下:
1 /* 定義讀數(shù)據(jù)操作函數(shù)指針類型 */
2 typedef void (*BME280Read)(struct BME280Object *bme,uint8_t regAddress,uint8_t *rData,uint16_t rSize);
3
4 /* 定義寫數(shù)據(jù)操作函數(shù)指針類型 */
5 typedef void (*BME280Write)(struct BME280Object *bme,uint8_t regAddress,uint8_t command);
6
7 /* 定義延時(shí)操作函數(shù)指針類型 */
8 typedef void (*BME280Delayms)(volatile uint32_t nTime);
9
10 /* 定義使用SPI接口時(shí),片選操作函數(shù)指針類型 */
11 typedef void (*BME280ChipSelect)(BME280CSType cs);
對(duì)于這幾個(gè)函數(shù)我們根據(jù)樣式定義就可以了,具體的操作可能與使用的硬件平臺(tái)有關(guān)系。若采用的SPI接口則需注意片選操作,片選操作函數(shù)用于多設(shè)備需要軟件操作時(shí),如采用硬件片選可以傳入NULL即可。同樣如果采用的是I2C接口,則片選可以傳入NULL即可。具體函數(shù)定義如下:
1 /*讀BME280寄存器值*/
2 static void ReadDataFromBME280(BME280ObjectType *bme280,uint8_t regAddress,uint8_t *rData,uint16_t rSize)
3 {
4 HAL_I2C_Master_Transmit(&bme280hi2c, bme280->bmeAddress,®Address,1,1000);
5
6 HAL_I2C_Master_Receive(&bme280hi2c, bme280->bmeAddress+1,rData, rSize, 1000);
7 }
8
9 /*寫B(tài)ME280寄存器值*/
10 static void WriteDataToBME280(BME280ObjectType *bme280,uint8_t regAddress,uint8_t command)
11 {
12 uint8_t pData[2];
13
14 pData[0]=regAddress;
15 pData[1]=command;
16
17 HAL_I2C_Master_Transmit(&bme280hi2c,bme280->bmeAddress, pData, 2,1000);
18 }
對(duì)于延時(shí)函數(shù)我們可以采用各種方法實(shí)現(xiàn)。我們采用的STM32平臺(tái)和HAL庫(kù)則可以直接使用HAL_Delay()函數(shù)。于是我們可以調(diào)用初始化函數(shù)如下:
1 BME280Initialization(&bme280, //BME280對(duì)象
2 0xEC, //I2C接口是設(shè)備地址
3 BME280_I2C, //接口選擇
4 BME280_T_SB_0P5, //間隔周期
5 BME280_IIR_FILTER_COEFF_X16, //過濾器
6 BME280_SPI3W_DISABLE, //3線SPI控制
7 BME280_TEMP_SAMPLE_X16, //溫度精度
8 BME280_PRES_SAMPLE_X16, //壓力精度
9 BME280_POWER_NORMAL_MODE, //電源模式
10 BME280_HUMI_SAMPLE_X16, //濕度精度
11 ReadDataFromBME280, //讀數(shù)據(jù)操作指針
12 WriteDataToBME280, //寫數(shù)據(jù)操作指針
13 HAL_Delay, //延時(shí)操作指針
14 NULL //片選操作指針
15 );
3.2 、基于對(duì)象進(jìn)行操作
我們定義了對(duì)象變量并使用初始化函數(shù)給其作了初始化。接著我們就來考慮操作這一對(duì)象獲取我們想要的數(shù)據(jù)。我們?cè)隍?qū)動(dòng)中已經(jīng)將獲取數(shù)據(jù)并轉(zhuǎn)換為轉(zhuǎn)換值的比例值,接下來我們使用這一驅(qū)動(dòng)開發(fā)我們的應(yīng)用實(shí)例。
1 /*獲取大氣壓力和溫度*/
2 void BME280GetEnvironmentalData(void)
3 {
4 float pressure; //壓力值
5 float temperature; //溫度值
6 float humidity; //濕度值
7
8 GetBME280Measure(&bme280);
9
10 pressure=bme280.pressure;
11 temperature=bme280.temperature;
12 humidity=bme280.humidity;
13 }
4 、應(yīng)用總結(jié)
BME280壓力濕度溫度傳感器的驅(qū)動(dòng)已經(jīng)實(shí)現(xiàn)并做了簡(jiǎn)單的應(yīng)用。在我們測(cè)試時(shí),得到的數(shù)據(jù)與其它方法獲得的溫度壓力數(shù)據(jù)基本是一致的,這說明我們的驅(qū)動(dòng)程序總體來說是正確的。
BME280壓力濕度溫度傳感器支持SPI和I2C兩種接口,而且SPI也支持3線和4線模式,但我們?cè)跍y(cè)試應(yīng)用中只使用了I2C接口,SPI接口還有待測(cè)試。
在使用驅(qū)動(dòng)時(shí)需注意,采用SPI接口的器件需要考慮片選操作的問題。如果片選信號(hào)是通過硬件電路來實(shí)現(xiàn)的,我們?cè)诔跏蓟瘯r(shí)給其傳遞NULL值。如果是軟件操作片選則傳遞我們編寫的片選操作函數(shù)。而如果采用I2C接口,那么在初始化時(shí)也應(yīng)傳遞NULL值。
BME280壓力濕度溫度傳感器在使用SPI接口時(shí),支持SPI模式0(CPOL=CPHA=0)和模式3(CPOL=CPHA=1)。而在使用I2C接口時(shí),支持標(biāo)準(zhǔn)模式、快速模式以及高速模式。而且在使用I2C接口時(shí),SDO引腳必須接高電平或低電平,以確定設(shè)備地址。
源碼下載:https://github.com/foxclever/ExPeriphDriver
評(píng)論
查看更多