您的位置:资讯频道 > 技术文档 > ActiveX/COM开发
VS 2005 中SerialPort控件的使用
这些天在做一些 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(-1) As 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,但是数据还没有发送过来的情况,所以加入了一个延迟,确保安全,但是这样做的效果就是有可能会使通信的速率降低。
相关文章:
-
暂无相关新闻。





