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

C#串口高效可靠的接收方案設計

2018-12-06 09:27:16劉馬飛
物聯網技術 2018年8期
關鍵詞:程序

劉馬飛

摘 要:在事件觸發方式接收串口數據包時,尤其在數據包不定長的情況下,需要仔細設計接收方案,否則會出現數據包接收不完整的情況。文中介紹了一種C#平臺下串口數據包的接收方案,可高效可靠地接收串口數據包,對C#串口應用程序的設計開發具有指導意義。

關鍵詞:C#;RS 232;串口通信;數據接收

中圖分類號:TP302 文獻標識碼:A 文章編號:2095-1302(2018)08-00-03

0 引 言

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

1 C#串口常見數據接收方案

C#串口常見數據接收方法為在DataReceived事件響應函數中,首先查詢接收緩沖區的字節數,然后申請一段字節數組的內存空間,再調用SerialPort對象SPCOM的Read函數,將串口接收緩沖區的數據讀取到字節數組中,最后對字節數組進行處理。

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

private void spCOM_DataReceived(object sender,SerialData ReceivedEventArgs e)

{

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

//進行串口數據接收操作

int icount = spCOM.BytesToRead;

byte[] data = new byte[icount];

spCOM.Read(data,0,icount);

//對數據包進行處理操作

}

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

2 C#串口高效可靠的數據接收方案

根據上述分析,串口數據接收方案的高效性要求當串口接收緩沖區存在數據時,需要立即進行數據接收操作,因此串口控件的ReceivedBytesThreshold屬性取默認值1,且在DataReceived事件響應函數中接收串口數據前不進行線程休眠。為了避免數據包接收不完整的情況出現,需要應用程序對串口接收到的數據重新組裝,精確定位數據包的開頭和結尾,再進行數據包的處理,從而實現數據接收的可靠性。

2.1 串口數據報文格式

本文以串口接收思遠創智能設備10系列高頻RFID全協議讀寫器的數據包為例,闡述接收方案。該讀寫器返回的數據包長度不固定,其格式如圖1所示。

2.2 高效可靠接收的實現

為了對接收到的串口數據包重新組裝,需要應用程序創建緩沖區。首先將接收到的串口數據填充到接收緩沖區,然后在接收緩沖區從前往后搜索包開始標記STX與接收標記ETX,從而可以獲得完整數據包。方案實現步驟如下:

(1)應用程序將創建類型為字節的泛型列表對象作為程序緩沖區,即在窗體成員變量中定義List recv_buf = new List()。

(2)在DataReceived事件響應函數中,首先定義兩個布爾變量data_sta_catched與data_end_catched,表示是否已經尋找到數據包頭和數據包結束標志,然后將串口接收緩沖區中的數據添加到程序緩沖區。

(3)判斷程序緩沖區是否包含一個完整的數據包。判斷步驟如下:

①由于數據包的大小必然大于或等于6 B,因此,首先判斷程序緩沖區字節數是否大于或等于6。若條件滿足,則進行后續判斷;否則,結束判斷。

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

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

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

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

方案的實現代碼如下:

private void spCOM_DataReceived(object sender,SerialData ReceivedEventArgs e)

{//定義兩個標志,記錄是否找到數據包開始和數據包結束

bool data_sta_catched=false;

bool data_end_catched=false;

//把本次數據添加到接收緩沖中

int iCount = 0,idx;

iCount = spCOM.BytesToRead;

byte[] bData = new byte[iCount];

spCOM.Read(bData,0,iCount);

recv_buf.AddRange(bData);

//尋找數據包的開始位置和結束位置,數據包大小必然等于6

int len_packet=0;

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

{

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

{

if(recv_buf[0] == 2)

{

data_sta_catched = true;

break;

}

else

{

recv_buf.RemoveAt(0);

}

}

//找到數據包頭后,再來檢查是否已經收到完整數據包

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;

}

}

}

}

//收到完整數據包,解析數據包

if(data_sta_catched&& data_end_catched)

{

//對數據包進行處理,然后將該數據包從緩沖區中移除

recv_buf.RemoveRange(0,len_packet);

}

}

方案驗證:

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

時性。

為了驗證接收方案的可靠性,避免數據中偽數據包頭和偽數據包結束標志對數據包接收造成干擾而引起丟包,避免硬件電路中熱噪聲對接收方案的可靠性檢測產生干擾,采用虛擬串口軟件創建一對虛擬串口COM1和COM2進行模擬。測試程序中創建發送線程不間斷發送100 000個不定長的數據包到COM1,然后利用本文接收方案在COM2上進行串口數據接收,可成功接收到100 000個數據包。

