筆者剛學C++++時,寫了一個不太成熟的串口調試助手練練手,之前也曾用java寫過serialPort,而在一次競賽中終於對SerialPort稍作了專研。以下僅僅是個人筆記。
C#提供用於串口通信的System.IO.Ports.SerialPort類,可方便地進行串口(支持RS232,對於RS485,筆者並未嘗試)的讀寫操作。
一、幾個特點
對於SerialPort,有以下幾點值得注意:
1,ReadLine只可用於同步讀取。在沒有數據的時候,此函數將阻塞。
2,SerialPort調用read系列函數(Read,ReadByte,ReabChar, ReadLine, ReadExisting等)時,所謂的緩沖區是不需要的,或者說讀出的數據直接“流向”用戶定義的byte[]或者string類型的變量中。對於Write也一樣。所以,不存在flushRx或者flushTx的概念。
3,盡管如一所述,串口本身的緩沖區還是存在的,也就是說,倘若下位機發送上來的數據未被讀取,則會在數據量不超過緩沖區大小的情況下不斷積壓下來。筆者在這個問題上由於自己的疏忽,導致過不必要的麻煩。
4,SerialPort的讀數據函數多樣,上面提到的Read,ReadByte,ReabChar, ReadLine, ReadExisting都可調用,雖然讀取的都是符合一定格式的串口數據包(比特流),然而效果卻不盡相同,具體原因筆者也不清楚,待對於串口通信的底層和應用層都精通的高手來解答。經過愚鈍的筆者一通試驗,那些函數可分為兩類,一類是readbyte,即ReadByte,Read等,他們讀出的數據存儲在byte變量中。另一類是readchar,比如ReadChar,ReadExisting,二者讀出的數據竟然不同。在我的試驗中,readbyte函數讀出ff ff時,readchar函數讀出了3f 3f。
5,如果串口未能讀出正確的數值,可嘗試插拔設備接口,原因亦為止,求高手指點!
二、代碼部分
不想聽我廢話?那就直接看代碼:
1,設置基本參數
1 //設置SerialPort 2 3 SerialPort serp = new SerialPort(); 4 5 serp.BaudRate = 115200; 6 7 ......//參考msdn
2,設定接收相關的參數
1 //設置接收超時。一旦超時,將拋出Exception 2 3 serp.serialport.ReadTimeout = 90 * 1000; 4 5 //注冊事件處理函數 6 7 serp.serialport.DataReceived += new SerialDataReceivedEventHandler(this.serialport_DataReceived); 8 9 serp.Open();
3,定義接收事件處理函數
1 //定義事件處理函數 2 3 private serialport_DataReceived(Object sender, SerialDataReceivedEventArgs e) 4 5 { 6 7 try{ 8 9 Thread.Sleep(100); //(毫秒)等待一定時間,確保數據的完整性 int len 10 11 int len = serp.BytesToRead; 12 13 if( len!=0 ) 14 15 { 16 17 byte [] buff = new byte[len]; 18 19 serp.Read(buff, 0, len); 20 21 //try some other functions to read? do yourself if intersted 22 23 //processing data in buff 24 25 } 26 27 } 28 29 }