Public Class Form1
'声明一个通信端口对象
' Dim RS232 As SerialPort
'声明一个委派类别,并声明符合函式参数有一个,而其型态是字符串
Delegate Sub SetTextCallback(ByVal InputString As String)
'**************************************************************
'表单的Load事件中先将所有的通信端口先列出来
'将通信端口排序,并将第一个通信端口设为默认值
'**************************************************************
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For Each sp As String In SerialPort.GetPortNames()
cmbCOM.Items.Add(sp)
Next
cmbCOM.Sorted = True '排序
cmbCOM.SelectedIndex = 0 '第一个是默认选项
End Sub
'**************************************************************
'『打开通信端口』按钮的Click事件
'此事件将设定通信端口参数,并打开通信端口
'**************************************************************
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
Dim mBaudRate As Integer
Dim mParity As IO.Ports.Parity
Dim mDataBit As Integer
Dim mStopbit As IO.Ports.StopBits
Dim mPortName As String
If Not Rs232.IsOpen Then '尚未打开
Rs232 = New IO.Ports.SerialPort(mPortName, mBaudRate, mParity, mDataBit, mStopbit)
Rs232.Encoding = Encoding.ASCII
' RS232.Encoding = Encoding.Unicode '设定编码方式为Unicode,以便能显示中文
Console.WriteLine(Rs232.IsOpen)
' RS232.ReceivedBytesThreshold = 18 '检查设备的实际阀值18
Rs232.Open() '打开通信端口
btnSend.Enabled = True '致能传送按钮
BkWorker.WorkerSupportsCancellation = True
If Not BkWorker.IsBusy Then '判断工作状态
BkWorker.RunWorkerAsync() '开始背景作业
End If
Else
MsgBox("~~通信端口打开错误(通信端口已被打开)~~", MsgBoxStyle.Critical Or MsgBoxStyle.OkCancel)
' End
End If
End Sub
'**************************************************************
'『关闭通信端口』按钮的Click事件
'以Close方法关闭通信端口,并释放对象所占用的资源
'**************************************************************
Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
If RS232 Is Nothing OrElse Not RS232.IsOpen Then '尚未打开
MsgBox("~~通信端口尚未打开~~", MsgBoxStyle.Critical Or MsgBoxStyle.OkCancel)
Else
btnSend.Enabled = False
BkWorker.CancelAsync() '取消作业
RS232.Close()
End If
End Sub
'**************************************************************
'『结束程序』按钮 的Click事件
'此事件将设定通信端口参数,并打开通信端口
'**************************************************************
Private Sub btnEnd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEnd.Click
If Not RS232 Is Nothing Then '判断是否已建立通信对象
If RS232.IsOpen Then RS232.Close() '若已打开,就将其关闭
End If
End
End Sub
'**************************************************************
'实№的取值程序
'**************************************************************
Private Sub GetRS232Data()
Dim InString As String
InString = ""
If Not RS232.IsOpen Then Exit Sub
Try
RS232.ReadTimeout = 1000
InString = RS232.ReadExisting
If InString.Length = 0 Then '若无数据则跳出
Exit Sub
Else
DisplayText(InString) '若有数据则加到接收的文字框
End If
Catch ex As Exception
MessageBox.Show("读取错误:" + ex.ToString, "错误通知", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
End Sub
'**************************************************************
'委派子程序
'处理上述通信端口的接收事件
'由于欲将数据显示到接收文字框中,因此必须检查是否由另外的Thread
'所调用的,若是,则必须先建立委派对象
'Invoke用于在拥有控制项基础视窗控制代码的进程上执行委派
'**************************************************************
Private Sub DisplayText(ByVal comData As String)
'如果调用txtReceive的是另外的进程,传回True
If Me.txtReceive.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf DisplayText)
'用大括号 {} 括住初始值,藉以初始化阵列的值。
Me.Invoke(d, New Object() {comData}) '以指定的引数清单叫用函式
Else '相同的进程
Me.txtReceive.Text += comData '将收到的数据入接收文字框中
End If
End Sub
'**************************************************************
'『传送』按钮的Click事件
'将文字框中的文字以Write方法自串行端口送出
'**************************************************************
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
Dim tmpdata As String = ":010347000002B3" & vbCrLf
Rs232.Write(tmpdata)
End Sub
'**************************************************************
'通信端口的KeyPress事件,在此不让用户输入数据
'**************************************************************
Private Sub cmbCOM_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles cmbCOM.KeyPress
e.KeyChar = ChrW(0) '禁止用户在其中输入任何的文字
End Sub
'**************************************************************
'BackgroundWorker的DoWork事件
'当RunWorkAsync方法被调用时,会引发此事件
'将欲执行的方法放在这里面,即可由另一个进程执行
'**************************************************************
Private Sub BkWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BkWorker.DoWork
GetRS232Data()
If BkWorker.CancellationPending Then
e.Cancel = True
End If
End Sub
'**************************************************************
'BackgroundWorker的RunWorkerCompleted事件
'当DoWork事件被执行完后,即引发此事件
'程序中检查取消状态,若非取消状态就继续执行背景作业
'**************************************************************
Private Sub BkWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BkWorker.RunWorkerCompleted
If Not BkWorker.CancellationPending Then
BkWorker.RunWorkerAsync() '开始背景作业
End If
End Sub