999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

C#串口高效可靠的接收方案設(shè)計(jì)

2018-12-06 09:27:16劉馬飛
物聯(lián)網(wǎng)技術(shù) 2018年8期
關(guān)鍵詞:程序

劉馬飛

摘 要:在事件觸發(fā)方式接收串口數(shù)據(jù)包時(shí),尤其在數(shù)據(jù)包不定長的情況下,需要仔細(xì)設(shè)計(jì)接收方案,否則會(huì)出現(xiàn)數(shù)據(jù)包接收不完整的情況。文中介紹了一種C#平臺(tái)下串口數(shù)據(jù)包的接收方案,可高效可靠地接收串口數(shù)據(jù)包,對(duì)C#串口應(yīng)用程序的設(shè)計(jì)開發(fā)具有指導(dǎo)意義。

關(guān)鍵詞:C#;RS 232;串口通信;數(shù)據(jù)接收

中圖分類號(hào):TP302 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):2095-1302(2018)08-00-03

0 引 言

C#.NET提供SerialPort類進(jìn)行串口數(shù)據(jù)收發(fā)通信。C#串口編程是職業(yè)教育物聯(lián)網(wǎng)應(yīng)用技術(shù)專業(yè)資源庫主干課程《物聯(lián)網(wǎng)設(shè)備編程與實(shí)施》的核心內(nèi)容之一[1]。在使用SerialPort進(jìn)行數(shù)據(jù)接收時(shí),面臨著“不知何時(shí)讀”的困境,通常采用系統(tǒng)封裝的事件觸發(fā)方式進(jìn)行數(shù)據(jù)接收[2],即C# SerialPort類封裝了DataReceived事件,當(dāng)串口接收緩沖區(qū)收到數(shù)據(jù)的字節(jié)數(shù)超過SerialPort串口屬性ReceivedBytesThreshold的值時(shí),系統(tǒng)將觸發(fā)DataReceived事件,調(diào)用該事件的響應(yīng)函數(shù),因此,可在該事件的響應(yīng)函數(shù)中進(jìn)行串口數(shù)據(jù)接收操作[1]。本文介紹了常規(guī)的DataReceived事件驅(qū)動(dòng)數(shù)據(jù)接收方法,提出了一種高效可靠的數(shù)據(jù)接收方案,并對(duì)可靠性進(jìn)行了仿真驗(yàn)證。

1 C#串口常見數(shù)據(jù)接收方案

C#串口常見數(shù)據(jù)接收方法為在DataReceived事件響應(yīng)函數(shù)中,首先查詢接收緩沖區(qū)的字節(jié)數(shù),然后申請(qǐng)一段字節(jié)數(shù)組的內(nèi)存空間,再調(diào)用SerialPort對(duì)象SPCOM的Read函數(shù),將串口接收緩沖區(qū)的數(shù)據(jù)讀取到字節(jié)數(shù)組中,最后對(duì)字節(jié)數(shù)組進(jìn)行處理。

串口通信設(shè)備傳遞的數(shù)據(jù)包通常為不定長數(shù)據(jù)包,因此ReceivedBytesThreshold通常取默認(rèn)值1,表示串口接收緩沖區(qū)的字節(jié)數(shù)大于或等于1便觸發(fā)DataReceived事件。由于DataReceived事件的觸發(fā)和處理運(yùn)行在輔助線程上,DataReceived事件觸發(fā)與DataReceived事件被處理而調(diào)用響應(yīng)函數(shù)之間存在微小的時(shí)延。因此,當(dāng)串口接收一個(gè)數(shù)據(jù)包時(shí),可能出現(xiàn)在收到數(shù)據(jù)包第一個(gè)字節(jié)時(shí)觸發(fā)DataReceived事件,而當(dāng)該DataReceived事件被處理時(shí),數(shù)據(jù)包并未接收完畢;也可能出現(xiàn)串口接收一個(gè)數(shù)據(jù)包時(shí),觸發(fā)多次DataReceived事件的情況。在串口數(shù)據(jù)包出現(xiàn)時(shí)間間隔較大的情況下,可以采用一般可靠的方法,即在進(jìn)行串口數(shù)據(jù)接收操作之前,調(diào)用Thread.Sleep(100)休眠100 ms后,再進(jìn)行數(shù)據(jù)接收操作,如此一來便降低了程序的響應(yīng)速度[3-4]。操作程序如下:

