在氣體分析類產(chǎn)品中,我們經(jīng)常會(huì)用到遠(yuǎn)紅外氣體傳感器。我們就在碳?xì)漕悮怏w成分分析中使用了S-Modlue遠(yuǎn)紅外氣體傳感器。接下來(lái),我們將討論S-Modlue遠(yuǎn)紅外氣體傳感器驅(qū)動(dòng)的設(shè)計(jì)與實(shí)現(xiàn)。
1、功能概述
??S-MODULE EVO 使用非分散紅外檢測(cè)技術(shù)NDIR,集成穩(wěn)定紅外光源,配置可靠性能的光電探測(cè)器,確保了傳感器檢測(cè)的穩(wěn)定性能。
??S-MODULE采用的是RS232串行通訊接口,但其通訊接口對(duì)外只有一個(gè)通訊引腳,所以實(shí)現(xiàn)的是半雙工模式。串口參數(shù)為:2400波特率,7位數(shù)據(jù)位,1位停止位,偶校驗(yàn)。
??在應(yīng)用層采用的則是Modbus ASCII協(xié)議。S-MODULE非分光紅外氣體模塊支持03和06功能碼。S-MODULE非分光紅外氣體模塊支持的Modbus參數(shù)如下:
2、驅(qū)動(dòng)設(shè)計(jì)與實(shí)現(xiàn)
??我們知道S-Module遠(yuǎn)紅外氣體傳感器采用基于半雙工RS232接口的Modbus ASCII通訊協(xié)議。接下來(lái)我們將基于它的協(xié)議規(guī)則設(shè)計(jì)并實(shí)現(xiàn)驅(qū)動(dòng)程序。
2.1、對(duì)象定義
??在使用一個(gè)對(duì)象之前我們需要獲得一個(gè)對(duì)象。同樣的我們想要S-Modlue遠(yuǎn)紅外氣體傳感器就需要先定義S-Modlue遠(yuǎn)紅外氣體傳感器的對(duì)象。
2.1.1、對(duì)象的抽象
??我們要得到S-Modlue遠(yuǎn)紅外氣體傳感器對(duì)象,需要先分析其基本特性。一般來(lái)說(shuō),一個(gè)對(duì)象至少包含兩方面的特性:屬性與操作。接下來(lái)我們就來(lái)從這兩個(gè)方面思考一下S-Modlue遠(yuǎn)紅外氣體傳感器的對(duì)象。
??先來(lái)考慮屬性,作為屬性肯定是用于標(biāo)識(shí)或記錄對(duì)象特征的東西。我們來(lái)考慮S-Modlue遠(yuǎn)紅外氣體傳感器對(duì)象的屬性。首先Modbus協(xié)議對(duì)象都有站地址用以標(biāo)識(shí)不同的設(shè)備,所以我們將設(shè)備地址作為對(duì)象的一個(gè)屬性。此外,狀態(tài)信息、溫度、濃度等實(shí)時(shí)信息表示了對(duì)象當(dāng)前的工作狀態(tài),所以我們將這些參數(shù)也作為對(duì)象的屬性。
??接著我們還需要考慮S-Modlue遠(yuǎn)紅外氣體傳感器對(duì)象的操作問(wèn)題。我們需要從S-Modlue遠(yuǎn)紅外氣體傳感器獲取數(shù)據(jù)和下發(fā)命令,就需要通過(guò)串口發(fā)送消息,但串口的處理與具體的平臺(tái)相關(guān),所以我們將其作為對(duì)象的操作。此外,在操作對(duì)象的過(guò)程中需要控制時(shí)序,所以延時(shí)操作函數(shù)必不可少,而延時(shí)操作函數(shù)往往依賴于具體的軟硬件平臺(tái),所以將延時(shí)函數(shù)作為對(duì)象的操作。
??根據(jù)上述我們對(duì)S-Modlue遠(yuǎn)紅外氣體傳感器的分析,我們可以定義S-Modlue遠(yuǎn)紅外氣體傳感器的對(duì)象類型如下:
/*定義NDIR對(duì)象類型*/
typedef struct NdirObject {
uint8_t moduleAddress;
uint16_t status;
uint32_t softVersion;
float concentration;
float temperature;
void (*SendByte)(uint8_t data);
void (*Delayms)(volatile uint32_t nTime);
}NdirObjectType;
2.1.2、對(duì)象初始化
??我們知道,一個(gè)對(duì)象僅作聲明是不能使用的,我們需要先對(duì)其進(jìn)行初始化,所以這里我們來(lái)考慮S-Modlue遠(yuǎn)紅外氣體傳感器對(duì)象的初始化函數(shù)。一般來(lái)說(shuō),初始化函數(shù)需要處理幾個(gè)方面的問(wèn)題。一是檢查輸入?yún)?shù)是否合理;二是為對(duì)象的屬性賦初值;三是對(duì)對(duì)象作必要的初始化配置。據(jù)此我們?cè)O(shè)計(jì)S-Modlue遠(yuǎn)紅外氣體傳感器對(duì)象的初始化函數(shù)如下:
/*NDIR初始化配置函數(shù)*/
void NdirInitialization(NdirObjectType *ndir, //NDIR對(duì)象
uint8_t moduleAddress, //模塊地址
NdirSendByteType send, //發(fā)送數(shù)據(jù)操作函數(shù)
NdirDelaymsType delayms //毫秒延時(shí)操作函數(shù)
)
{
if((ndir==NULL)||(send==NULL)||(delayms==NULL))
{
return;
}
ndir->SendByte=send;
ndir->Delayms=delayms;
ndir->moduleAddress=moduleAddress;
ndir->concentration=0.0;
ndir->temperature=0.0;
ndir->status=0;
ndir->softVersion=0;
}
2.2、對(duì)象操作
??我們已經(jīng)完成了S-Modlue遠(yuǎn)紅外氣體傳感器對(duì)象類型的定義和對(duì)象初始化函數(shù)的設(shè)計(jì)。但我們的主要目標(biāo)是獲取對(duì)象的信息,接下來(lái)我們還要實(shí)現(xiàn)面向S-Modlue遠(yuǎn)紅外氣體傳感器的各類操作。
??對(duì)于S-Modlue遠(yuǎn)紅外氣體傳感器對(duì)象來(lái)說(shuō),最基本的操作就是向其發(fā)送操作命令或數(shù)據(jù)消息。這是基于串口的Modbus ASCII協(xié)議的數(shù)據(jù)通訊,基于此我們可編寫(xiě)響應(yīng)的數(shù)據(jù)發(fā)送操作函數(shù)如下:
/*發(fā)送數(shù)據(jù)給舒茨非分光紅外氣體檢測(cè)模塊(讀寫(xiě)數(shù)據(jù))*/
static void NDIRSendData(NdirObjectType *ndir,uint8_t *txData,uint16_t length)
{
uint16_t sendDataAmount=0;
uint8_t sendDataArray[17]; //不小于(length+1)*2+3
uint8_t rawData[7];//含校驗(yàn)碼
for(int i=0;i6]=CheckSumCalc(txData,length);
uint8_t objData[14];
uint16_t cLength=ConvertHexArrayToASCIICharArray(rawData,length+1,objData);
sendDataArray[sendDataAmount++]=':';
for(int i=0;i0x0D;
sendDataArray[sendDataAmount++]=0x0A;
for(uint16_t sendDataIndex=0;sendDataIndex/*發(fā)送一個(gè)字節(jié)*/
ndir->SendByte(sendDataArray[sendDataIndex]);
}
}
3、驅(qū)動(dòng)的使用
??我們已經(jīng)實(shí)現(xiàn)了S-Module遠(yuǎn)紅外氣體傳感器的驅(qū)動(dòng)程序,但我們還需要驗(yàn)證一下它的正確性,所以在本節(jié)中我們就來(lái)設(shè)計(jì)一個(gè)簡(jiǎn)單的驗(yàn)證應(yīng)用。
3.1、聲明并初始化對(duì)象
??使用基于對(duì)象的操作我們需要先得到這個(gè)對(duì)象,所以我們先要使用前面定義的S-Modlue遠(yuǎn)紅外氣體傳感器對(duì)象類型聲明一個(gè)S-Modlue遠(yuǎn)紅外氣體傳感器對(duì)象變量,具體操作格式如下:
??NdirObjectType ndir;
??聲明了這個(gè)對(duì)象變量并不能立即使用,我們還需要使用驅(qū)動(dòng)中定義的初始化函數(shù)對(duì)這個(gè)變量進(jìn)行初始化。這個(gè)初始化函數(shù)所需要的輸入?yún)?shù)如下:
NdirObjectType *ndir, //NDIR對(duì)象
uint8_t moduleAddress, //模塊地址
NdirSendByteType send, //發(fā)送數(shù)據(jù)操作函數(shù)
NdirDelaymsType delayms //毫秒延時(shí)操作函數(shù)
??對(duì)于這些參數(shù),對(duì)象變量我們已經(jīng)定義了。模塊地址根據(jù)我們實(shí)際的使用情況輸入就好了。主要的是我們需要定義幾個(gè)函數(shù),并將函數(shù)指針作為參數(shù)。這幾個(gè)函數(shù)的類型如下:
/*發(fā)送一個(gè)字節(jié)操作函數(shù)指針類型*/
typedef void (*NdirSendByteType)(uint8_t data);
/*毫秒延時(shí)函數(shù)指針類型*/
typedef void (*NdirDelaymsType)(volatile uint32_t nTime);
??對(duì)于這幾個(gè)函數(shù)我們根據(jù)樣式定義就可以了,具體的操作可能與使用的硬件平臺(tái)有關(guān)系。具體函數(shù)定義如下:
static void SendByteForNdir(uint8_t data)
{
HAL_UART_Transmit(&ndirhuart,&data,1,1000);
}
??對(duì)于延時(shí)函數(shù)我們可以采用各種方法實(shí)現(xiàn)。我們采用的STM32平臺(tái)和HAL庫(kù)則可以直接使用HAL_Delay()函數(shù)。于是我們可以調(diào)用初始化函數(shù)如下:
/*上位通訊設(shè)備端口初始化配置*/
void Ndir_Init_Configuration(void)
{
NDIR_USART_Init_Configuration(); //配置串口中斷
/*NDIR初始化配置函數(shù)*/
NdirInitialization(&ndir, //NDIR對(duì)象
0x02, //模塊地址
SendByteForNdir, //發(fā)送數(shù)據(jù)操作函數(shù)
HAL_Delay //毫秒延時(shí)操作函數(shù)
);
/*讀軟件版本*/
ReadNDIRSoftVersion(&ndir,rxBuffer);
}
3.2、基于對(duì)象進(jìn)行操作
??我們定義了對(duì)象變量并使用初始化函數(shù)給其作了初始化。接著我們就來(lái)考慮操作這一對(duì)象獲取我們想要的數(shù)據(jù)。我們?cè)隍?qū)動(dòng)中已經(jīng)封裝了溫度、濃度以及狀態(tài)信息的操作函數(shù),接下來(lái)我們使用這一驅(qū)動(dòng)開(kāi)發(fā)我們的應(yīng)用實(shí)例。
/*NDIR數(shù)據(jù)操作*/
void Ndir_Comm_Process(void)
{
/*從舒茨非分光紅外氣體檢測(cè)模塊讀取濃度值*/
ReadConcentrationData(&ndir,rxBuffer);
/*從舒茨非分光紅外氣體檢測(cè)模塊讀取內(nèi)部溫度值*/
ReadTemperatureData(&ndir,rxBuffer);
/*從舒茨非分光紅外氣體檢測(cè)模塊讀取狀態(tài)標(biāo)志*/
ReadNDIRStatusflags(&ndir,rxBuffer);
}
4、應(yīng)用總結(jié)
??在我們的氣體分析儀產(chǎn)品上,我們就是用來(lái)S-Module遠(yuǎn)紅外氣體傳感器,也是基于我們的這一驅(qū)動(dòng)實(shí)現(xiàn)的,通訊穩(wěn)定,效果良好。
??在使用驅(qū)動(dòng)程序時(shí)需要注意,驅(qū)動(dòng)程序?qū)⒔馕龀绦蚍庋b到了數(shù)據(jù)發(fā)送函數(shù)中,可以直接調(diào)用數(shù)據(jù)讀取函數(shù)就可以了,也可以單獨(dú)調(diào)用解析函數(shù)來(lái)實(shí)現(xiàn),具體工作方式可應(yīng)需求實(shí)現(xiàn)。
評(píng)論
查看更多