在我們的項(xiàng)目中,經(jīng)常會(huì)有需要檢測(cè)大氣壓力的時(shí)候。 這次我們?cè)诖髿?a href="http://hljzzgx.com/v/tag/1453/" target="_blank">環(huán)境監(jiān)測(cè)的過程中用到了HP203B這款氣壓傳感器。 所以這一篇中,我們來思考HP203B氣壓傳感器的驅(qū)動(dòng)設(shè)計(jì)。
1、功能概述
??HP203B是高分辨率(0.1meter)壓力傳感器,帶有I2C接口,包括一個(gè)硅壓阻壓力元件和一個(gè)高分辨率24 位△∑ADC。 HP203B提供高精度24位壓力和溫度數(shù)字輸出,客戶可以根據(jù)應(yīng)用需要轉(zhuǎn)換速度和高度,所有內(nèi)置計(jì)算采用了高速4MHz的浮點(diǎn)運(yùn)算,計(jì)算誤差小,數(shù)據(jù)補(bǔ)償是內(nèi)部集成,通訊連接非常簡單,高度及溫度上下限比較的可編程事件及中斷輸出控制。
1.1、功能
??HP203B是一款超小型集高精度氣壓計(jì)、高度計(jì)和溫度計(jì)于一體的傳感器。 內(nèi)部集成了24位ADC,硅傳感芯片,以及存放內(nèi)部參數(shù)的OTP。 該傳感器通過設(shè)計(jì)公司獲得的專利補(bǔ)償算法在傳感器器件片內(nèi)進(jìn)行采樣,信號(hào)處理以及運(yùn)算,最終計(jì)算出實(shí)際的直接結(jié)果值,所以外部應(yīng)用MCU只需發(fā)出信號(hào)采集命令,待完成后,再通過I2C接口直接讀取壓力,溫度及絕對(duì)海拔高度三者的實(shí)際值。 具體結(jié)構(gòu)圖如下:
??此外,該傳感器內(nèi)部提供了對(duì)溫度、壓力和海拔高度的上下限閾值及中間閥值,并構(gòu)成的趨勢(shì)變化的多種事件響應(yīng)的條件預(yù)定設(shè)置。 當(dāng)其中任一事件發(fā)生達(dá)到了預(yù)設(shè)條件后,在傳感器內(nèi)部狀態(tài)寄存器會(huì)置起相應(yīng)的標(biāo)志,并在已經(jīng)預(yù)先設(shè)置的相應(yīng)的中斷腳位上輸出高電平。
1.2、命令
??HP203B氣壓傳感器通過命令集來實(shí)現(xiàn)上位對(duì)它的訪問。 命令集允許用戶控制傳感器進(jìn)行配置及結(jié)果讀取。 具體的命令列表如下:
??用戶通過上述列表中的命令可以實(shí)現(xiàn)對(duì)HP203B氣壓傳感器的配置及操作,也可以讀取我們檢測(cè)的數(shù)據(jù)。
1.3、接口
??HP203B氣壓傳感器使用I2C接口。 I2C設(shè)備地址如下所示。 設(shè)備地址的LSB是由CSB腳的狀態(tài)決定。
??CSB PIN=0: 對(duì)應(yīng)的地址0XEE (write) and 0XEF (read)。
??CSB PIN=1: 對(duì)應(yīng)的地址0XEC (write) and 0XED (read)。
1.4、報(bào)文格式
??HP203B氣壓傳感器根據(jù)操作命令的不同,可以將通訊的報(bào)文格式分為4類。
??第一類:主機(jī)發(fā)出一個(gè)單字節(jié)命令的類型。 主機(jī)發(fā)出設(shè)備地址(ID)并跟隨寫位 W 位,收到答復(fù) ACK 位后,發(fā)出命令字節(jié),傳感器收到后,地回 ACK.如下是發(fā)出一個(gè) SOFT_RST 命令。
??第二類:主機(jī)寫入寄存器的類型。 主機(jī)發(fā)出設(shè)備地址(ID)并跟隨寫位 W 位,收到答復(fù) ACK 位后,發(fā)出命令字節(jié)及一個(gè)字節(jié)的數(shù)據(jù)。 這種格式僅適用于當(dāng)用戶想要發(fā)出一個(gè) WRITE_REG 命令。
??第三類:主機(jī)從設(shè)備讀取寄存器的類型。 在這第三類型中共有兩幀并分別發(fā)送。 第一幀是發(fā)送包含高 2 位二進(jìn)制數(shù) 10 及后面跟著低 6 位的寄存器地址的 READ_REG 命令。 第一幀的格式與第一類的相同。 在第二幀,該傳感器將發(fā)送回寄存器中的數(shù)據(jù)當(dāng)收到正確的設(shè)備地址及讀位(R)之后。 這種類型僅適用于使用 READ_REG 命令。
??第四類:主機(jī)從設(shè)備讀3個(gè)字節(jié)或6個(gè)字節(jié)的ADC數(shù)據(jù)。
??其中,第四類是我們最常使用的,筆記我們的目的就是獲取氣壓的監(jiān)測(cè)數(shù)據(jù)。
2、驅(qū)動(dòng)設(shè)計(jì)與實(shí)現(xiàn)
??在前面我們簡單的描述了HP203B氣壓傳感器的基本情況,接下來我們將據(jù)此來設(shè)計(jì)HP203B氣壓傳感器的驅(qū)動(dòng)程序。
2.1、對(duì)象定義
??我們依然使用基于對(duì)象的方式來設(shè)計(jì)HP203B氣壓傳感器的驅(qū)動(dòng)。 所以我們首先考慮HP203B氣壓傳感器對(duì)象類型的定義。 關(guān)于對(duì)象,我們知道器包含屬性和操作。
??我們先來考慮HP203B氣壓傳感器對(duì)象的屬性問題。 對(duì)于I2C設(shè)備,都有一個(gè)設(shè)備地址,這一地址用以表示該設(shè)備在總線上的唯一存在,所以我們將設(shè)備地址作為屬性,來記錄該設(shè)備的特性。 同樣的,HP203B氣壓傳感器用以監(jiān)測(cè)氣壓、溫度和海拔,這幾個(gè)參數(shù)標(biāo)識(shí)HP203B氣壓傳感器對(duì)象當(dāng)前的狀態(tài),所以我們將器作為對(duì)象的屬性。
??接下來我們考慮對(duì)象的操作。 對(duì)象的操作有很多,但我們只需要考慮那些需要依賴于具體的軟硬件平臺(tái)才能實(shí)現(xiàn)的定義為對(duì)象的操作。 而HP203B氣壓傳感器作為I2C接口的設(shè)備,與平臺(tái)相關(guān)的就是I2C接口的讀寫,所以我們將通過I2C讀寫數(shù)據(jù)的過程定義為對(duì)象的操作。
??基于這些分析,我們定義HP203B氣壓傳感器的對(duì)象類型如下:
/*定義HP203B對(duì)象類型*/
typedef struct Hp203bObject {
uint8_t deviceAddress;
uint32_t cTemperature;
uint32_t cPressure;
uint32_t cAltitude;
float fTemperature;
float fPressure;
float fAltitude;
void (*Receive)(struct Hp203bObject *hp,uint8_t *rData,uint16_t rSize); //接收數(shù)據(jù)操作指針
void (*Transmit)(struct Hp203bObject *hp,uint8_t *tData,uint16_t tSize); //發(fā)送數(shù)據(jù)操作指針
}Hp203bObjectType;
??定義了HP203B氣壓傳感器對(duì)象類型,我們可以得到相應(yīng)的對(duì)象變量,但這一對(duì)象變量并不可以使用,需要對(duì)其屬性和操作進(jìn)行初始化配置才能使用。 所以我們還需要設(shè)計(jì)以個(gè)初始化函數(shù)對(duì)對(duì)象變量進(jìn)行初始化操作。 在這里我們根據(jù)設(shè)定的HP203B氣壓傳感器對(duì)象的屬性和操作來實(shí)現(xiàn)對(duì)象的初始化函數(shù)如下:
/*HP203B對(duì)象初始化*/
void Hp203bInitialization(Hp203bObjectType *hp,
uint8_t deviceAddress,
Ph203bReceiveType recieve,
Ph203bTransmitType transmit)
{
if((hp==NULL)||(recieve==NULL)||(transmit==NULL))
{
return;
}
hp->Receive=recieve;
hp->Transmit=transmit;
if((deviceAddress==0xEE)||(deviceAddress==0xEC))
{
hp->deviceAddress=deviceAddress;
}
else if((deviceAddress==0x77)||(deviceAddress==0x76))
{
hp->deviceAddress=(deviceAddress<<1);
}
else
{
hp->deviceAddress=0;
}
/*軟復(fù)位命令*/
Hp203bSoftReset(hp);
}
2.2、對(duì)象操作
??我們實(shí)現(xiàn)了HP203B氣壓傳感器對(duì)象類型的定義,接下來我們考慮我們需要對(duì)HP203B氣壓傳感器實(shí)時(shí)的操作。 根據(jù)前面我們對(duì)操作命令及操作報(bào)文的了解,我們對(duì)HP203B氣壓傳感器的操作主要是對(duì)寄存器的訪問和對(duì)數(shù)據(jù)的訪問。
2.2.1、訪問寄存器
??對(duì)寄存器的訪問包括都寄存器的值和寫寄存器的值,根據(jù)響應(yīng)的指令和所要操作的寄存器地址,我們可以實(shí)現(xiàn)讀寫寄存器的操作函數(shù)如下:
/*讀寄存器值*/
uint8_t Hp203bReadRegister(Hp203bObjectType *hp,Hp203bRegisterType reg)
{
uint8_t cmd=CMD_ANA_CAL;
uint8_t rData=0;
hp->Transmit(hp,&cmd,1);
hp->Receive(hp,&rData,1);
return rData;
}
/*寫寄存器值*/
void Hp203bWriteRegister(Hp203bObjectType *hp,Hp203bRegisterType reg,uint8_t value)
{
uint8_t cmd[2];
cmd[0]=CMD_WRITE_REG;
cmd[1]=value;
hp->Transmit(hp,cmd,2);
}
2.2.2、訪問測(cè)量值
??我們對(duì)HP203B氣壓傳感器的操作最終都是為了獲取氣壓、溫度和海拔的測(cè)量值。 HP203B氣壓傳感器使用不同的操作命令來獲取不同的測(cè)量值,這里我們以讀取氣壓和溫度測(cè)量值為例。
/*讀取溫度和壓力值*/
void Hp203bReadTemperaturPressure(Hp203bObjectType *hp)
{
uint8_t cmd=CMD_READ_PT;
uint8_t rData[6];
uint32_t temp=0;
hp->Transmit(hp,&cmd,1);
hp->Receive(hp,rData,6);
hp->cTemperature=(rData[0]<<16)+(rData[1]<<8)+rData[2];
if(rData[0]>0x0F)
{
hp->cTemperature=hp->cTemperature|0xFFF00000;
temp=~(hp->cTemperature-0x01);
hp->fTemperature=0.0-(float)temp/100.0;
}
else
{
hp->fTemperature=(float)hp->cTemperature/100.0;
}
hp->cPressure=(rData[3]<<16)+(rData[4]<<8)+rData[5];
hp->fPressure=(float)(hp->cPressure)/100.0;
}
3、驅(qū)動(dòng)的使用
??我們已經(jīng)設(shè)計(jì)并實(shí)現(xiàn)了HP203B氣壓傳感器對(duì)象的驅(qū)動(dòng)程序,接下來我們將使用這一驅(qū)動(dòng)程序?qū)崿F(xiàn)對(duì)HP203B氣壓傳感器的操作。
3.1、聲明并初始化對(duì)象
??在實(shí)現(xiàn)對(duì)HP203B氣壓傳感器的操作之前,我們先聲明一個(gè)HP203B氣壓傳感器的對(duì)象變量。
Hp203bObjectType hp203b;
??聲明的這個(gè)對(duì)象變量,我們需要先對(duì)其進(jìn)行初始化。 初始化函數(shù)有4個(gè)參數(shù),第一個(gè)是所要初始化的對(duì)象變量。 第二個(gè)參數(shù)是該對(duì)象變量所表示的設(shè)備的地址。 這些直接輸入就可以,主要是后2個(gè)參數(shù)為發(fā)送和接收函數(shù)的函數(shù)指針,這兩個(gè)函數(shù)我們需要實(shí)現(xiàn)。 其函數(shù)原型如下:
/*接收數(shù)據(jù)操作指針*/
typedef void (*Ph203bReceiveType)(struct Hp203bObject *hp,uint8_t *rData,uint16_t rSize);
/*發(fā)送數(shù)據(jù)操作指針*/
typedef void (*Ph203bTransmitType)(struct Hp203bObject *hp,uint8_t *tData,uint16_t tSize);
??根據(jù)函數(shù)原型要求,并結(jié)合我們所采用的軟硬件平臺(tái),我們可以實(shí)現(xiàn)數(shù)據(jù)的發(fā)送及接收函數(shù)如下:
/*從Hp203b接收數(shù)據(jù)*/
static void ReceiveFromHp203b(Hp203bObjectType *hp,uint8_t *rData,uint16_t rSize)
{
HAL_I2C_Master_Receive(&hi2c1,hp->deviceAddress,rData, rSize, 1000);
}
/*向Hp203b傳送數(shù)據(jù)*/
static void TransmitToHp203b(Hp203bObjectType *hp,uint8_t *tData,uint16_t tSize)
{
HAL_I2C_Master_Transmit(&hi2c1,hp->deviceAddress,tData,tSize,1000);
}
??根據(jù)上述的說明及實(shí)現(xiàn),我們可以使用初始化函數(shù)對(duì)HP203B氣壓傳感器對(duì)象變量進(jìn)行初始化配置。
/*HP203B對(duì)象初始化*/
Hp203bInitialization(&hp203b,
0xEC,
ReceiveFromHp203b,
TransmitToHp203b);
HAL_Delay(100);
/*OSR設(shè)定,通道選擇,執(zhí)行轉(zhuǎn)換*/
Hp203bConvertSetting(&hp203b,Hp203b_OSR_4096,Hp203b_P_T_Channel);
??初始化對(duì)象變量的同時(shí),實(shí)現(xiàn)了轉(zhuǎn)換方式及轉(zhuǎn)換通道的配置。
3.2、基于對(duì)象進(jìn)行操作
??完成HP203B氣壓傳感器的基本配置后,我們就可以定時(shí)獲取壓力和溫度數(shù)據(jù)了。 先調(diào)用壓力溫度獲取函數(shù):
Hp203bReadTemperaturPressure(&hp203b);
??正確讀取后,通過訪問對(duì)象變量hp203b的fTemperature和fPressure屬性就可以得到我們想要的數(shù)據(jù)了。
4、應(yīng)用總結(jié)
??這一篇中,我們?cè)O(shè)計(jì)并實(shí)現(xiàn)了HP203B氣壓傳感器的驅(qū)動(dòng)程序。 我們將這一驅(qū)動(dòng)應(yīng)用到實(shí)際的項(xiàng)目中,系統(tǒng)運(yùn)行穩(wěn)定。
評(píng)論
查看更多