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