private void spCOM_DataReceived(object sender,SerialData ReceivedEventArgs e)

{

Thread.Sleep(100)//數(shù)據(jù)接收操作先休眠100 ms

//進(jìn)行串口數(shù)據(jù)接收操作

int icount = spCOM.BytesToRead;

byte[] data = new byte[icount];

spCOM.Read(data,0,icount);

//對(duì)數(shù)據(jù)包進(jìn)行處理操作

}

數(shù)據(jù)包通常包含有一定的包頭和包結(jié)束標(biāo)志,用于表征數(shù)據(jù)包的完整性。對(duì)于數(shù)據(jù)包的處理,必須在接收到完整數(shù)據(jù)包的前提下方可進(jìn)行。當(dāng)較多數(shù)據(jù)包到達(dá)間隔接近或過長時(shí),使其休眠一段時(shí)間的方式可能并不奏效,如果簡單判斷包頭結(jié)束標(biāo)志不正確就丟棄數(shù)據(jù),可能導(dǎo)致丟包,因此需要采用高效可靠的接收方案。

2 C#串口高效可靠的數(shù)據(jù)接收方案

根據(jù)上述分析,串口數(shù)據(jù)接收方案的高效性要求當(dāng)串口接收緩沖區(qū)存在數(shù)據(jù)時(shí),需要立即進(jìn)行數(shù)據(jù)接收操作,因此串口控件的ReceivedBytesThreshold屬性取默認(rèn)值1,且在DataReceived事件響應(yīng)函數(shù)中接收串口數(shù)據(jù)前不進(jìn)行線程休眠。為了避免數(shù)據(jù)包接收不完整的情況出現(xiàn),需要應(yīng)用程序?qū)Υ诮邮盏降臄?shù)據(jù)重新組裝,精確定位數(shù)據(jù)包的開頭和結(jié)尾,再進(jìn)行數(shù)據(jù)包的處理,從而實(shí)現(xiàn)數(shù)據(jù)接收的可靠性。

2.1 串口數(shù)據(jù)報(bào)文格式

本文以串口接收思遠(yuǎn)創(chuàng)智能設(shè)備10系列高頻RFID全協(xié)議讀寫器的數(shù)據(jù)包為例,闡述接收方案。該讀寫器返回的數(shù)據(jù)包長度不固定,其格式如圖1所示。

2.2 高效可靠接收的實(shí)現(xiàn)

為了對(duì)接收到的串口數(shù)據(jù)包重新組裝,需要應(yīng)用程序創(chuàng)建緩沖區(qū)。首先將接收到的串口數(shù)據(jù)填充到接收緩沖區(qū),然后在接收緩沖區(qū)從前往后搜索包開始標(biāo)記STX與接收標(biāo)記ETX,從而可以獲得完整數(shù)據(jù)包。方案實(shí)現(xiàn)步驟如下:

(1)應(yīng)用程序?qū)?chuàng)建類型為字節(jié)的泛型列表對(duì)象作為程序緩沖區(qū),即在窗體成員變量中定義List recv_buf = new List()。

(2)在DataReceived事件響應(yīng)函數(shù)中,首先定義兩個(gè)布爾變量data_sta_catched與data_end_catched,表示是否已經(jīng)尋找到數(shù)據(jù)包頭和數(shù)據(jù)包結(jié)束標(biāo)志,然后將串口接收緩沖區(qū)中的數(shù)據(jù)添加到程序緩沖區(qū)。

