VB.NET 串口异步访问

前端之家收集整理的这篇文章主要介绍了VB.NET 串口异步访问前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
  1. Imports System
  2. Imports System.Collections.Generic
  3. Imports System.ComponentModel
  4. Imports System.Data
  5. Imports System.Drawing
  6. Imports System.Linq
  7. Imports System.Text
  8. Imports System.IO.Ports
  9. Imports System.Text.RegularExpressions
  10.  
  11.  
  12.  
  13.  
  14. Public Class Form1
  15.  
  16.  
  17. WithEvents Comm As SerialPort = New SerialPort
  18. Private Builder As StringBuilder = New StringBuilder '避免在事件处理方法中反复的创建,所以定义到外面
  19. Private ReceiveCount As Long = 0 '接收计数
  20. Private SendCount As Long = 0 '发送计数
  21.  
  22.  
  23. Private Listening As Boolean = False '是否没有执行完invoke相关操作
  24. Private Closingg As Boolean = False '是否正在关闭串口,执行Application.DoEvents,并阻止再次invoke
  25.  
  26.  
  27. Public Delegate Sub UpdateData(ByVal mByte() As Byte)
  28.  
  29.  
  30. Public Sub ShowData(ByVal mByte() As Byte)
  31. Console.WriteLine(mByte)
  32. ReceiveCount += mByte.Length
  33. Builder.Clear()
  34.  
  35.  
  36. If CheckBoxHex.Checked Then
  37. For Each b As Byte In mByte
  38. Builder.Append(b.ToString("X2") + " ")
  39. Next
  40.  
  41.  
  42. Else
  43.  
  44.  
  45. Builder.Append(Encoding.ASCII.GetString(mByte))
  46.  
  47.  
  48. End If
  49. TxtGet.AppendText(Builder.ToString)
  50. labelGetCount.Text = "Get:" + ReceiveCount.ToString
  51. End Sub
  52.  
  53.  
  54. Private Sub Form1_Load(sender As System.Object,e As System.EventArgs) Handles MyBase.Load
  55.  
  56.  
  57. '初始化下拉串口名称列表框
  58. Dim Ports() As String = SerialPort.GetPortNames
  59. Array.Sort(Ports)
  60. ComboPortName.Items.AddRange(Ports)
  61. ComboPortName.SelectedIndex = IIf(ComboPortName.Items.Count > 0,-1)
  62. ComboBaudrate.SelectedIndex = ComboBaudrate.Items.IndexOf("9600")
  63. '初始化Serialport对象
  64. Comm.NewLine = vbCrLf
  65. Comm.RtsEnable = True
  66.  
  67.  
  68. 'AddHandler Obj.Ev_Event,AddressOf EventHandler
  69. 'RemoveHandler Obj.Ev_Event,AddressOf EventHandler
  70. 'AddHandler Comm.DataReceived,AddressOf Comm_DataReceived
  71.  
  72.  
  73. End Sub
  74.  
  75.  
  76. Private Sub Comm_DataReceived(sender As Object,e As System.IO.Ports.SerialDataReceivedEventArgs) Handles Comm.DataReceived
  77. If Closingg Then Return '如果正在关闭,忽略操作,直接返回,尽快的完成串口监听线程的一次循环
  78.  
  79.  
  80. Try
  81. Listening = True '设置标记,说明我已经开始处理数据,一会儿要使用系统UI的。
  82. Dim n As Long = Comm.BytesToRead '先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致
  83. Dim Buf(n - 1) As Byte '声明一个临时数组存储当前来的串口数据
  84.  
  85.  
  86. Comm.Read(Buf,n) '读取缓冲数据
  87. Builder.Clear() '清除字符串构造器的内容
  88.  
  89.  
  90. Dim b As UpdateData = New UpdateData(AddressOf ShowData)
  91. Me.BeginInvoke(b,Buf)
  92.  
  93.  
  94. Catch ex As Exception
  95. Err.Clear()
  96. Finally
  97. Listening = False '我用完了,ui可以关闭串口了。
  98. End Try
  99. End Sub
  100.  
  101.  
  102. Private Sub ShowMsg(ByVal buffer() As Byte)
  103. If CheckBoxHex.Checked Then
  104. For Each b As Byte In Buffer
  105. Builder.Append(b.ToString("X2") + " ")
  106. Next
  107. Else
  108. Builder.Append(Encoding.ASCII.GetString(buffer))
  109. End If
  110. Me.TxtGet.AppendText(Builder.ToString())
  111. labelGetCount.Text = "Get:" + ReceiveCount.ToString
  112. End Sub
  113.  
  114.  
  115. Private Sub BtnXOpen_Click(sender As System.Object,e As System.EventArgs) Handles BtnXOpen.Click
  116. '根据当前串口对象,来判断操作
  117. If Comm.IsOpen Then
  118. Closingg = True '
  119. While Listening
  120. Application.DoEvents()
  121. End While
  122. '打开时点击,则关闭串口
  123. Comm.Close()
  124. Closingg = False
  125. Else
  126. Comm.PortName = ComboPortName.Text
  127. Comm.BaudRate = Integer.Parse(ComboBaudrate.Text)
  128. Try
  129. Comm.Open()
  130. Catch ex As Exception
  131. '捕获到异常信息,创建一个新的comm对象,之前的不能用了。
  132. Comm = New SerialPort
  133. '现实异常信息给客户。
  134. MessageBox.Show(ex.Message)
  135. End Try
  136. End If
  137.  
  138.  
  139. '设置按钮的状态
  140. BtnXOpen.Text = IIf(Comm.IsOpen,"Close","Open")
  141. BtnXOpen.Enabled = Comm.IsOpen
  142.  
  143.  
  144. End Sub
  145.  
  146.  
  147. '动态的修改获取文本框是否支持自动换行。
  148. Private Sub CheckBoxNewLineGet_CheckedChanged(sender As System.Object,e As System.EventArgs) Handles CheckBoxNewLineGet.CheckedChanged
  149. TxtGet.WordWrap = CheckBoxNewLineGet.Checked
  150. End Sub
  151.  
  152.  
  153. Private Sub BtnXSend_Click(sender As System.Object,e As System.EventArgs) Handles BtnXSend.Click
  154. Dim n As Integer = 0 '定义一个变量,记录发送了几个字节
  155. If checkBoxHexSend.Checked Then '16进制发送
  156. '我们不管规则了。如果写错了一些,我们允许的,只用正则得到有效的十六进制数
  157. Dim Mc As MatchCollection = Regex.Matches(TxtSend.Text.Trim,"(?i)[/da-f]{2}") '"(?i)[/da-f]{2}"
  158. Dim buf As List(Of Byte) = New List(Of Byte)
  159.  
  160.  
  161. '依次添加到列表中
  162. For Each m As Match In Mc
  163. ' buf.Add(Byte.Parse(m.Value))
  164. buf.Add(Byte.Parse(m.Value,System.Globalization.NumberStyles.HexNumber))
  165. Next
  166.  
  167.  
  168. '转换列表为数组后发送
  169. Comm.Write(buf.ToArray,buf.Count)
  170. n = buf.Count
  171. Else 'ascii编码直接发送
  172. '包含换行符
  173. If checkBoxNewlineSend.Checked Then
  174. Comm.WriteLine(TxtSend.Text)
  175. n = TxtSend.Text.Length + 2
  176. Else
  177. Comm.Write(TxtSend.Text)
  178. n = TxtSend.Text.Length
  179. End If
  180. End If
  181.  
  182.  
  183. SendCount += n '累加发送字节数
  184. labelSendCount.Text = "Send:" + SendCount.ToString
  185. End Sub
  186.  
  187.  
  188. Private Sub BtnXReset_Click(sender As System.Object,e As System.EventArgs) Handles BtnXReset.Click
  189.  
  190.  
  191. '复位接受和发送的字节数计数器并更新界面。
  192. SendCount = 0
  193. ReceiveCount = 0
  194. labelGetCount.Text = "Get:0"
  195. labelSendCount.Text = "Send:0"
  196. Builder.Clear()
  197.  
  198.  
  199. End Sub
  200.  
  201.  
  202. Private Sub BtxClear_Click(sender As System.Object,e As System.EventArgs) Handles BtxClear.Click
  203. TxtGet.Text = ""
  204. Builder.Clear()
  205. End Sub
  206. End Class

猜你在找的VB相关文章