外设驱动库开发笔记31:S-Modlue远红外气体传感器驱动
??在氣體分析類產品中,我們經常會用到遠紅外氣體傳感器。我們就在碳氫類氣體成分分析中使用了S-Modlue遠紅外氣體傳感器。接下來,我們將討論S-Modlue遠紅外氣體傳感器驅動的設計與實現。
1、功能概述
??S-MODULE EVO 使用非分散紅外檢測技術NDIR,集成穩定紅外光源,配置可靠性能的光電探測器,確保了傳感器檢測的穩定性能。
??S-MODULE采用的是RS232串行通訊接口,但其通訊接口對外只有一個通訊引腳,所以實現的是半雙工模式。串口參數為:2400波特率,7位數據位,1位停止位,偶校驗。
??在應用層采用的則是Modbus ASCII協議。S-MODULE非分光紅外氣體模塊支持03和06功能碼。S-MODULE非分光紅外氣體模塊支持的Modbus參數如下:
2、驅動設計與實現
??我們知道S-Module遠紅外氣體傳感器采用基于半雙工RS232接口的Modbus ASCII通訊協議。接下來我們將基于它的協議規則設計并實現驅動程序。
2.1、對象定義
??在使用一個對象之前我們需要獲得一個對象。同樣的我們想要S-Modlue遠紅外氣體傳感器就需要先定義S-Modlue遠紅外氣體傳感器的對象。
2.1.1、對象的抽象
??我們要得到S-Modlue遠紅外氣體傳感器對象,需要先分析其基本特性。一般來說,一個對象至少包含兩方面的特性:屬性與操作。接下來我們就來從這兩個方面思考一下S-Modlue遠紅外氣體傳感器的對象。
??先來考慮屬性,作為屬性肯定是用于標識或記錄對象特征的東西。我們來考慮S-Modlue遠紅外氣體傳感器對象的屬性。首先Modbus協議對象都有站地址用以標識不同的設備,所以我們將設備地址作為對象的一個屬性。此外,狀態信息、溫度、濃度等實時信息表示了對象當前的工作狀態,所以我們將這些參數也作為對象的屬性。
??接著我們還需要考慮S-Modlue遠紅外氣體傳感器對象的操作問題。我們需要從S-Modlue遠紅外氣體傳感器獲取數據和下發命令,就需要通過串口發送消息,但串口的處理與具體的平臺相關,所以我們將其作為對象的操作。此外,在操作對象的過程中需要控制時序,所以延時操作函數必不可少,而延時操作函數往往依賴于具體的軟硬件平臺,所以將延時函數作為對象的操作。
??根據上述我們對S-Modlue遠紅外氣體傳感器的分析,我們可以定義S-Modlue遠紅外氣體傳感器的對象類型如下:
/*定義NDIR對象類型*/ 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、對象初始化
??我們知道,一個對象僅作聲明是不能使用的,我們需要先對其進行初始化,所以這里我們來考慮S-Modlue遠紅外氣體傳感器對象的初始化函數。一般來說,初始化函數需要處理幾個方面的問題。一是檢查輸入參數是否合理;二是為對象的屬性賦初值;三是對對象作必要的初始化配置。據此我們設計S-Modlue遠紅外氣體傳感器對象的初始化函數如下:
/*NDIR初始化配置函數*/ void NdirInitialization(NdirObjectType *ndir, //NDIR對象uint8_t moduleAddress, //模塊地址NdirSendByteType send, //發送數據操作函數NdirDelaymsType delayms //毫秒延時操作函數) {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、對象操作
??我們已經完成了S-Modlue遠紅外氣體傳感器對象類型的定義和對象初始化函數的設計。但我們的主要目標是獲取對象的信息,接下來我們還要實現面向S-Modlue遠紅外氣體傳感器的各類操作。
??對于S-Modlue遠紅外氣體傳感器對象來說,最基本的操作就是向其發送操作命令或數據消息。這是基于串口的Modbus ASCII協議的數據通訊,基于此我們可編寫響應的數據發送操作函數如下:
/*發送數據給舒茨非分光紅外氣體檢測模塊(讀寫數據)*/ static void NDIRSendData(NdirObjectType *ndir,uint8_t *txData,uint16_t length) {uint16_t sendDataAmount=0;uint8_t sendDataArray[17]; //不小于(length+1)*2+3uint8_t rawData[7];//含校驗碼for(int i=0;i<length;i++){rawData[i]=txData[i];}rawData[6]=CheckSumCalc(txData,length);uint8_t objData[14];uint16_t cLength=ConvertHexArrayToASCIICharArray(rawData,length+1,objData);sendDataArray[sendDataAmount++]=':';for(int i=0;i<cLength;i++){sendDataArray[sendDataAmount++]=objData[i];}sendDataArray[sendDataAmount++]=0x0D;sendDataArray[sendDataAmount++]=0x0A;for(uint16_t sendDataIndex=0;sendDataIndex<sendDataAmount;sendDataIndex++){/*發送一個字節*/ndir->SendByte(sendDataArray[sendDataIndex]);} }3、驅動的使用
??我們已經實現了S-Module遠紅外氣體傳感器的驅動程序,但我們還需要驗證一下它的正確性,所以在本節中我們就來設計一個簡單的驗證應用。
3.1、聲明并初始化對象
??使用基于對象的操作我們需要先得到這個對象,所以我們先要使用前面定義的S-Modlue遠紅外氣體傳感器對象類型聲明一個S-Modlue遠紅外氣體傳感器對象變量,具體操作格式如下:
??NdirObjectType ndir;
??聲明了這個對象變量并不能立即使用,我們還需要使用驅動中定義的初始化函數對這個變量進行初始化。這個初始化函數所需要的輸入參數如下:
NdirObjectType *ndir, //NDIR對象 uint8_t moduleAddress, //模塊地址 NdirSendByteType send, //發送數據操作函數 NdirDelaymsType delayms //毫秒延時操作函數??對于這些參數,對象變量我們已經定義了。模塊地址根據我們實際的使用情況輸入就好了。主要的是我們需要定義幾個函數,并將函數指針作為參數。這幾個函數的類型如下:
/*發送一個字節操作函數指針類型*/ typedef void (*NdirSendByteType)(uint8_t data); /*毫秒延時函數指針類型*/ typedef void (*NdirDelaymsType)(volatile uint32_t nTime);??對于這幾個函數我們根據樣式定義就可以了,具體的操作可能與使用的硬件平臺有關系。具體函數定義如下:
static void SendByteForNdir(uint8_t data) {HAL_UART_Transmit(&ndirhuart,&data,1,1000); }??對于延時函數我們可以采用各種方法實現。我們采用的STM32平臺和HAL庫則可以直接使用HAL_Delay()函數。于是我們可以調用初始化函數如下:
/*上位通訊設備端口初始化配置*/ void Ndir_Init_Configuration(void) {NDIR_USART_Init_Configuration(); //配置串口中斷/*NDIR初始化配置函數*/NdirInitialization(&ndir, //NDIR對象0x02, //模塊地址SendByteForNdir, //發送數據操作函數HAL_Delay //毫秒延時操作函數);/*讀軟件版本*/ReadNDIRSoftVersion(&ndir,rxBuffer); }3.2、基于對象進行操作
??我們定義了對象變量并使用初始化函數給其作了初始化。接著我們就來考慮操作這一對象獲取我們想要的數據。我們在驅動中已經封裝了溫度、濃度以及狀態信息的操作函數,接下來我們使用這一驅動開發我們的應用實例。
/*NDIR數據操作*/ void Ndir_Comm_Process(void) {/*從舒茨非分光紅外氣體檢測模塊讀取濃度值*/ReadConcentrationData(&ndir,rxBuffer);/*從舒茨非分光紅外氣體檢測模塊讀取內部溫度值*/ReadTemperatureData(&ndir,rxBuffer);/*從舒茨非分光紅外氣體檢測模塊讀取狀態標志*/ReadNDIRStatusflags(&ndir,rxBuffer); }4、應用總結
??在我們的氣體分析儀產品上,我們就是用來S-Module遠紅外氣體傳感器,也是基于我們的這一驅動實現的,通訊穩定,效果良好。
??在使用驅動程序時需要注意,驅動程序將解析程序封裝到了數據發送函數中,可以直接調用數據讀取函數就可以了,也可以單獨調用解析函數來實現,具體工作方式可應需求實現。
歡迎關注:
總結
以上是生活随笔為你收集整理的外设驱动库开发笔记31:S-Modlue远红外气体传感器驱动的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 外设驱动库开发笔记15:DHT11温湿度
- 下一篇: STM32与宇电设备实现AI-BUS通讯