有時候我們需要檢測一些無法直接接觸的器件的溫度。為了實現這一需求,我們通常會選擇紅外溫度傳感器來實現這一功能。考慮到復用的問題,我們一般會將操作元器件的代碼抽象為驅動函數以備調用。這里我們就來設計并實現TSEV01CL55紅外溫度傳感器的驅動。
1 、功能概述
TSEV01CL55是一種基于紅外輻射檢測的無接觸測溫系統。TSEV01CL55在前端裝有紅外傳感器(熱電堆)。
1.1 、硬件描述
TSEV01CL55適用于需要非接觸式溫度測量的廣泛應用場合。TSEV01CL55紅外溫度傳感器測溫時,熱堆傳感器必須指向所要測量的目標對象。TSEV01CL55紅外溫度傳感器的引腳定義如下:
TSEV01CL55紅外溫度傳感器測溫基本工作原理是:用熱電堆傳感器探測紅外輻射,該傳感器將入射輻射轉換成模擬電壓;用熱敏電阻測定傳感器溫度。根據測到的目標溫度和環境溫度數據進一步的進行模擬信號處理和調理,使用處理單元計算環境溫度和物體溫度。
1.2 、通訊接口
TSEV01CL55紅外溫度傳感器對外通訊采用數字輸出總線(I2C)。通過I2C總線和響應的操作命令就可以得到物體溫度和環境溫度數據。這兩個值都是以百分之一的度數傳輸的。相關的操作命令如下:
TSEV01CL55紅外溫度傳感器測溫有一定的范圍限制,當環境或物體溫度超過指定溫度范圍時,溫度輸出顯示以下數據:
TSEV01CL55紅外溫度傳感器的I2C硬件模塊在SCL“鎖存”問題上進行了更改。修改后的I2C模塊不再下拉SCL命令主程序等待數據的計算。因此,主設備必須增加等待時間,以確保從設備能夠組織數據。對于標準數據傳輸(比如讀取溫度),1ms的時間足夠從設備組織數據。對于需要更多時間的操作(如讀取/寫入EEPROM),應該留取足夠的時間等待從設備處理數據。
向TSEV01CL55紅外溫度傳感器寫命令時序如下:
從TSEV01CL55紅外溫度傳感器讀數據時序如下:
上述時序圖是讀取目標溫度的時序圖。其它數據的讀寫過程類似,在此不再贅述。
2 、驅動設計與實現
我們已經了解了TSEV01CL55紅外溫度傳感器的基本情況。接下來我們將設計并實現TSEV01CL55紅外溫度傳感器的通用驅動程序。
2.1 、對象定義
在使用一個對象之前我們需要獲得一個對象。同樣的我們想要TSEV01CL55紅外溫度傳感器對象就需要先定義TSEV01CL55紅外溫度傳感器的對象。如何得到TSEV01CL55紅外溫度傳感器的對象呢?接下來我們就來考慮這個問題。
2.1.1 、對象的抽象
我們要得到TSEV01CL55紅外溫度傳感器對象,需要先分析器基本特性。一般來說,一個對象至少包含兩方面的特性:屬性與操作。接下來我們就來從這兩個方面思考一下TSEV01CL55紅外溫度傳感器的對象。
先來考慮屬性,作為屬性肯定是用于標識或記錄對象特征的東西。我們來考慮TSEV01CL55紅外溫度傳感器對象屬性。作為I2C通訊從設備,在總線上唯一區別不同設備的就是設備地址。所以我們將I2C設備地址作為對象的一個屬性。TSEV01CL55紅外溫度傳感器所檢測的環境溫度和目標溫度雖然不能唯一標識TSEV01CL55紅外溫度傳感器對象,但可以記錄當前的狀態所以我們將其作為對象的屬性。
接著我們還需要考慮TSEV01CL55紅外溫度傳感器對象的操作問題。對于I2C通訊設備,我們需要向設備寫命令,同時也要從設備接收數據,但不論是接收數據還是發送命令都依賴于硬件接口和相關的硬件平臺,所以我們將寫命令和收數據作為TSEV01CL55紅外溫度傳感器對象的兩個操作。此外,操作過程中我們需要時序操作,而延時操作都依賴于具體的平臺,所以我們將延時操作作為TSEV01CL55紅外溫度傳感器對象的一個操作。
根據上述我們對TSEV01CL55紅外溫度傳感器的分析,我們可以定義TSEV01CL55紅外溫度傳感器的對象類型如下:
//定義TSEV01CL55紅外溫度傳感器對象類型
typedef structHLPTObject{
uint8_t devAddress; //對象的地址
float tempObject; //對象溫度值
float tempAmbient; //環境溫度
void (*Delayms)(volatile uint32_tnTime); //延時操作指針
void (*Receive)(struct HLPTObject *hlpt,uint8_t *rData,uint16_t rSize); //接收數據操作指針
void (*Transmit)(struct HLPTObject *hlpt,uint8_t *wData,uint16_t wSize); //發送數據操作指針
}HLPTObjectType;
2.1.2 、對象初始化
我們知道,一個對象僅作聲明是不能使用的,我們需要先對其進行初始化,所以這里我們來考慮TSEV01CL55紅外溫度傳感器對象的初始化函數。一般來說,初始化函數需要處理幾個方面的問題。一是檢查輸入參數是否合理;二是為對象的屬性賦初值;三是對對象作必要的初始化配置。據此我們設計TSEV01CL55紅外溫度傳感器對象的初始化函數如下:
/* 紅外溫度傳感器對象初始化 */
void HLPTInitialization(HLPTObjectType*hlpt, //初始化的對象變量
uint8_t address, //設備I2C地址
HLPTReceive receive, //接收函數指針
HLPTTransmit transmit, //發送函數指針
HLPTDelayms delayms //毫秒延時函數指針
)
{
if((hlpt==NULL)||(receive==NULL)||(transmit==NULL)||(delayms==NULL))
{
return;
}
hlpt->Receive=receive;
hlpt->Transmit=transmit;
hlpt->Delayms=delayms;
hlpt->tempObject=0.0;
hlpt->tempAmbient=0.0;
if(address>0x00)
{
hlpt->devAddress=address;
}
else
{
hlpt->devAddress=HLPTSlaveAddress;
}
}
2.2 、對象操作
我們已經完成了TSEV01CL55紅外溫度傳感器對象類型的定義和對象初始化函數的設計。但我們的主要目標是獲取對象的信息,接下來我們還要實現面向TSEV01CL55紅外溫度傳感器的各類操作。
面向TSEV01CL55紅外溫度傳感器的操作比較簡單,最主要的就是讀取溫度數據,包括環境溫度和目標溫度。所以我們開發獲取面向TSEV01CL55紅外溫度傳感器數據的操作如下:
/* 讀取數據 */
static uint16_tReadDataFromHLPT(HLPTObjectType *hlpt,uint8_t cmd)
{
uint8_t data[2];
uint16_t tempCode;
hlpt->Transmit(hlpt,cmd,1);
hlpt->Delayms(1);
hlpt->Receive(hlpt,data,2);
tempCode=(data[0]<<8)+data[1];
return tempCode;
}
3 、驅動的使用
我們已經設計并實現了TSEV01CL55紅外溫度傳感器的驅動程序,接下來我們將考慮設計一個簡單的應用來驗證這一驅動。
3.1 、聲明并初始化對象
使用基于對象的操作我們需要先得到這個對象,所以我們先要使用前面定義的TSEV01CL55紅外溫度傳感器對象類型聲明一個TSEV01CL55紅外溫度傳感器對象變量,具體操作格式如下:
HLPTObjectTypehlpt;
聲明了這個對象變量并不能立即使用,我們還需要使用驅動中定義的初始化函數對這個變量進行初始化。這個初始化函數所需要的輸入參數如下:
HLPTObjectType*hlpt,初始化的對象變量
uint8_t address,設備I2C地址
HLPTReceivereceive,接收函數指針
HLPTTransmittransmit,發送函數指針
HLPTDelaymsdelayms,毫秒延時函數指針
對于這些參數,對象變量我們已經定義了。而設備地址,根據實際情況輸入就好了。主要的是我們需要定義幾個函數,并將函數指針作為參數。這幾個函數的類型如下:
/*延時操作指針類型*/
typedef void (*HLPTDelayms)(volatileuint32_t nTime);
/*接收數據操作指針類型*/
typedef void (*HLPTReceive)(structHLPTObject *hlpt,uint8_t *rData,uint16_t rSize);
/*發送數據操作指針類型*/
typedef void (*HLPTTransmit)(structHLPTObject *hlpt,uint8_t *wData,uint16_t wSize);
對于這幾個函數我們根據樣式定義就可以了,具體的操作可能與使用的硬件平臺有關系。具體函數定義如下:
/*從TSEV01CL55接收數據*/
static voidReceiveFromHLPT(HLPTObjectType *sht,uint8_t *rData,uint16_t rSize)
{
HAL_I2C_Master_Receive(&hlpti2c, sht->devAddress,rData, rSize, 1000);
}
/*向TSEV01CL55傳送數據*/
static voidTransmitToHLPT(HLPTObjectType *sht,uint8_t *tData,uint16_t tSize)
{
HAL_I2C_Master_Transmit(&hlpti2c,sht->devAddress,tData,tSize,1000);
}
對于延時函數我們可以采用各種方法實現。我們采用的STM32平臺和HAL庫則可以直接使用HAL_Delay()函數。于是我們可以調用初始化函數如下:
HLPTInitialization(&hlpt,0x54,ReceiveFromHLPT,TransmitToHLPT,HAL_Delay);
3.2 、基于對象進行操作
我們定義了對象變量并使用初始化函數給其作了初始化。接著我們就來考慮操作這一對象獲取我們想要的數據。我們在驅動中已經將獲取數據并轉換為轉換值的比例值,接下來我們使用這一驅動開發我們的應用實例。
/*讀取溫度值*/
void GetTemperatureData(void)
{
float tempObject;
float tempAmbient;
GetHLPTemperature(&hlpt);
tempObject=hlpt.tempObject;
tempAmbient=hlpt.tempAmbient;
}
4 、應用總結
我們實現了TSEV01CL55紅外溫度傳感器的驅動,并再次基礎上設計了一個簡單的驗證應用。我們得到了目標溫度和環境溫度。這說明我們的驅動設計是成功的。
在使用驅動時我們需要注意,與TSEV01CL55紅外溫度傳感器的I2C通訊會出現鎖死的情況,特別是使用硬件I2C收發器的時候。而且TSEV01CL55紅外溫度傳感器不會在數據準備好后下拉SCL電平,所以讀取數據時,需要給以足夠的延時來保證數據準備就緒。
在使用TSEV01CL55紅外溫度傳感器的驅動時還應注意,TSEV01CL55紅外溫度傳感器有一個固定的地址0x54,在初始化時輸入此地址,若不給定這個地址就會以廣播的方式通訊。
評論
查看更多