(3)判斷程序緩沖區(qū)是否包含一個(gè)完整的數(shù)據(jù)包。判斷步驟如下:

①由于數(shù)據(jù)包的大小必然大于或等于6 B,因此,首先判斷程序緩沖區(qū)字節(jié)數(shù)是否大于或等于6。若條件滿足,則進(jìn)行后續(xù)判斷;否則,結(jié)束判斷。

②在程序緩沖區(qū)從前往后尋找數(shù)據(jù)包頭STX(0x02),對(duì)于非數(shù)據(jù)包頭的數(shù)據(jù),將其移出程序緩沖區(qū),確保尋找到的數(shù)據(jù)包頭位于程序緩沖區(qū)的開始位置。尋找到數(shù)據(jù)包頭后,將data_sta_catched置為True,并結(jié)束尋找。

③若已成功尋找到數(shù)據(jù)包頭,則檢查數(shù)據(jù)包結(jié)束標(biāo)志以確定是否已經(jīng)收到完整數(shù)據(jù)包。由于數(shù)據(jù)包頭STX位于程序緩沖的開始位置,程序緩沖的第三個(gè)字節(jié)為數(shù)據(jù)包的DATALENGTH字段,表征了數(shù)據(jù)包中數(shù)據(jù)字節(jié)的長度,即包括STATUS 和DATA 域的字節(jié)數(shù),因此本數(shù)據(jù)包的總長度應(yīng)在DATALENGTH字段值上加5。

可首先通過判斷程序緩沖區(qū)中的字節(jié)數(shù)是否大于或等于當(dāng)前數(shù)據(jù)包的總長度。若條件滿足,則通過DATALENGTH字段推斷數(shù)據(jù)包結(jié)束字節(jié)位置,并判斷該字節(jié)是否為數(shù)據(jù)包結(jié)束標(biāo)志ETX(0x03)。若該字節(jié)為數(shù)據(jù)包結(jié)束標(biāo)志,表明成功尋找到了數(shù)據(jù)包,則置data_end_catched為True,并確定數(shù)據(jù)包的長度len_packet;若該字節(jié)不為數(shù)據(jù)包結(jié)束標(biāo)志,則可斷定②中data_sta_catched并非真正的數(shù)據(jù)包開頭,因此刪除該偽數(shù)據(jù)包頭,并置data_sta_catched為False。

④判斷data_sta_catched和data_end_catched是否均為True,若條件滿足,則程序緩沖區(qū)從字節(jié)0位置開始已包含一個(gè)完整的數(shù)據(jù)包,該數(shù)據(jù)包長度為len_packet,因此便可對(duì)該數(shù)據(jù)包進(jìn)行處理,處理完畢后需要將該數(shù)據(jù)包從程序緩沖區(qū)中刪除。

方案的實(shí)現(xiàn)代碼如下:

private void spCOM_DataReceived(object sender,SerialData ReceivedEventArgs e)

