开发全功能串口调试助手(含完整工程)
小记: 的串口通信用了很长时间了,也只用 Write 和Read 这样的方 法,以前都是用这种方式做上位机软件, 如此足矣。
而前几天研究GSM 模块时对 串口返回的数据总是把握不好,参考开发板附送的例程,发现采用
SerialPort
的DataReceived 事件,可以实现中断触发式的数据接收。
于是想到要自己做一 个串口调试助手,在实现基本功能的前提下增加一些方便自己调试的功能。
经过
断断续续的编写,就做成了下面这个小软件:
这个软件能够实现串口调试助手的全部功能,经过通信测试,数据接收性能 不亚于呼啸工作室的SComAssistant2.2,通过加大输入缓冲区,可以满足大量 数据接收。
的串口通信主要使用 VS 自带的SerialPort 控件,而不是早先的 MSComm 更具有兼容性,这也是很久以前就放弃 VB 改用.NET 的直接原因。
该控 件的主要方法、属性如下(该数据来自 VS 的MSD
帮助库):
想要通过串口收发数据,就需要对串口进行配置,包括设置端口、波特率、数据格式(如COM端口、9600bps、8位数据位、无校验位、1位停止位)等属性,之后通过Open方法打开串口。
打开串口可通过手动指定,也可以使用GetPortNames 方法获取计算机中存在的串口。
如果打开出错,则可能是串口不存在或者已被占用。
下面是相应代码:
Private SubSerialPortOpen()
On Error GoToErr
If SerialPort.IsOpen = True ThenSerialPort.Close() '避免重复打开端
口
SerialPort.Ope n()
LabelCOMStatus.Text ="串口已打开"
Exit Sub
Err: MsgBox(‘ 串口不存在或已被占用!" + vbNewLine + ErrorToString()) ' 出现错误,显示错误信息
En dSub
如果想要在串口中支持中文字符收发,则可在初始化时设置串口控件的编码:
SerialPort.E ncodi ng = System.Text.E ncodi ng.Default
发送数据通过Write方法来完成,由于串口调试助手需要支持文本和16进制, 需要加入转换代码:
Private SubButtonSendData_Click( ByVal sender AsSystem.Object, ByVal e AsSystem.EventArgs) Handles ButtonSendData.Click
On Error GoToErr
DimoutDataBuf AsString = TextBoxSend.Text
If outDataBuf = "" ThenExit Sub'如果输入文本框中没有数据则不发送
If SerialPort.lsOpen = True Then'判断串口是否打开
If HexSendFlag = True Then
' ----- 十六进制发送------------
outDataBuf = outDataBuf.Replace( "","")'清除空格与回车
outDataBuf = outDataBuf.Replace(vbNewLine, "")
'十六进制数据位数为偶数,例如:FF 00 15 AC 0D
If outDataBuf.Length Mod2 <> 0 Then
MsgBoxC请输入正确的十六进制数,用空格和回车隔开。
")
Exit Sub
En dIf
DimoutBytes(outDataBuf.Length / 2 - 1) As Byte
For I As Integer = 1 TooutDataBuf.Length - 1 Step 2
outBytes((I - 1) / 2) = Val( "&H" + Mid(outDataBuf, I, 2))
'VB 的十六进制表示方法,例如0x1D表示为& H1D
Next
SerialPort.Write(outBytes, 0, outDataBuf.Length / 2)
BarCou ntTx.Text = Val(BarCou ntTx.Text) + outDataBuf.Le ngth / 2
Else
' ------- 文本发送 --------------
SerialPort.Write(outDataBuf)
BarCountTx.Text = Val(BarCountTx.Text) + outDataBuf.Length '发送字节计数
En dIf
Else
MsgBox"串口未打开,请先打开串口。
")
En dIf
Exit Sub
Err: MsgBox(‘ 数据输入或发送错误!" + vbNewL ine + ErrorToStri ng())
En dSub
接收数据采用DataReceived事件,该事件在串口输入缓冲区中的字节数满足
设置条件时触发,并执行事件中的代码。
事件触发的字节数在ReceivedBytesThreshold 属性中设置,默认为1字节。
由于DataReceived事件采用了独立的线程,无法对软件界面中的控件进行直接操作,因而在现实时需要采用委托实例的方法。
首先建立委托:
Delegate SubRecieveRefreshMethodDelegate( ByVal [text] As String )'声
明委托
Dim RecieveRefresh AsNewRecieveRefreshMethodDelegate( AddressOf Recie veRefreshMethod)'定义数据显示委托实例
Sub RecieveRefreshMethod( ByVal str As String )'定义一个数据显示委托实例的方法
ShowRecieveData(str)
EndSub
其中ShowRecieveData函数将str字符串显示到TextBox控件中。
下面是DataReceived事件中对十六进制数据的处理。
同发送数据一样,读取数据时也要根据不同的显示方式使用不同的方法。
通过Read方法,根据缓冲区中存在的字节数读取十六进制数据,而文本显示则简单的多,只需ReadExisting即可。
最后通过Invoke方法调用委托,显示数据。
Private Sub SerialPort_DataReceived( ByVal sender As Object, ByVal e As
Syste m.10 .Ports.SerialDataReceivedEve ntArgs) Han dles SerialPort.DataRec eived
If HexRecieveFlag Then
' ------ 十六进制显示--------
Dim inDataLen As Integer = SerialPort.BytesToRead()'获取可读取的字节数
If inDataLen > 0 Then
Dim inBytes(inDataLen - 1) As Byte, bytes As Byte
Dim strHex As String =""
SerialPort.Read(i nBytes, 0, i nDataLe n) '读取数据
For Each bytes In in Bytes
strHex = strHex + [String].Format( "{0:X2} ", bytes)'格式化成十六
进制(不含&H)
Next
TextBoxRecieve.I nvoke(RecieveRefresh, strHex) '调用委托,显示接收的数据
BarCou ntRx.Text = (Val(BarCou ntRx.Text) + in DataLe n).ToStri ng ' 接收字节计数
End If
Else
'------------ 文本显示----------
Dim str As String
str = SerialPort.ReadExisti ng '读取全部可用字符串
TextBoxRecieve .Inv oke(RecieveRefresh, str)
BarCou ntRx.Text = (Val(BarCou ntRx.Text) + str.Le ngth).ToStri ng '接收字节计数
End If
End Sub
至此就实现了串口收发的基本功能,另外的定时收发(使用Timer控件)、
文件发送(使用FileSystem )参见附带的源文件代码。
(附件功能完全不给力呀,终于传上来了... ) AHSerialPortEIf.rar
在完成串口调试助手的功能后,还可以根据个人的使用习惯或需求,添加相应的功能。