使用了SerialPort類接收串口通訊的報文。報文格式是0xF3 xx xx xx。。。xx xx 0xFD。其中報頭是F3,報尾是FD。xx是資料,報文長度是不固定的。相鄰兩個報文之間間隔約500毫秒。考慮了下面幾種判斷報文的方法,但是都不成功:
1、采用最常見的方法,設定屬性port.ReceivedBytesThreshold ,收到設定數量的位元組資料后觸發接收事件port.DataReceived,因為報文長度不固定,所以無法使用這個方法。
2、使用讀取方法port.ReadTo(Encoding.ASCII.GetString(new byte[1] { 0xFD })),當讀到報尾時則停止。除錯發現,始終讀不到資料,估計原因是ascii值0xFD對應的不是一個可列印字符。
3、感覺最合理的方法應該是:當串口持續一段時間例如100ms,沒有收到資料,則讀取緩沖區所有資料,并判斷報頭報尾。但是這種方法怎樣寫代碼呢?SerialPort.ReadTimeout似乎并不合適。難道是要開一個100mS的timer嗎?
4、因為一個報文里的相鄰兩個位元組資料之間,時間間隔幾乎等于零,所以每接收到一個位元組就去讀取并判斷一次,這樣的方法時間上來不及。
應該采用哪種方法呢?望高手指教,感謝!
uj5u.com熱心網友回復:
你這種就適合無限監聽接收,將收到的資料放入一個佇列中,然后異步從佇列中提取片段決議。uj5u.com熱心網友回復:
感謝回復!
“無限監聽接收,將收到的資料放入一個佇列中”,代碼應該怎樣寫,可以大致說一下嗎,謝謝
uj5u.com熱心網友回復:
每收到對方設備發來的報文后,我都要及時回復,所以不能接收很多資料后,再事后慢慢去決議。
uj5u.com熱心網友回復:
在收到設定數量的位元組資料后觸發接收事件中,先把資料讀取出來保存到佇列里面,然后在佇列里面決議,決議到一個完整的幀則呼叫處理代碼uj5u.com熱心網友回復:
拿串口助手試一下,發送到回傳資料多少毫秒, 2個資料包間隔 500毫秒足夠了,除非回傳的資料特別慢uj5u.com熱心網友回復:
While(!Stop){
byte[] data=https://bbs.csdn.net/topics/new byte[1024];//1024設定為資料最大長度,如果性能要求不高,用List
While(不是結束符){
向data中加入讀取的一個byte ;
}
處理data;
}
uj5u.com熱心網友回復:
資料協議一般要包含包頭,資料,包尾三部分的,包頭一般處理資料長度等資訊,包尾一般包含校驗資訊和結束符等內容,完整的資料協議才能較好的處理各種例外.uj5u.com熱心網友回復:
偽代碼不是很嚴謹,大致思路
uj5u.com熱心網友回復:
1.你接收資料是十六進制的資料不是ASCII。可以使用如下:comm.Read(buf, 0, n);
foreach (byte b in buf)//將報文保存到字串
{
//依次的拼接出16進制字串
builder.Append(b.ToString("X2"));
}
data.AddRange(buf);//或者報文保存到byte【】中,
2.開一個執行緒分析byte【】
從第一個位元組分析 F3,沒有洗掉
找到0xFD,開始分析報文,完成后洗掉
繼續
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/194804.html
標籤:C#
上一篇:除以0為什么不報錯?
下一篇:一直不斷技術轉型中,回來看看
