C# 串口操做系列(5)--通信庫雛形

C# 串口操做系列(5)--通信庫雛形

標籤: 通信c#數據分析byteclassstring
 分類:
 

串口是很簡單的,編寫基於串口的程序也很容易。新手們除了要面對一堆的生僻概念,以及跨線程訪問的細節,還有一個須要跨越的難題,就是協議解析,上一篇已經說明了:數組

一個二進制格式的協議通常包含: 協議頭 + 數據段長度 + 數據  + 校驗緩存

一個Ascii格式的文本協議,通常包含: 數據頭 + 正文 + 數據結束標識框架

相似的命令可能不少,相似的代碼也會重複寫不少次。對於我,並不以爲這個有任何難度,可是,不少時候,須要寫點相似東西的時候呢,我每每不想寫,不是別的,要搭建一個這樣的框架,這絕對是個體力活,並且還須要耐心細心ide

從我上一次帶項目,我就開始考慮編寫通用的一個通信庫,支持不少功能,不過和公司內容結合緊密,不適合開源,更不適合推廣。我從新組織、抽象了各個概念。但願能讓新人朋友減小學習難度,更快的投入到其餘方面。post

 

請注意,此文章我也不知道如何概括,不算科普,不能算類庫的介紹,我是在介紹如何設計一個這樣的通信庫。學習

通信庫,並不是串口庫,因此,我但願有一個基類,能夠描述各類通信方法的基類或接口,微軟已經這麼作了,他把這個叫作Stream。我認爲很差的理由是,提供了Length屬性、peek方法、seek方法卻沒法使用,不少方法和屬性是不支持的,若是使用這個類操做硬件,就像一顆地雷,不當心就會寫一個不支持的操做,並且會在運行時報錯。因此,我但願能針對流設備的硬件,從新設計,我抽象出了一個接口:ICommunication。提供基本的打開、關閉、讀寫、字符集和有效數據長度等流設備的特性和操做。this

爲了能有一個通用的配置類,我定義了一個接口:ICommunicationSetting。spa

當你實現一個設備的時候,你須要實現ICommunication,還須要編寫一個設置的類,去實現ICommunicationSetting接口。別以爲麻煩,這是爲了能抽象的好,編寫一個一勞永逸不用常常重寫的通用代碼。有了2個接口,我甚至能夠開始編寫依賴此接口的功能或軟件了。固然,我還有須要寫有關協議的分析。.net

既然協議是分2種,那天然要編寫BinaryXXX和TextXXX,沒錯,有這樣2個類。

考慮的更詳細一點,任何數據,都不是無限期有效的,好比你獲取下位機發來的電壓,過了幾秒了,應該就無效了,因此要考慮定時失效,因而我實現了有效性檢查。數據要在字節數組中查找,分析,通知。因此這些公共的部分,我抽出來了,我寫了一個接口,叫作:IAnalyzer,並編寫了默認的實現,因而有了AnalyzeResult類,同時,區分2種協議方式,建立了子類:BinaryAnalyzeResult和TextAnalyzeResult。

那麼,誰來使用ICommunication,IAnalyzer呢?放心,聯繫有點緊密,我不會撒手扔給外面的,這樣作反而更復雜了,不是麼。因此我寫了一個帶有分析功能的類:WyzComm。

使用通信庫的

這個類實現了數據的採集、緩存、分析器的調用,以及事件調用的通知。數據死鎖的控制,全部你認爲的麻煩事情,都在這裏作了。那麼,我編寫這個類的時候,我確定不知道將來有多少種協議是否是?那怎麼辦呢?我沒法寫死分析器,因此,我編寫了接口:IAnalyzerCollection,由於文章從串口提及,我首先提供了串口的實現:

SerialPort(此類和微軟的那個名字同樣而已,但不是同一個),實現了ICommunication接口,我定義了一個SerialPortSetting類,實現了ICommunicationSetting。