{//定義兩個(gè)標(biāo)志,記錄是否找到數(shù)據(jù)包開始和數(shù)據(jù)包結(jié)束

bool data_sta_catched=false;

bool data_end_catched=false;

//把本次數(shù)據(jù)添加到接收緩沖中

int iCount = 0,idx;

iCount = spCOM.BytesToRead;

byte[] bData = new byte[iCount];

spCOM.Read(bData,0,iCount);

recv_buf.AddRange(bData);

//尋找數(shù)據(jù)包的開始位置和結(jié)束位置,數(shù)據(jù)包大小必然等于6

int len_packet=0;

if(recv_buf.Count >= 6)//判斷程序緩沖區(qū)是否大于6

{

while(recv_buf.Count > 0)//從前往后尋找數(shù)據(jù)包頭0x02

{

if(recv_buf[0] == 2)

{

data_sta_catched = true;

break;

}

else

{

recv_buf.RemoveAt(0);

}

}

//找到數(shù)據(jù)包頭后,再來檢查是否已經(jīng)收到完整數(shù)據(jù)包

if(data_sta_catched)

{

iCount= Convert.ToInt32(recv_buf[2]);

if(recv_buf.Count >= iCount + 5)

{

if(recv_buf[iCount + 4] == 3)

{

data_end_catched = true;

len_packet = iCount + 5;

}

else

{

recv_buf.RemoveAt(0);

data_sta_catched = false;

}

}

}

}

//收到完整數(shù)據(jù)包,解析數(shù)據(jù)包

if(data_sta_catched&& data_end_catched)

{

//對(duì)數(shù)據(jù)包進(jìn)行處理,然后將該數(shù)據(jù)包從緩沖區(qū)中移除

recv_buf.RemoveRange(0,len_packet);

}

}

方案驗(yàn)證:

由于接收操作摒棄了常規(guī)方法中的增加線程休眠方式,因此數(shù)據(jù)接收的高效性通過Windows線程并發(fā)得以保證,讀者可將方案在C#串口通信程序中實(shí)現(xiàn),觀察接收數(shù)據(jù)的實(shí)

時(shí)性。

為了驗(yàn)證接收方案的可靠性,避免數(shù)據(jù)中偽數(shù)據(jù)包頭和偽數(shù)據(jù)包結(jié)束標(biāo)志對(duì)數(shù)據(jù)包接收造成干擾而引起丟包,避免硬件電路中熱噪聲對(duì)接收方案的可靠性檢測(cè)產(chǎn)生干擾,采用虛擬串口軟件創(chuàng)建一對(duì)虛擬串口COM1和COM2進(jìn)行模擬。測(cè)試程序中創(chuàng)建發(fā)送線程不間斷發(fā)送100 000個(gè)不定長的數(shù)據(jù)包到COM1,然后利用本文接收方案在COM2上進(jìn)行串口數(shù)據(jù)接收,可成功接收到100 000個(gè)數(shù)據(jù)包。

從測(cè)試結(jié)果可以看出,本文接收方案成功避免了數(shù)據(jù)中偽數(shù)據(jù)包頭和偽數(shù)據(jù)包結(jié)束標(biāo)志對(duì)數(shù)據(jù)包接收造成干擾而引起丟包的現(xiàn)象,從而證明該接收方案具有高可靠性。

3 結(jié) 語

本文介紹了一種在C#平臺(tái)下串口數(shù)據(jù)包的接收方案,通過應(yīng)用程序增加緩沖區(qū)對(duì)數(shù)據(jù)包重組,避免了簡單接收時(shí)數(shù)據(jù)包丟失的不足,可高效、可靠地接收串口數(shù)據(jù)包,對(duì)C#串口應(yīng)用程序的設(shè)計(jì)開發(fā)具有指導(dǎo)意義。

參考文獻(xiàn)

[1]邱曉榮.《物聯(lián)網(wǎng)設(shè)備編程與實(shí)施》課程的構(gòu)建與實(shí)施[J].物聯(lián)網(wǎng)技術(shù),2015,5(7):96-97.

[2]陳天娥.物聯(lián)網(wǎng)設(shè)備編程與實(shí)施[M].北京:高等教育出版社,2014.

[3] NAGEL C,GLYNN J,SKINNER M. C#高級(jí)編程(9版)[M].

李銘,譯.北京:清華大學(xué)出版社,2015.

[4] PERKINS B , HAMMER J V , REID J D. C#入門經(jīng)典(7版)[M].齊立波,黃俊偉,譯.北京:清華大學(xué)出版社,2016.

[5]于潤偉. C#項(xiàng)目實(shí)訓(xùn)教程[M].北京:電子工業(yè)出版社,2009.

