VB.NET串口通信例子
??
这是我3年前的一个例子,最近翻出来回忆一下。 串口是计算机上一种非常通用设备通信的协议。大多数计算机包含两个基于RS232的串口,现在配电脑好像只有一个。串口同时也是仪器仪表设备通用的通信协议;很多GPIB兼容的设备也带有RS-232口。同时,串口通信协议也可以用于获取远程采集设备的数据。串口通信在工控领域用途很广。 典型地,串口用于ASCII码字符的传输。通信使用3根线完成:(1)地线,(2)发送,(3)接收。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其他线用于握手,但是不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通行的端口,这些参数必须匹配: 串口通信还有一个参数是单工、半双工和双工。 如果在通信过程的任意时刻,信息只能由一方A传到另一方B,则称为单工。 如果在任意时刻,信息既可由A传到B,又能由B传A,但只能由一个方向上的传输存在,称为半双工传输。 如果在任意时刻,线路上存在A到B和B到A的双向信号传输,则称为全双工。 电话线就是二线全双工信道。 由于采用了回波抵消技术,双向的传输信号不致混淆不清。双工信道有时也将收、发信道分开,采用分离的线路或频带传输相反方向的信号,如回线传输。 在调试时可以用串口助手和windows的超级终端,不要带电插拔串口,容易烧毁。 在VB.NET中提供了IO.Ports类,是我们的编程变得很简单,下面是我的例子: Form1.vb
一不小心看到一高手写的C#串中操作系列的文章,很不错,可惜我辈不懂C#,于是顺便改成用VB.NET2010 其中几乎都有注解。 顺便说明,再发送16进制不是很完善,有懂的兄弟,说明一下 001.
Imports System
002.
Imports System.Collections.Generic
003.
Imports System.ComponentModel
004.
Imports System.Data
005.
Imports System.Drawing
006.
Imports System.Linq
007.
Imports System.Text
008.
Imports System.IO.Ports
009.
Imports System.Text.RegularExpressions
010.
011.
012.
Public Class Form1
013.
014.
WithEvents Comm As SerialPort = New SerialPort
015.
Private Builder As StringBuilder = New StringBuilder '避免在事件处理方法中反复的创建,所以定义到外面
016.
Private ReceiveCount As Long = 0 '接收计数
017.
Private SendCount As Long = 0 '发送计数
018.
019.
Private Listening As Boolean = False '是否没有执行完invoke相关操作
020.
Private Closingg As Boolean = False '是否正在关闭串口,执行Application.DoEvents,并阻止再次invoke
021.
022.
Public Delegate Sub UpdateData( ByVal mByte() As Byte )
023.
024.
Public Sub ShowData( ByVal mByte() As Byte )
025.
Console.WriteLine(mByte)
026.
ReceiveCount += mByte.Length
027.
Builder.Clear()
028.
029.
If CheckBoxHex.Checked Then
030.
For Each b As Byte In mByte
031.
Builder.Append(b.ToString( "X2" ) + " " )
032.
Next
033.
034.
Else
035.
036.
Builder.Append(Encoding.ASCII.GetString(mByte))
037.
038.
End If
039.
TxtGet.AppendText(Builder.ToString)
040.
labelGetCount.Text = "Get:" + ReceiveCount.ToString
041.
End Sub
042.
043.
Private Sub Form1_Load(sender As System. Object ,e As System.EventArgs) Handles MyBase .Load
044.
045.
'初始化下拉串口名称列表框
046.
Dim Ports() As String = SerialPort.GetPortNames
047.
Array.Sort(Ports)
048.
ComboPortName.Items.AddRange(Ports)
049.
ComboPortName.SelectedIndex = IIf(ComboPortName.Items.Count > 0,-1)
050.
ComboBaudrate.SelectedIndex = ComboBaudrate.Items.IndexOf( "9600" )
051.
'初始化Serialport对象
052.
Comm.NewLine = vbCrLf
053.
Comm.RtsEnable = True
054.
055.
'AddHandler Obj.Ev_Event,AddressOf EventHandler
056.
'RemoveHandler Obj.Ev_Event,AddressOf EventHandler
057.
'AddHandler Comm.DataReceived,AddressOf Comm_DataReceived
058.
059.
End Sub
060.
061.
Private Sub Comm_DataReceived(sender As Object ,e As System.IO.Ports.SerialDataReceivedEventArgs) Handles Comm.DataReceived
062.
If Closingg Then Return '如果正在关闭,忽略操作,直接返回,尽快的完成串口监听线程的一次循环
063.
064.
Try
065.
Listening = True '设置标记,说明我已经开始处理数据,一会儿要使用系统UI的。
066.
Dim n As Long = Comm.BytesToRead '先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致
067.
Dim Buf(n - 1) As Byte '声明一个临时数组存储当前来的串口数据
068.
069.
Comm.Read(Buf,n) '读取缓冲数据
070.
Builder.Clear() '清除字符串构造器的内容
071.
072.
Dim b As UpdateData = New UpdateData( AddressOf ShowData)
073.
Me .BeginInvoke(b,Buf)
074.
075.
Catch ex As Exception
076.
Err.Clear()
077.
Finally
078.
Listening = False '我用完了,ui可以关闭串口了。
079.
End Try
080.
End Sub
081.
082.
Private Sub ShowMsg( ByVal buffer() As Byte )
083.
If CheckBoxHex.Checked Then
084.
For Each b As Byte In Buffer
085.
Builder.Append(b.ToString( "X2" ) + " " )
086.
Next
087.
Else
088.
Builder.Append(Encoding.ASCII.GetString(buffer))
089.
End If
090.
Me .TxtGet.AppendText(Builder.ToString())
091.
labelGetCount.Text = "Get:" + ReceiveCount.ToString
092.
End Sub
093.
094.
Private Sub BtnXOpen_Click(sender As System. Object ,e As System.EventArgs) Handles BtnXOpen.Click
095.
'根据当前串口对象,来判断操作
096.
If Comm.IsOpen Then
097.
Closingg = True '
098.
While Listening
099.
Application.DoEvents()
100.
End While
101.
'打开时点击,则关闭串口
102.
Comm.Close()
103.
Closingg = False
104.
Else
105.
Comm.PortName = ComboPortName.Text
106.
Comm.BaudRate = Integer .Parse(ComboBaudrate.Text)
107.
Try
108.
Comm.Open()
109.
Catch ex As Exception
110.
'捕获到异常信息,创建一个新的comm对象,之前的不能用了。
111.
Comm = New SerialPort
112.
'现实异常信息给客户。
113.
MessageBox.Show(ex.Message)
114.
End Try
115.
End If
116.
117.
'设置按钮的状态
118.
BtnXOpen.Text = IIf(Comm.IsOpen, "Close" , "Open" )
119.
BtnXOpen.Enabled = Comm.IsOpen
120.
121.
End Sub
122.
123.
'动态的修改获取文本框是否支持自动换行。
124.
Private Sub CheckBoxNewLineGet_CheckedChanged(sender As System. Object ,e As System.EventArgs) Handles CheckBoxNewLineGet.CheckedChanged
125.
TxtGet.WordWrap = CheckBoxNewLineGet.Checked
126.
End Sub
127.
128.
Private Sub BtnXSend_Click(sender As System. Object ,e As System.EventArgs) Handles BtnXSend.Click
129.
Dim n As Integer = 0 '定义一个变量,记录发送了几个字节
130.
If checkBoxHexSend.Checked Then '16进制发送
131.
'我们不管规则了。如果写错了一些,我们允许的,只用正则得到有效的十六进制数
132.
Dim Mc As MatchCollection = Regex.Matches(TxtSend.Text.Trim, "(?i)[/da-f]{2}" ) '"(?i)[/da-f]{2}"
133.
Dim buf As List(Of Byte ) = New List(Of Byte )
134.
135.
'依次添加到列表中
136.
For Each m As Match In Mc
137.
' buf.Add(Byte.Parse(m.Value))
138.
buf.Add( Byte .Parse(m.Value,System.Globalization.NumberStyles.HexNumber))
139.
Next
140.
141.
'转换列表为数组后发送
142.
Comm.Write(buf.ToArray,buf.Count)
143.
n = buf.Count
144.
Else 'ascii编码直接发送
145.
'包含换行符
146.
If checkBoxNewlineSend.Checked Then
147.
Comm.WriteLine(TxtSend.Text)
148.
n = TxtSend.Text.Length + 2
149.
Else
150.
Comm.Write(TxtSend.Text)
151.
n = TxtSend.Text.Length
152.
End If
153.
End If
154.
155.
SendCount += n '累加发送字节数
156.
labelSendCount.Text = "Send:" + SendCount.ToString
157.
End Sub
158.
159.
Private Sub BtnXReset_Click(sender As System. Object ,e As System.EventArgs) Handles BtnXReset.Click
160.
161.
'复位接受和发送的字节数计数器并更新界面。
162.
SendCount = 0
163.
ReceiveCount = 0
164.
labelGetCount.Text = "Get:0"
165.
labelSendCount.Text = "Send:0"
166.
Builder.Clear()
167.
168.
End Sub
169.
170.
Private Sub BtxClear_Click(sender As System. Object ,e As System.EventArgs) Handles BtxClear.Click
171.
TxtGet.Text = ""
172.
Builder.Clear()
173.
End Sub
174.
End Class
??
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |