VS 2005 中SerialPort控件的使用

翻译|其它|编辑:郝浩|2007-10-25 11:26:34.000|阅读 5887 次

概述:

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

      这些天在做一些 PDA 和计算机进行通讯的程序,用的串行口。VS2005中自带了串行口控件 System.IO.Ports.SerialPort,用起来比较方便,可以较为方便的接收和发送数据。

      在实际的使用过程中,发现了一些问题,主要是串行口数据的接收出现了一些问题,比如,SerialPort 的 Encoding 方式、收到的字符不完整 等。

      SerialPort 默认的 Encoding 是 ASCII 方式,这种方式对于传输汉字可能存在一些问题,所以在实际应用中,我采用了 Unicode 编码方式。在测试的时候,发送了一个 config 字符串过去,对方接收出现了问题,并不是我的 Unicode 字符串 config,而只是一部分。接收数据的处理是在 SerialPort.DataReceived 事件中处理的。代码如下:

    Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        
Dim s As String

        s 
= SerialPort1.ReadExisting()
        AppendSerialText(s 
&
 ControlChars.CrLf)
    
End Sub

      这里的 AppendSerialText 是一个过程,用于将文字显示到 TextBox 中,用的是委托来做的。

      运行程序会发现,发送过来的字符串通常是不完成的。一个 config 字符串,在 Unicode 编码下的长度是12个 byte。经过改进 DataReceived 事件的处理,得到 BytesToRead 属性的值,发现通常是在7或者8的时候,这个事件就触发了。也就是说,不是所有的数据到达了串行口,这个事件才触发。网络上很多例子代码在实际使用的时候多有这个问题,可以看出来,这些例子代码并没有在实际的应用中测试过。

      知道了问题所在,修改了事件处理程序,这个修改得到了 BOSS 的帮助,因为他在 EVC 里面已经做过这个事情了。

    Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        
Dim s As String, iLen As Integer

        
Dim All(-1As Byte, index As Integer = 0
        iLen 
= SerialPort1.BytesToRead
        
Do While iLen > 0

            AppendSerialText(
"BytesToRead size:" & iLen.ToString & ControlChars.CrLf)
            
ReDim Preserve All(index + iLen - 1
)
            index 
+=
 SerialPort1.Read(All, index, iLen)
            System.Threading.Thread.Sleep(
50
)    ‘ 这个很重要!
            iLen 
=
 SerialPort1.BytesToRead
        
Loop

        s 
= System.Text.Encoding.Unicode.GetString(All)
        AppendSerialText(
String.Format("Bytes Hex(length is {0}):{1}{2}{1}"
, All.Length, ControlChars.CrLf, ByteArrayToHexString(All)))
        AppendSerialText(s 
&
 ControlChars.CrLf)
        SerialPort1.Write(ProcessCommand(s))
    
End Sub

      在代码的循环过程中,有一个 Thread.Sleep(50)的代码,这个语句最早在我做这个事件中也是没有的。但是如果对方发送过来的数据比较大,字符串比较长,则有可能会出现 BytesToRead 为0,但是数据还没有发送过来的情况,所以加入了一个延迟,确保安全,但是这样做的效果就是有可能会使通信的速率降低。


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:csdn

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP