摘要:隨著智能化、自動化的發(fā)展,各類設(shè)備對聯(lián)網(wǎng)通信的需求越來越強(qiáng)。在傳統(tǒng)設(shè)備改造過程中,串口通信應(yīng)用廣泛,針對常用串口通信中協(xié)議解析與其他模塊融合,導(dǎo)致協(xié)議解析模塊存在無法實(shí)現(xiàn)重用和維護(hù)困難等問題,文章應(yīng)用面向?qū)ο蟮乃枷?,充分利用C#語言的封裝、繼承和多態(tài)特性,設(shè)計了可擴(kuò)展的串口通信模塊,通過設(shè)計不同的協(xié)議實(shí)現(xiàn)類,可擴(kuò)展不同的通信協(xié)議,而客戶端只需要設(shè)計簡單的實(shí)現(xiàn)類對通信協(xié)議進(jìn)行配置即可完成對協(xié)議的解析。文章以文本數(shù)據(jù)格式的通信協(xié)議為例,進(jìn)行了實(shí)際測試,該模塊穩(wěn)定可靠,具有較高的實(shí)用性。
關(guān)鍵詞:串口;通信協(xié)議;面向?qū)ο?;可擴(kuò)展
中圖分類號:TP311.5
文獻(xiàn)標(biāo)志碼:A
0 引言
數(shù)據(jù)通信也稱數(shù)據(jù)交換,指將數(shù)據(jù)從一個系統(tǒng)傳輸至另一個系統(tǒng)的過程。隨著各種設(shè)備的自動化、智能化發(fā)展,信息技術(shù)在裝備制造業(yè)中的應(yīng)用越來越廣泛。傳統(tǒng)設(shè)備進(jìn)行數(shù)字化改造,與各種信息化系統(tǒng)進(jìn)行通信是必不可少的功能。目前,各類設(shè)備通信的方式很多,如串口通信、USB通信、以太網(wǎng)通信等。雖然現(xiàn)在新的設(shè)備具備聯(lián)網(wǎng)功能,即實(shí)現(xiàn)了以太網(wǎng)聯(lián)網(wǎng)通信功能,但是還有大量的設(shè)備只具備USB通信或串口通信能,不具備以太網(wǎng)功能。使用USB通信的開發(fā)難度比串口通信的復(fù)雜度有所提升,需專用的驅(qū)動程序和上位機(jī)軟件,而串口通信不僅結(jié)構(gòu)簡單,成本低,能使用傳統(tǒng)的上位機(jī)軟件,而且設(shè)備端的開發(fā)更容易。目前,大量的USB轉(zhuǎn)串口模塊也使傳統(tǒng)具有串口通信的設(shè)備能夠具有USB連接功能,且上位機(jī)不需要修改,解決了電腦不具備物理串口的問題。
大量研究者對串口通信進(jìn)行了研究,王文娟等[1]對比常用幾種串口數(shù)據(jù)傳輸方式,利用VS2010的PComm設(shè)計了多類型數(shù)據(jù)串口通信軟件,解決了PComm不兼容Win64位操作系統(tǒng)無法傳輸多類型數(shù)據(jù)的問題。屈武江[2]應(yīng)用VS2008通過對應(yīng)動態(tài)鏈接庫中API庫內(nèi)的函數(shù)實(shí)現(xiàn)了一種基于串口通信的數(shù)據(jù)采集分析系統(tǒng)。辛王毅等[3]利用C#開發(fā)與雙輪電機(jī)通信的上位機(jī)軟件,通過預(yù)編碼指令控制小車的直行、后退、左轉(zhuǎn)、右轉(zhuǎn)等,并能接收下位機(jī)上傳的傳感器數(shù)據(jù)。王建等[4]利用QT Creator 編寫 PC 端串口接收界面程序,實(shí)時顯示、接收由下位機(jī)上傳的傳感器數(shù)據(jù),將接收到的原始數(shù)據(jù)以字節(jié)的形式直接顯示在界面中,未對數(shù)據(jù)進(jìn)行解析,需要人工再次計算得出數(shù)據(jù)的具體含義。蔣萍花等[5]利用MSComm控件實(shí)現(xiàn)計算機(jī)與下位機(jī)之間串口通信,介紹了上位機(jī)與下位機(jī)之間數(shù)據(jù)通信的協(xié)議及通過串口進(jìn)行遠(yuǎn)程通信的方案。陳旭輝等[6]設(shè)計了基于USB接口的虛擬多串口通信設(shè)備,PC首先發(fā)送數(shù)據(jù)到虛擬串口,再由虛擬串口通過物理串口將數(shù)據(jù)發(fā)送到外部設(shè)備。經(jīng)過對相關(guān)文件進(jìn)行分析,多數(shù)研究人員利用串口進(jìn)行通信時,主要采用API, PComm, SerialPort等控件實(shí)現(xiàn)對串口數(shù)據(jù)的讀寫,而且采用硬編碼或字節(jié)流的方式獲取通信數(shù)據(jù),提交給上層軟件對內(nèi)容進(jìn)行解析,上層必須完全明白通信過程中各字節(jié)的含義,該控件未對協(xié)議進(jìn)行解析,也未對通信過程中的數(shù)據(jù)進(jìn)行檢驗,對上層應(yīng)用的開發(fā)不友好。針對此問題,文章提出了一種基于C#語言面向?qū)ο蟮耐ㄓ脜f(xié)議解析串口通信的類庫,可根據(jù)項目需要自由擴(kuò)展通信協(xié)議,自動進(jìn)行解析,并向上層提供完整的數(shù)據(jù),方便上層軟件的開發(fā),加快了項目開發(fā)的進(jìn)度,提高了協(xié)議解析的穩(wěn)定性。
1 功能需求
在各類使用通信的軟件中,通信的雙方都需事先約定通信的規(guī)則,即通信協(xié)議。設(shè)計的通信協(xié)議要求簡單高效,且能保證數(shù)據(jù)的完整性,能適應(yīng)二進(jìn)制數(shù)據(jù)流和ASCII數(shù)據(jù)流兩種方式??蛻舳四軌蛲ㄟ^擴(kuò)展解析類讓模塊在內(nèi)部對數(shù)據(jù)流進(jìn)行解析,輸出真實(shí)數(shù)據(jù)。具體如圖1所示。
2 模塊設(shè)計
根據(jù)功能需求,從串口獲取的數(shù)據(jù)流,要能夠根據(jù)實(shí)際情況對二進(jìn)制或者ASCII數(shù)據(jù)流進(jìn)行解析,因此一般通信協(xié)議定義一幀數(shù)據(jù)的格式如下:
數(shù)據(jù)頭+數(shù)據(jù)長度+正式數(shù)據(jù)+檢驗碼+數(shù)據(jù)尾
其中,完整性通常采用檢驗方式來保證,常用的方式有CRC16,CRC32,XOR等方式。工業(yè)對數(shù)據(jù)的安全性要求較高,還會加入重發(fā)機(jī)制等。數(shù)據(jù)的傳輸也有兩種方式,一種是采用二進(jìn)制方式,另一種是ASCII方式。對于ASCII方式,在幀數(shù)據(jù)中可以不要數(shù)據(jù)長度,而在最后使用回車或其他文本作為結(jié)束標(biāo)志。在二進(jìn)制方式中,一個字節(jié)代表一個數(shù)據(jù),通信效率高,而在ASCII方式中,一個字節(jié)只代表一個數(shù)字,但更直觀。因此,串口通信模塊的設(shè)計要能正常接收到串口通信中的數(shù)據(jù)流,能夠?qū)?shù)據(jù)按照幀格式進(jìn)行解析,并能適應(yīng)二進(jìn)制方式或者ASCII方式。上層軟件的開發(fā)只需開發(fā)擴(kuò)展解析類對具體的參數(shù)進(jìn)行簡單設(shè)定,即可完成對協(xié)議的解析,并獲得需要的數(shù)據(jù)。
2.1 模塊基類設(shè)計
為讓客戶端在使用模塊時具有統(tǒng)一接口及成員屬性,設(shè)計人員將基本功能及主要成員屬性設(shè)計到抽象基類中,并利用通用的函數(shù),避免子類重復(fù)編寫相同的代碼,提高了代碼的復(fù)用度。因此,本文定義了抽象基類Base,并在該類中定義3個主要的方法。
(1)AddValue。
AddValue將接收到的字節(jié)數(shù)據(jù)保存至緩存,在此函數(shù)中,需要判斷接收到當(dāng)前字節(jié)數(shù)據(jù)和接收到前一字節(jié)數(shù)據(jù)之間的時間,確保收到的數(shù)據(jù)是連續(xù)一幀數(shù)據(jù)。
(2)GetResult。
該成員函數(shù)為抽象函數(shù),由文本模式或二進(jìn)制模式協(xié)議解析子類具體實(shí)現(xiàn),用于對接收到的數(shù)據(jù)進(jìn)行初步解析,獲得具體的數(shù)據(jù)內(nèi)容。
(3)Analyze。
該成員函數(shù)為抽象函數(shù),由客戶端覆寫,用于從GetResult函數(shù)獲得的數(shù)據(jù)內(nèi)容,將其轉(zhuǎn)換成具體的數(shù)據(jù)對象。
為方便客戶端調(diào)用,定義客戶端數(shù)據(jù)解析的事件——GetNewData,該事件傳遞一個從GetResult函數(shù)中初步解析的數(shù)據(jù),供其內(nèi)部解析。
2.2 文本類數(shù)據(jù)協(xié)議實(shí)現(xiàn)類
該協(xié)議主要用于不同類別數(shù)據(jù)流的解析基類,此類(TextAnalyzeResult)繼承于Base類,并根據(jù)數(shù)據(jù)流特點(diǎn)增加其部分抽象函數(shù)和抽象成員屬性,如幀數(shù)據(jù)開頭標(biāo)志(BeginOfLine)、數(shù)據(jù)結(jié)束標(biāo)志(EndOfLine),并重點(diǎn)實(shí)現(xiàn)GetResult成員函數(shù)。該協(xié)議將根據(jù)其子類設(shè)定的BeginOfLine,EndOfLine字符串對收到的幀數(shù)據(jù)進(jìn)行組裝,形成完整的幀數(shù)據(jù),并對其進(jìn)行完整性判斷及解析,獲取真實(shí)的數(shù)據(jù)部分。具體流程如圖2所示。
2.3 文本協(xié)議客戶端實(shí)現(xiàn)類
對于每種文本數(shù)據(jù)流的協(xié)議,客戶端只需實(shí)現(xiàn)繼承于TextAnalyzeResult類的客戶端類,以TextData類為例。TextData類只需要實(shí)現(xiàn)BeginOfLine和EndOfLine兩個成員屬性,告知系統(tǒng)協(xié)議頭和協(xié)議尾的字符標(biāo)記,可選擇覆寫其父類成員函數(shù)對獲取到的真實(shí)數(shù)據(jù)進(jìn)行分析,解析出每個字符的具體含義,并轉(zhuǎn)換成具體的對象,方便客戶端使用。此類需要根據(jù)不同的通信協(xié)議類別分別進(jìn)行設(shè)計。
2.4 模塊實(shí)現(xiàn)類
模塊實(shí)現(xiàn)類SerialPortCommunication主要是向應(yīng)用軟件提供具體通信功能的類。該類需要實(shí)現(xiàn)具體的串口參數(shù)配置、操作以及調(diào)用前述基類和協(xié)議相關(guān)類對接收到的數(shù)據(jù)進(jìn)行解析。該類主要利用.NET提供的SerialPort串口類實(shí)現(xiàn)對串口數(shù)據(jù)流的讀寫功能,其中讀取功能是在數(shù)據(jù)到達(dá)事件中讀取到數(shù)據(jù)后,保存到緩沖區(qū),利用前述模塊基類的子類,對緩沖區(qū)的數(shù)據(jù)進(jìn)行解析,得到真實(shí)的數(shù)據(jù),并將真實(shí)的數(shù)據(jù)轉(zhuǎn)換成類對象,方便客戶端使用。
3 模塊測試
本次測試實(shí)例為利用C#語言編寫串口通信測試程序解析文本協(xié)議,其具體協(xié)議格式為:幀頭(Start)+數(shù)據(jù)+幀尾(End),客戶端需要解析出具體的數(shù)據(jù),在此只需要定義具體的文本協(xié)議客戶端實(shí)現(xiàn)類TextData,繼承于TextAnalyzeResult類,因此需要覆寫其抽象成員屬性:幀數(shù)據(jù)開頭標(biāo)志(BeginOfLine)、數(shù)據(jù)結(jié)束標(biāo)志(EndOfLine),并將其分別賦值為Start和End。
在具體的界面操作類中,設(shè)置Base類的List列表,利用語言的多態(tài)特性,將TextData類的實(shí)例添加到列表,該實(shí)例需要設(shè)置獲取數(shù)據(jù)事件,以便在界面線程中能獲取到解析出的真實(shí)數(shù)據(jù),再用該列表和具體的串口類(SerialPort)實(shí)例化SerialPortCommun ication,然后在設(shè)置的事件處理函數(shù)中處理接收到的數(shù)據(jù)。具體測試效果如圖3所示。
從圖3可以看出,當(dāng)一次發(fā)送一個或多個完整的數(shù)據(jù)幀時,模塊能正確識別;當(dāng)一個完整的數(shù)據(jù)幀被拆分成兩次或多次發(fā)送時,數(shù)據(jù)啟動超時機(jī)制,數(shù)據(jù)被丟棄;當(dāng)一次發(fā)送的數(shù)據(jù)中包含了一個完整數(shù)據(jù)幀和一個不完整的數(shù)據(jù)幀時,完整的數(shù)據(jù)幀能被正常識別,不完整的數(shù)據(jù)幀將會被丟棄,與設(shè)計的預(yù)期相符。
4 結(jié)語
本文通過使用面向?qū)ο蟮乃枷朐O(shè)計了串口通信的通用協(xié)議解析模塊,將串口通信過程中使用極為廣泛的協(xié)議解析通過基類和子類封裝,客戶端只需要編寫極簡單的協(xié)議格式,模塊即可自動解析出通信協(xié)議中的數(shù)據(jù)。通過測試,該設(shè)計功能簡單實(shí)用,通信穩(wěn)定,能夠有效提高相關(guān)軟件的開發(fā)效率,降低其維護(hù)成本,具有較好的使用價值。
參考文獻(xiàn)
[1]王文娟,李緒凱,王欣,等.基于VS2010的PComm多類型數(shù)據(jù)串口通信軟件設(shè)計[J].電子測試,2018(20):48-50,45.
[2]屈武江.串口數(shù)據(jù)采集系統(tǒng)在VS2008中的設(shè)計與實(shí)現(xiàn)[J].沈陽師范大學(xué)學(xué)報(自然科學(xué)版),2013(3):409-412.
[3]辛王毅,李宇棟.基于C#與Proteus雙輪電機(jī)串口通信系統(tǒng)仿真[J].湖北民族學(xué)院學(xué)報(自然科學(xué)版),2017(1):59-62.
[4]王建,王吳桐.基于LoRa的遠(yuǎn)程激光雷達(dá)數(shù)據(jù)串口采集[J].工業(yè)控制計算機(jī),2020(11):34-35.
[5]蔣萍花,張楠.數(shù)據(jù)采集系統(tǒng)串口通信的設(shè)計與實(shí)現(xiàn)[J].電子測量技術(shù),2015(6):139-142.
[6]陳旭輝,楊紅云.USB接口的虛擬多串口通信設(shè)備設(shè)計[J].單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2020(4):18-21.
(編輯 王雪芬)
Design of scalable serial communication module based on C#
Wang Dong1, Yang Jie2, Tan Lijian1
(1.School of Intelligent Manufacturing, Chongqing Industry amp; Trade Polytechnic, Chongqing 408000, China;
2.School of Artificial Intelligence, Chongqing Industry amp; Trade Polytechnic, Chongqing 408000, China)
Abstract: With the development of intelligence and automation, the demand for networking communication of various devices is getting stronger and stronger. The serial communication is widely used in the process of traditional equipment transformation. For the common serial communication, the protocol parsing and other modules are fused together, which leads to the problem that the protocol parsing module cannot be reused and is difficult to maintain. This paper applies object-oriented thinking and makes full use of the encapsulation, inheritance and polymorphic features of C# language to design an extensible serial communication module. By designing different protocol implementation classes, different communication protocols can be extended, and the client only needs to design a simple implementation class to configure the communication protocol to complete the parsing of the protocol. And the communication protocol in text data format is taken as an example and tested practically, the module is stable and reliable and has high practicality.
Key words: serial port; communication protocol; OOP; extensible