從測試結果可以看出,本文接收方案成功避免了數據中偽數據包頭和偽數據包結束標志對數據包接收造成干擾而引起丟包的現象,從而證明該接收方案具有高可靠性。

3 結 語

本文介紹了一種在C#平臺下串口數據包的接收方案,通過應用程序增加緩沖區對數據包重組,避免了簡單接收時數據包丟失的不足,可高效、可靠地接收串口數據包,對C#串口應用程序的設計開發具有指導意義。

參考文獻

[1]邱曉榮.《物聯網設備編程與實施》課程的構建與實施[J].物聯網技術,2015,5(7):96-97.

[2]陳天娥.物聯網設備編程與實施[M].北京:高等教育出版社,2014.

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

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

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

[5]于潤偉. C#項目實訓教程[M].北京:電子工業出版社,2009.

[6]高超.組合導航計算機高效多串口通訊技術的設計與實現[J].數字技術與應用,2016(1):197.

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

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

猜你喜歡
程序
給Windows添加程序快速切換欄
電腦愛好者(2020年6期)2020-05-26 09:27:33
試論我國未決羈押程序的立法完善
人大建設(2019年12期)2019-05-21 02:55:44
失能的信仰——走向衰亡的民事訴訟程序
“程序猿”的生活什么樣
英國與歐盟正式啟動“離婚”程序程序
環球時報(2017-03-30)2017-03-30 06:44:45
基于VMM的程序行為異常檢測
偵查實驗批準程序初探
我國刑事速裁程序的構建
創衛暗訪程序有待改進
中國衛生(2015年3期)2015-11-19 02:53:32
恐怖犯罪刑事訴訟程序的完善
主站蜘蛛池模板: 亚洲国产精品一区二区高清无码久久| 日韩黄色在线| 五月婷婷导航| 亚洲欧美不卡中文字幕| 亚洲swag精品自拍一区| 手机在线国产精品| 美女毛片在线| 欧美亚洲国产精品久久蜜芽| 欧美国产成人在线| 国产成人调教在线视频| 高潮毛片免费观看| 亚洲国产成熟视频在线多多| 九色91在线视频| 成年午夜精品久久精品| 国产一级片网址| av在线人妻熟妇| 国产精品私拍在线爆乳| 日韩欧美国产区| 日韩大片免费观看视频播放| 伊人国产无码高清视频| 国产精品亚洲日韩AⅤ在线观看| 色网站免费在线观看| 国产91导航| 91精品aⅴ无码中文字字幕蜜桃| 日本道综合一本久久久88| 黄色网站在线观看无码| 91精品国产丝袜| 国产一区二区三区在线观看视频| 久久久受www免费人成| 国产精品人成在线播放| 国产另类乱子伦精品免费女| 天天综合网色中文字幕| 91福利国产成人精品导航| 毛片视频网| 午夜福利亚洲精品| 久久免费视频播放| 久久久国产精品无码专区| 久久久精品国产SM调教网站| 五月天久久婷婷| 99免费视频观看| 91精品免费高清在线| 亚洲美女一区| 深夜福利视频一区二区| 亚洲三级a| 国产精品久久自在自线观看| 六月婷婷激情综合| 日本精品影院| 九色最新网址| 免费一级毛片在线播放傲雪网| 中文字幕调教一区二区视频| 一个色综合久久| 欧美精品啪啪一区二区三区| 无码日韩精品91超碰| 热re99久久精品国99热| 精品99在线观看| 好紧太爽了视频免费无码| 欧美三级不卡在线观看视频| 欧美午夜在线观看| 国产亚洲视频在线观看| 91九色最新地址| 国产成人1024精品下载| 亚洲色图欧美视频| 久久久精品久久久久三级| 老司国产精品视频| 国产91小视频在线观看| 激情影院内射美女| 91精品国产91久久久久久三级| 真实国产乱子伦视频| 人妻丰满熟妇AV无码区| 欧美午夜精品| 国产九九精品视频| 亚洲乱强伦| 久久久久国产一级毛片高清板| 国产青榴视频在线观看网站| 国产第一页第二页| 日本在线免费网站| 国产一级二级三级毛片| 日韩国产另类| 国产69囗曝护士吞精在线视频| 四虎成人精品在永久免费| 欧美日本激情| 亚洲无线国产观看|