聚豐項(xiàng)目 > 多組分氣體分析儀設(shè)計(jì)驗(yàn)證
多組分氣體分析儀是我公司近期研發(fā)的三個(gè)主要產(chǎn)品之一。采用模塊化設(shè)計(jì),可增減配置,可分析混合氣體中的氧氣、氫氣、甲烷、丙烷等氣體的組分。
A670521546
A670521546
團(tuán)隊(duì)成員
尹家軍 工程師
在硬件方面充分考慮系統(tǒng)應(yīng)用的需求,AD采集、DA輸出、DI輸入、DO輸出以及通訊等。
通訊部分主要包括串口通訊與以太網(wǎng)通訊。以太網(wǎng)的通訊采用W5500以太網(wǎng)控制器與MCU通過(guò)SPI總線通訊,在本項(xiàng)目中使用SPI2來(lái)實(shí)現(xiàn)通訊,以太網(wǎng)通訊部分的硬件設(shè)計(jì)如下:
串口通訊主要對(duì)象有兩個(gè),遠(yuǎn)紅外炭氫傳感器和顯示屏。遠(yuǎn)紅外炭氫傳感器采用單總線串行通訊,TTL電平。兩路接口,通常一用一備,在需要時(shí)也可接兩臺(tái)傳感器,如一臺(tái)甲烷一臺(tái)丙烷。硬件接口的設(shè)計(jì)如下:
對(duì)于顯示屏起通訊接口采用RS485或者RS232。主要是應(yīng)為面向不同的應(yīng)用場(chǎng)合,在需要大顯示屏的時(shí)候選擇的是RS485接口,在普通小顯示屏是使用的是RS232接口。但這兩個(gè)屏不會(huì)同時(shí)使用所以采用一個(gè)USART口,實(shí)際使用的USART2通訊口,是使用RS232還RS485選擇焊接不同的器件。硬件部分的設(shè)計(jì)如下圖所示:
模擬量輸入輸出采用SPI接口與AD7705和AD5663來(lái)完成,模擬量輸入輸出個(gè)兩路。模擬量輸入主要用于采集氫氣組分?jǐn)?shù)據(jù)和氧氣組分?jǐn)?shù)據(jù)。氫氣傳感器采用熱式原理輸出0-5VDC的信號(hào)。氧氣傳感器有兩種:順磁傳感器和電化學(xué)傳感器,順磁傳感器輸出4-20mA電流信號(hào),電化學(xué)傳感器輸出0-2.5VDC的信號(hào),兩者不同時(shí)采用,所以采用同一路AI通道,根據(jù)不同的傳感器焊接不同的器件。硬件設(shè)計(jì)如下:
模擬量輸出也是兩路,通過(guò)SPI總線與MCU通訊。沒(méi)路均能輸出0-5VDC信號(hào)。這部分硬件設(shè)計(jì)比較簡(jiǎn)單:
數(shù)字量輸入輸出主要用與小型真空泵和電磁閥得控制以及按鈕和狀態(tài)信息的輸入,硬件電路比較簡(jiǎn)單:
還有其他部分的硬件設(shè)計(jì),相對(duì)比較平常就不在此討論了。
軟件的開(kāi)發(fā)環(huán)境采用IAR EWARM和STM32CubeMX,在STM32CubeMX完成基本配置并生成項(xiàng)目,再在IAR EWARM開(kāi)發(fā)應(yīng)用并調(diào)試?;镜拈_(kāi)發(fā)調(diào)試就不討論了,主要說(shuō)一說(shuō)數(shù)字量輸入輸出,模擬量輸入輸出、串口通訊以及以太網(wǎng)通訊幾個(gè)方面的應(yīng)用開(kāi)發(fā)和調(diào)試。
為了讓軟件更好地適應(yīng)更換傳感器和應(yīng)用不同場(chǎng)合的功能增減要求,我們?cè)谠O(shè)計(jì)軟件時(shí)使用了一個(gè)配置文件來(lái)配置更能的使用和增減。這個(gè)配置文件就是一個(gè)頭文件,定義了一些宏來(lái)控制條件編譯,節(jié)選部分配置文件如下:
/*多組分氣體分析儀應(yīng)用版本定義:
——0,用于標(biāo)準(zhǔn)的多組分氣體分析儀,版本號(hào)VA1.0.1;
——1,用于標(biāo)準(zhǔn)的多組分氣體分析儀,版本號(hào)VA1.0.1;
——2,用于標(biāo)準(zhǔn)的多組分氣體分析儀,版本號(hào)VA1.0.1;
——3,用于便攜式氣體分析儀,版本號(hào)V1.0.1B;
——4,B版應(yīng)用板,版本號(hào)V1.0.1B;*/
#ifndef MFC_MasterBoard_VERSION
#define MFC_MasterBoard_VERSION (0)
#endif
/*定義擴(kuò)展功能的使能,一次只能使能一項(xiàng)*/
//#define EXT_Ethernet_ENABLE //擴(kuò)展以太網(wǎng)通訊
//#define EXT_CAN_ENABLE //擴(kuò)展CAN總線通訊
/*定義片上Flash存取使能*/
#ifndef STORAGE_ENABLE
#define STORAGE_ENABLE (1)
#endif
/*全局變量定義*/
#include "globalvariable.h"
/*顯示屏控制*/
#include "lcdcommunication.h"
/*數(shù)字邏輯處理*/
#include "logicprocess.h"
/*模擬量輸入輸出處理*/
#include "addaprocess.h"
/*以太網(wǎng)通訊處理*/
#include "ethernetprocess.h"
/*紅外炭氫傳感器*/
#include "ndirdataprocess.h"
/*片上Flash參數(shù)存取操作*/
#if STORAGE_ENABLE > (1)
#include "storeprocess.h"
#endif
/*調(diào)試功能*/
#include "CommonConfig.h"
關(guān)于模擬量輸入輸出、串口通訊以及以太網(wǎng)通訊幾個(gè)方面軟件的設(shè)計(jì)及調(diào)試在前面的文章中都已經(jīng)較少的比較清楚了,只有數(shù)字量輸入輸出沒(méi)有涉及到,在總結(jié)這一篇文章中我們?cè)谲浖脑O(shè)計(jì)和調(diào)試上主要說(shuō)說(shuō)數(shù)字量的處理。在多組分氣體成分分析儀中總共有5個(gè)DI輸入和5個(gè)DO輸出。這10個(gè)引腳的GPIO配置如下:
/*Configure GPIO pins : DI1_Pin DI2_Pin DI3_PinDI4_Pin
DI5_Pin */
GPIO_InitStruct.Pin = DI1_Pin|DI2_Pin|DI3_Pin|DI4_Pin
|DI5_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/*Configure GPIO pins : DO1_Pin DO2_Pin DO3_PinDO4_Pin
DO5_Pin */
GPIO_InitStruct.Pin = DO1_Pin|DO2_Pin|DO3_Pin|DO4_Pin
|DO5_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOD, DO1_Pin|DO2_Pin|DO3_Pin|DO4_Pin
|DO5_Pin,GPIO_PIN_RESET);
對(duì)于DI、DO的操作我們采用定義操作函數(shù)來(lái)實(shí)現(xiàn)對(duì)單個(gè)通道和全部通道的操作。我們首先定義兩個(gè)枚舉類(lèi)型分別定義如下:
//定義數(shù)字量輸出通道枚舉類(lèi)型,規(guī)定通道的范圍
typedef enum {
DOChannel1,
DOChannel2,
DOChannel3,
DOChannel4,
DOChannel5,
DOChannelNum
} DigitalOutput;
//定義數(shù)字量輸入通道枚舉類(lèi)型,規(guī)定通道的范圍
typedef enum {
DIChannel1,
DIChannel2,
DIChannel3,
DIChannel4,
DIChannel5,
DIChannelNum
} DigitalInput;
數(shù)字量輸入輸出的枚舉主要是為了方便操作和識(shí)別,通道數(shù)量出現(xiàn)變化時(shí)只需要增加枚舉兩種的通道定義即可。此處數(shù)字量輸入輸出均定義了5個(gè)通道。枚舉量的最后一個(gè)成員代表了通道的數(shù)量,在枚舉全部通道時(shí)能夠很好的避免超出范圍的錯(cuò)誤。
同時(shí)還要定義如下的結(jié)構(gòu)體,用于定義需要操作GPIO目標(biāo)。
//定義用于針腳操作的目標(biāo)針腳類(lèi)型
typedef struct{
GPIO_TypeDef* GPIOx;
uint16_tGPIO_Pin;
}TargetPin;
有了上述的定義則可以實(shí)現(xiàn)前面設(shè)想的操作了,接下來(lái)我們還需要定義兩個(gè)數(shù)字量輸入輸出通道的TargetPin類(lèi)型的數(shù)組,用于存放想要操作的目標(biāo)通道,和前面枚舉兩種定義的通道一致,此處也是5個(gè)通道。
//定義DI通道的全部目標(biāo)針腳數(shù)組
TargetPin diPin[]={{GPIOE,GPIO_Pin_2},{GPIOE,GPIO_Pin_3},{GPIOE,GPIO_Pin_4}
,{GPIOE,GPIO_Pin_5},{GPIOE,GPIO_Pin_6}};
//定義DO通道的全部目標(biāo)針腳數(shù)組
TargetPindoPin[]={{GPIOD,GPIO_Pin_3},{GPIOD,GPIO_Pin_4},{GPIOD,GPIO_Pin_5}
,{GPIOD,GPIO_Pin_6},{GPIOD,GPIO_Pin_7}};
有了以上2個(gè)數(shù)組就可以在避免在操作過(guò)程中大量使用條件分支語(yǔ)句(Switch或if語(yǔ)句),簡(jiǎn)化編碼和避免在增加通道時(shí)號(hào)要修改函數(shù)的情況?,F(xiàn)在如果通道數(shù)量出現(xiàn)變化則只需要修改枚舉量和數(shù)組的值就可?;蛘卟僮鞯墓苣_出現(xiàn)變化則只需要修改數(shù)組的值就可以了。而不需要去修改函數(shù)體,而且函數(shù)體的編碼也非常簡(jiǎn)單。
對(duì)數(shù)字量輸出的操作如下,在操作全部通道時(shí),以枚舉變量作為循環(huán)變量,以枚舉的最后定義的數(shù)量來(lái)控制,并以枚舉量的取值作為數(shù)組下標(biāo),有效避免出現(xiàn)超出范圍的錯(cuò)誤,同時(shí)在通道數(shù)量和通道對(duì)應(yīng)的具體針腳發(fā)生變化時(shí),無(wú)需修改函數(shù)。
//操作全部繼電器DO通道
//輸入?yún)?shù)TargetPin *doPin為要操作的DO通道列表
//輸入?yún)?shù)BOOL *commands欲寫(xiě)給DO通道的值列表
void OperationAllRelayChannel(TargetPin*doPin,BOOL *commands)
{
DigitalOutput DOChannel;
for(DOChannel=DOChannel1;DOChannel<DOChannelNum;DOChannel++)
{
OperationSingleRelayChannel(doPin[DOChannel],commands[DOChannel]);
}
}
//操作單個(gè)繼電器DO通道
//輸入?yún)?shù)TargetPin doPin為要操作的DO通道
//輸入?yún)?shù)BOOL command欲寫(xiě)給DO通道的值
void OperationSingleRelayChannel(TargetPindoPin,BOOL command)
{
HAL_GPIO_WritePin(doPin.GPIOx,doPin.GPIO_Pin,command);
}
對(duì)數(shù)字量輸入的操作函數(shù)的編寫(xiě)采用與數(shù)字量輸出相同的思路。對(duì)于枚舉之所以可以用作數(shù)組下標(biāo),是因?yàn)槊杜e沒(méi)被指定值時(shí),總是從0開(kāi)始向上累加,正好與數(shù)組下標(biāo)是一致的。這要做還有一個(gè)好處是,通道與具體的GPIO引腳是由TargetPin數(shù)組的賦值順序決定的,修改非常方便。
//獲取全部DI量狀態(tài)輸入值
//輸入?yún)?shù)TargetPin *diPin為需要讀取的DI通道列表
//輸入?yún)?shù)BOOL *result為讀取的通道值返回列表
void GetAllDIStatusInput(TargetPin *diPin,BOOL*result)
{
DigitalInput DIChannel;
for(DIChannel=DIChannel1;DIChannel<DIChannelNum;DIChannel++)
{
result[DIChannel]=GetSingleDIStatusInput(diPin[DIChannel]);
}
}
//獲取單個(gè)DI量狀態(tài)輸入值
//輸入?yún)?shù)TargetPin diPin是需要讀取的DI通道
//返回值為讀取的通道值
BOOL GetSingleDIStatusInput(TargetPin diPin)
{
uint8_treadValue;
readValue= GPIO_ReadInputDataBit(diPin.GPIOx,diPin.GPIO_Pin);
return(readValue>0)?True:False;
}
最后來(lái)一張調(diào)試數(shù)字量輸入輸出的截圖:
多組分氣體成分分析儀項(xiàng)目軟件其他部分的設(shè)計(jì)與調(diào)試也已經(jīng)過(guò)驗(yàn)證,在此就不多說(shuō)了。
多組分氣體分析儀的測(cè)試機(jī)已經(jīng)可以運(yùn)行,大部分的功能也已經(jīng)完成,測(cè)試基本完成。來(lái)幾張結(jié)果圖片,首先來(lái)一張調(diào)試模擬量數(shù)據(jù)采集的圖片:
再來(lái)一張顯示屏顯示各組分的的畫(huà)面:
接下來(lái)再來(lái)一張顯示屏顯示參數(shù)設(shè)定和操作的界面:
再來(lái)一張顯示網(wǎng)絡(luò)通訊的界面:
零角度: 對(duì)這個(gè)比較感興趣,可以共同探討一下嗎?QQ41040168
回復(fù)
動(dòng)心忍性1234: 您好我是無(wú)線電雜志的編輯,我們對(duì)您的項(xiàng)目十分感興趣,請(qǐng)問(wèn)您有興趣投稿嗎?成為我們的作者除稿費(fèi)外還有其他優(yōu)厚條件。敬請(qǐng)參與。投稿請(qǐng)聯(lián)系QQ260534978.
回復(fù)