C# SerialPort异步读取总结

  笔者刚学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   }


 

posted @ 2012-05-23 15:58  chng  阅读(13990)  评论(3编辑  收藏  举报
BackToTop