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