至此。通信庫的框架就完成了。而這也就是使用通信庫所須要關注的全部內容。下面,爲了能進行實際的演示,我編寫了簡單的實現。來演示一種功能,假設我有個程序,須要同時分析二進制數據格式和ASCII的文本數據格式,數據各不相同,使用了通信庫以後,我不須要重寫數據的緩存、關閉的死鎖處理、數據對界面的通知。我只須要編寫2個協議類,和1個協議集合類。個人數據分析工做就完成了。

 

首先是一個文本協議,協議頭是WYZ,協議尾是回車換行,中間是一個整形數字。我只須要設置好頭、尾,編寫數據分析。

 

[c-sharp]  view plain  copy
 
  1. public class MyData1 : TextAnalyzeResult<int>  
  2. {  
  3.     public MyData1()  
  4.     {  
  5.         this.BeginOfLine = "WYZ";  
  6.         this.EndOfLine = "/r/n";  
  7.     }  
  8.   
  9.     public override void Analyze()  
  10.     {  
  11.         string s = Encoding.GetString(Raw);  
  12.         Match m = Regex.Match(s, "//d+");  
  13.         if (m.Success)  
  14.         {  
  15.             this.Data = int.Parse(m.Value);  
  16.             this.Valid = true;  
  17.         }  
  18.     }  
  19. }  

 

 

而後我定義了一個二進制協議,分析一條數據包含2個子項。

我首先定義這個數據的具體類型

 

[c-sharp]  view plain  copy
 
  1. public class SampleData  
  2. {  
  3.     public int Version { get; set; }  
  4.     public float Voltage { get; set; }  
  5.     public SampleData()  
  6.     {  
  7.         Version = 0;  
  8.         Voltage = 0;  
  9.     }  
  10.     public override string ToString()  
  11.     {  
  12.         return string.Format("{0},{1}", Version.ToString(), Voltage.ToString());  
  13.     }  
  14. }  

 

而後我編寫協議分析類

 

[c-sharp]  view plain  copy
 
  1. public class MyData2 : BinaryAnalyzeResult<SampleData>  
  2. {  
  3.     public MyData2()  
  4.     {  
  5.         this._mask = new byte[] { 0xAA, 0xBB, 0xCC };  
  6.         this.TimeOut = 5;//超過5秒,收不到數據,則此數據無效。  
  7.         //自定義校驗方法,演示爲逐個相加和隨便一個數字取模,我選擇的是42  
  8.         this.checksum = (buf, offset, count) =>  
  9.             {  
  10.                 byte checksum = 0;  
  11.                 for (int i = offset; i < offset + count; i++)  
  12.                 {  
  13.                     checksum = (byte)((checksum + buf[i]) % 42);  
  14.                 }  
  15.                 return checksum;  
  16.             };  
  17.     }  
  18.   
  19.     public override void Analyze()  
  20.     {  
  21.         int offset = _mask.Length + LenLength;//_mask.Length表示標記後的一個字節,_mask.Length+1表示標記後的第二個字節,有一個字節表示長度。  
  22.         this.Data.Version = BitConverter.ToInt32(Raw, offset + 0);  
  23.         this.Data.Voltage = BitConverter.ToSingle(Raw, offset + 4);  
  24.         this.Valid = true;//注意要設置數據有效狀態  
  25.     }  
  26. }  

 

 

完成了。一個基於串口的,同時分析2種數據的,數據具備有效性判斷,支持獨立數據通知界面,總體原始數據緩存顯示的功能。完成了。

爲了演示功能,我寫了新的校驗方式,固然,你不用管,默認已經支持了異或校驗,後續還會把經常使用校驗都添加進去,crc16,crc32,奇偶校驗等。

 

模擬發送數據爲:

文本格式發送:WYZ123<CR><LF>

二進制格式發送:AA BB CC 08 0A 00 00 00 FA 3E F7 42 05

 

vs2008工程項目源碼範例

 
4
相關文章
相關標籤/搜索