1。簡介
隨 着USB的流行,串口通訊已經應用到日常生活的很多方面了,USB是一種高速的串口通訊協議,USB接口非常復雜,通常被用在需要傳輸大量數據數據的地 方,如U盤、相機、打印機等。除了USB這種較為奢侈的串口外,在工控和嵌入式行業,大量被使用的是另一種古老的串口協議,RS-232串口。RS- 232是一種非常簡潔的低速串口通訊接口,它可以同時進行數據接收和發送的工作。
2。.NET 2.0對串口的支持
.NET 2.0提供了對串口通信功能的支持,有關類可以在命名空間System.IO.Ports下找到,這其中最為重要的是SerialPort類。
通過創建一個新的SerialPort 對象,我們就可以在.NET程序中控制串口通訊的全過程。
3。使用 SerialPort 設置串口屬性
進行串口通訊時,需要設置一些相關參數,可以通過設置SerialPort 類的屬性來進行。串口屬性主要包括
.PortName 串口名稱,COM1, COM2等。
.BaudRate 波特率,也就是串口通訊的速度,進行串口通訊的雙方其波特率需要相同,如果用PC連接其他非PC系統,一般地,波特率由非PC系統決定。
.Parity 奇偶校驗。可以選取枚舉Parity中的值
.DataBits 數據位
.StopBits 停止位,可以選取枚舉StopBits中的值
.Handshake 握手方式,也就是數據流控制方式,可以選取枚舉Handshake中的值
4。打開與關閉串口
在創建一個SerialPort 對象,設置串口屬性后,可以通過 Open()方法打開串口。數據讀寫完成后,可以通過Close()方法關閉串口。
根據經驗,對於有些系統,在打開串口后,還需要將RtsEnable設置為True,這樣才能讀寫數據,否則不能正常讀寫數據。
5。讀寫行數據
雙方通訊時,一般都需要定義通訊協議,即使最簡單的通過串口發送文本聊天的程序。
通常是在當一方按下回車時,將其所數據的文本連同換行符發給另一方。在這個通訊事例中,協議楨是通過換行符界定的,每一楨數據都被換行符隔開,這樣就很容易識別出通訊雙發發送的信息。
在 以上的例子中,可以用WriteLine()來發送數據,用ReadLine()來讀取數據。WriteLine發送完數據后,會將換行符作為數據也發送 給對方。ReadLine()讀取數據時,直至遇到一個換行符,然后返回一個字符串代表一行信息。換行符可以通過SerialPort 的屬性 NewLine來設置。一般地,Windows將CrLn作為換行符,而在Linux下,換行符則只用一個Ln表示。
ReadLine() 方法是阻塞的,直至遇到一個換行符后返回。在讀取數據時,如果一直沒有遇到換行符,那么在等待ReadTimeout時間后,拋出一個 TimeoutException。默認情況下,ReadTimeout為InfiniteTimeout。這樣,ReadLine一直處於阻塞狀態,直 至有新一行數據到達。
WriteLine()方法也是阻塞的,如果另一方不能及時接收數據,就會引起TimeoutException異常。
由於ReadLine()和WriteLine()方法都是阻塞式的,在程序使用SerialPort 進行串口通訊時,一般應該把讀寫操作交由其他線程處理,避免因為阻塞而導致程序不響應。
6。讀寫字節或字符數據
對於字節或字符數據,用Read()方法來讀數據,該方法需要一個字節或字符數組作為參數來保存讀取的數據,結果返回實際讀取的字節或字符數。寫數據使用Write()方法,該方法可以將字節數組、字符數據或字符串發送給另一方。
如果通訊雙方交換的數據位字節流數據,要構建一個使用的串口通訊程序,那么雙方應該定義數據楨格式。通常數據楨由楨頭和楨尾來界定。
發送數據比較簡單,只需要將構造好的數據用Write()方法發送出去即可。
接收數據則比較復雜,通訊是以字節流的形式到達的,通過調用一次Read()方法並不能確保所讀取的數據就是完整一楨。因此需要將每次讀取的數據整合在一 起,對整合后的數據進行分析,按照定義的楨格式,通過楨頭和楨尾,將楨信息從字節流中抽取出來,這樣才能獲取有意義的信息。
除了利用Read()方法來讀數據,還可以使用ReadExisting()方法來讀取數據。該方法讀取當前所能讀到的數據,以字符串的形式返回。
7。事件DataReceived
SerialPort 提供了DataReceived事件。當有數據進入時,該事件被觸發。該事件的觸發由操作系統決定,當有數據到達時,該事件在輔助線程中被觸發。輔助線程的優先級比較低,因此並不能確保每個字節的數據到達時,該事件都被觸發。
在使用該事件接收數據時,最好對定義通訊協議格式,添加楨頭和楨尾。在DataReceived事件中接收數據時,把數據放在數組中或字符串中緩沖起來,當接收的包含楨頭和楨尾的完整數據時,在進行處理,另外,為了有效地接收數據,可以在每次讀取數據后,加入System.Threading.Thread.Sleep方法進行演示。
8。其他
用跳線使串口的第2、3針連接,可以在本地計算機上實現串口通信,所以,通過串口的第2、3針的連接可以對程序進行檢測。
.BytesToRead 該屬性返回能夠讀到的字節數。
ReadByte從 SerialPort 輸入緩沖區中同步讀取一個字節
ReadChar從 SerialPort 輸入緩沖區中同步讀取一個字符
對於長度的完整性,可以用同步方式接收數據,在從線程用serialPort.BytesToRead 判斷累計接收字節的長度.
對於預先知道結尾處字節的完整性,你可以用serialPort.ReadTo (string value)方法讀取數據(value為結尾處的字符串)
對 於長度和結尾處字節不能確定信息的完整性處理,我的一種方法是用異步的方式,這種方法需事先估計出接收對方信息所需的時間,將此時間設置為從線程睡眠的時 間。另一種方法是用同步方式接收,當SerialPort.ReadByte()方法阻塞到接收到初始始數據后,從線程每次睡眠一個短暫的時間,用 serialPort.BytesToRead ==0判斷有無新數據.若有新數據,從線程繼續睡眠;若沒有新數據到來,說明數據是完整的。
當然數據完整接收后,仍要用接收數據的協議(頭、尾字節、校驗等方式)判斷數據的正確性,保證數據真正是完整的。