[6]高超.組合導(dǎo)航計(jì)算機(jī)高效多串口通訊技術(shù)的設(shè)計(jì)與實(shí)現(xiàn)[J].數(shù)字技術(shù)與應(yīng)用,2016(1):197.

[7]王斌,張林,鄧軍.一種基于高速串口通信的高效數(shù)據(jù)處理方法[J].自動(dòng)化技術(shù)與應(yīng)用,2016,35(6):57-60.

[8]鄭武,肖寶森.串口通信新模型的研究與C#實(shí)現(xiàn)[J].電腦編程技巧與維護(hù),2013(13):29-30.

猜你喜歡
程序
給Windows添加程序快速切換欄
電腦愛好者(2020年6期)2020-05-26 09:27:33
試論我國未決羈押程序的立法完善
失能的信仰——走向衰亡的民事訴訟程序
“程序猿”的生活什么樣
英國與歐盟正式啟動(dòng)“離婚”程序程序
基于VMM的程序行為異常檢測(cè)
偵查實(shí)驗(yàn)批準(zhǔn)程序初探
我國刑事速裁程序的構(gòu)建
創(chuàng)衛(wèi)暗訪程序有待改進(jìn)
恐怖犯罪刑事訴訟程序的完善
主站蜘蛛池模板: 亚洲天堂精品视频| 国产欧美日韩另类精彩视频| 久久精品只有这里有| 欧美国产日韩在线| 996免费视频国产在线播放| 超碰91免费人妻| 国产99视频在线| 欧美日韩北条麻妃一区二区| 国产欧美在线| 国产一级小视频| 国产成人精品2021欧美日韩 | 搞黄网站免费观看| 国产不卡在线看| 国产十八禁在线观看免费| 在线亚洲天堂| 天堂av高清一区二区三区| 在线免费亚洲无码视频| 国产精品yjizz视频网一二区| 亚洲精品黄| AⅤ色综合久久天堂AV色综合| 拍国产真实乱人偷精品| 99精品在线看| 精品伊人久久久香线蕉 | 国产成人综合日韩精品无码不卡| 91无码人妻精品一区| 色呦呦手机在线精品| 手机精品视频在线观看免费| 97视频在线观看免费视频| 亚洲人成网站日本片| 91毛片网| 尤物成AV人片在线观看| 久热这里只有精品6| 色天堂无毒不卡| 成人在线综合| 国产成人综合在线观看| 成人噜噜噜视频在线观看| 国产色婷婷| 亚洲女同一区二区| 国产日韩丝袜一二三区| 精品欧美视频| 亚洲视频在线观看免费视频| 欧美 亚洲 日韩 国产| 国产丝袜无码一区二区视频| 欧美天堂在线| 日韩欧美国产另类| 日韩第一页在线| 亚洲无码视频一区二区三区| 午夜人性色福利无码视频在线观看| 亚洲AV无码久久精品色欲| 国产女主播一区| 亚洲男人天堂久久| 啪啪啪亚洲无码| 韩日免费小视频| 四虎影视国产精品| 欧美中文字幕一区二区三区| 亚洲日韩国产精品综合在线观看| 国产精品成人啪精品视频| 国产午夜人做人免费视频中文| 亚洲精品视频免费看| 亚洲va视频| 六月婷婷精品视频在线观看| 操国产美女| 黄色一级视频欧美| 欧美视频在线不卡| 精品一区二区久久久久网站| 精品91视频| 国产超碰一区二区三区| 精品1区2区3区| 黄色不卡视频| 欧美性精品不卡在线观看| 刘亦菲一区二区在线观看| 亚洲一道AV无码午夜福利| 国产日韩欧美黄色片免费观看| 国产亚洲精| 精品视频在线一区| 色爽网免费视频| 制服无码网站| www.亚洲色图.com| 亚洲啪啪网| 91久久性奴调教国产免费| 操操操综合网| 夜色爽爽影院18禁妓女影院|