| 在.NET work 2.0中提供了SerialPort類,該類主要實現串口數據通信等。本文章將本人在學習過程中從網絡上搜集到的相關信息寫出來供大家參考。 下面主要介紹該類的主要屬性(表1)和方法(表.2)。 如果需要了解更多的信息請登錄http://msdn.microsoft.com/zh-cn/library/system.io.ports.serialport(VS.80).aspx查看。 相關文章 《使用System.IO.Ports讀取COM口數據》 http://www.devasp.net/net/articles/display/727.html 使用SerialPort類的方法: 方法一: 首先要添加 using System.IO; using System.IO.Ports; 1...在類的內部定義SerialPort com; 2...打開串口 ??????????? com = new SerialPort(); ??????????? com.BaudRate = 115200; ??????????? com.PortName = "COM1"; ??????????? com.DataBits = 8; ??????????? com.Open();//打開串口 3...發送數據 ??????????? Byte[] TxData ={1,2,3,4,5,6,7,8 }; ??????????? com.Write(TxData, 0, 8); 4...接收數據 ???? 4.1使用事件接收 ???? this.com.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.OnDataReceived); private void OnDataReceived(object sender, SerialDataReceivedEventArgs e) ??? 4.2使用線程接收 ???? 接收數據啟動一個線程,使其接收。 在類的內部定義 ??????? Thread _readThread; ??????? bool _keepReading; 打開串口后啟動線程 ??????????? _keepReading = true; ??????????? _readThread = new Thread(ReadPort); ??????????? _readThread.Start(); 線程函數 view plaincopy to clipboardprint? private void ReadPort()?? {?? ??? while (_keepReading)?? ??? {?? ??????? if (com.IsOpen)?? ??????? {?? ??????????? byte[] readBuffer = new byte[com.ReadBufferSize + 1];?? ??????????? try ??????????? {?? ??????????????? // If there are bytes available on the serial port,?? ??????????????? // Read returns up to "count" bytes, but will not block (wait)?? ??????????????? // for the remaining bytes. If there are no bytes available?? ??????????????? // on the serial port, Read will block until at least one byte?? ??????????????? // is available on the port, up until the ReadTimeout milliseconds?? ??????????????? // have elapsed, at which time a TimeoutException will be thrown.?? ??????????????? int count = com.Read(readBuffer, 0, com.ReadBufferSize);?? ??????????????? String SerialIn = System.Text.Encoding.ASCII.GetString(readBuffer, 0, count);?? ??????????????? if (count != 0)?? ??????????????????? //byteToHexStr(readBuffer);?? ??????????????????? Thread(byteToHexStr(readBuffer,count));?? ??????????? }?? ??????????? catch (TimeoutException) { }?? ??????? }?? ??????? else ??????? {?? ??????????? TimeSpan waitTime = new TimeSpan(0, 0, 0, 0, 50);?? ??????????? Thread.Sleep(waitTime);?? ??????? }?? ??? }?? } ??????? private void ReadPort() ??????? { ??????????? while (_keepReading) ??????????? { ??????????????? if (com.IsOpen) ??????????????? { ??????????????????? byte[] readBuffer = new byte[com.ReadBufferSize + 1]; ??????????????????? try ??????????????????? { ??????????????????????? // If there are bytes available on the serial port, ??????????????????????? // Read returns up to "count" bytes, but will not block (wait) ??????????????????????? // for the remaining bytes. If there are no bytes available ??????????????????????? // on the serial port, Read will block until at least one byte ??????????????????????? // is available on the port, up until the ReadTimeout milliseconds ??????????????????????? // have elapsed, at which time a TimeoutException will be thrown. ??????????????????????? int count = com.Read(readBuffer, 0, com.ReadBufferSize); ??????????????????????? String SerialIn = System.Text.Encoding.ASCII.GetString(readBuffer, 0, count); ??????????????????????? if (count != 0) ??????????????????????????? //byteToHexStr(readBuffer); ??????????????????????????? Thread(byteToHexStr(readBuffer,count)); ??????????????????? } ??????????????????? catch (TimeoutException) { } ??????????????? } ??????????????? else ??????????????? { ??????????????????? TimeSpan waitTime = new TimeSpan(0, 0, 0, 0, 50); ??????????????????? Thread.Sleep(waitTime); ??????????????? } ??????????? } ??????? } 方法二:使用C#自帶的SerialPor控件。 1...在“工具箱”的“組件”中選擇SerialPor控件添加。 2...設置串口并打開 serialPort1.PortName = "COM1"; serialPort1.BaudRate = 9600; serialPort1.Open(); 3...寫入數據可以使用Write或者下面的函數 serialPort1.WriteLine(str); 4...添加數據接收的事件 private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) 使用中的一些常見問題 C#中SerialPort類中DataReceived事件GUI實時處理方法(來自wanglei_wan@yahoo.com.cn 的看法) MSDN:從 SerialPort 對象接收數據時,將在輔助線程上引發 DataReceived 事件。由于此事件在輔助線程而非主線程上引發,因此嘗試修改主線程中的一些元素(如 UI 元素)時會引發線程異常。如果有必要修改主 Form 或 Control 中的元素,必須使用 Invoke 回發更改請求,這將在正確的線程上執行.進而要想將輔助線程中所讀到的數據顯示到主線程的Form控件上時,只有通過Invoke方法來實現 下面是代碼實例: private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { ?? int SDateTemp = this.serialPort1.ReadByte(); ?? //讀取串口中一個字節的數據 ?? this.tB_ReceiveDate.Invoke(?? //在擁有此控件的基礎窗口句柄的線程上執行委托Invoke(Delegate) //即在textBox_ReceiveDate控件的父窗口form中執行委托. new MethodInvoker(??????????? /*表示一個委托,該委托可執行托管代碼中聲明為 void 且不接受任何參數的任何方法。 在對控件的 Invoke 方法進行調用時或需要一個簡單委托又不想自己定義時可以使用該委托。*/ delegate{???????????????? ??? /*匿名方法,C#2.0的新功能,這是一種允許程序員將一段完整代碼區塊當成參數傳遞的程序代碼編寫技術,通過此種方法可 以直接使用委托來設計事件響應程序以下就是你要在主線程上實現的功能但是有一點要注意,這里不適宜處理過多的方法,因為C#消息機制是消息流水線響應機制,如果這里在主線程上處理語句的時間過長會導致主UI線程阻塞,停止響應或響應不順暢,這時你的主form界面會延遲或卡死????? */?????????????????? this.tB_ReceiveDate.AppendText(SDateTemp.ToString());//輸出到主窗口文本控件 this.tB_ReceiveDate.Text += " ";} ??? ) ??? ); } 如何知道當前電腦有哪個串口 在窗體上添加一個comboBox控件。 然后使用comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames()); 或者 string[] portList = System.IO.Ports.SerialPort.GetPortNames(); ??????????? for (int i = 0; i < portList.Length; ++i) ??????????? { ??????????????? string name = portList[i]; ??????????????? comboBox1.Items.Add(name); ??????????? } |