VB.NET 串口访问之一

一不小心看到一高手写的C#串中操作系列的文章,很不错,可惜我辈不懂C#,于是顺便改成用VB.NET2010

 

其中几乎都有注解。

顺便说明,再发送16进制不是很完善,有懂的兄弟,说明一下

Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.IO.Ports
Imports System.Text.RegularExpressions


Public Class Form1

    WithEvents Comm As SerialPort = New SerialPort
    Private Builder As StringBuilder = New StringBuilder '避免在事件处理方法中反复的创建,所以定义到外面
    Private ReceiveCount As Long = 0     '接收计数
    Private SendCount As Long = 0        '发送计数

    Private Listening As Boolean = False  '是否没有执行完invoke相关操作 
    Private Closingg As Boolean = False     '是否正在关闭串口,执行Application.DoEvents,并阻止再次invoke   

    Public Delegate Sub UpdateData(ByVal mByte() As Byte)

    Public Sub ShowData(ByVal mByte() As Byte)
        Console.WriteLine(mByte)
        ReceiveCount += mByte.Length
        Builder.Clear()

        If CheckBoxHex.Checked Then
            For Each b As Byte In mByte
                Builder.Append(b.ToString("X2") + " ")
            Next

        Else

            Builder.Append(Encoding.ASCII.GetString(mByte))

        End If
        TxtGet.AppendText(Builder.ToString)
        labelGetCount.Text = "Get:" + ReceiveCount.ToString
    End Sub

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        '初始化下拉串口名称列表框
        Dim Ports() As String = SerialPort.GetPortNames
        Array.Sort(Ports)
        ComboPortName.Items.AddRange(Ports)
        ComboPortName.SelectedIndex = IIf(ComboPortName.Items.Count > 0, 0, -1)
        ComboBaudrate.SelectedIndex = ComboBaudrate.Items.IndexOf("9600")
        '初始化Serialport对象
        Comm.NewLine = vbCrLf
        Comm.RtsEnable = True

        'AddHandler Obj.Ev_Event, AddressOf EventHandler
        'RemoveHandler Obj.Ev_Event, AddressOf EventHandler
        'AddHandler Comm.DataReceived, AddressOf Comm_DataReceived

    End Sub

    Private Sub Comm_DataReceived(sender As Object, e As System.IO.Ports.SerialDataReceivedEventArgs) Handles Comm.DataReceived
        If Closingg Then Return '如果正在关闭,忽略操作,直接返回,尽快的完成串口监听线程的一次循环   

        Try
            Listening = True                    '设置标记,说明我已经开始处理数据,一会儿要使用系统UI的。
            Dim n As Long = Comm.BytesToRead    '先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致   
            Dim Buf(n - 1) As Byte              '声明一个临时数组存储当前来的串口数据 

            Comm.Read(Buf, 0, n)                '读取缓冲数据
            Builder.Clear()                     '清除字符串构造器的内容 

            Dim b As UpdateData = New UpdateData(AddressOf ShowData)
            Me.BeginInvoke(b, Buf)

        Catch ex As Exception
            Err.Clear()
        Finally
            Listening = False                    '我用完了,ui可以关闭串口了。
        End Try
    End Sub

    Private Sub ShowMsg(ByVal buffer() As Byte)
        If CheckBoxHex.Checked Then
            For Each b As Byte In Buffer
                Builder.Append(b.ToString("X2") + " ")
            Next
        Else
            Builder.Append(Encoding.ASCII.GetString(buffer))
        End If
        Me.TxtGet.AppendText(Builder.ToString())
        labelGetCount.Text = "Get:" + ReceiveCount.ToString
    End Sub

    Private Sub BtnXOpen_Click(sender As System.Object, e As System.EventArgs) Handles BtnXOpen.Click
        '根据当前串口对象,来判断操作 
        If Comm.IsOpen Then
            Closingg = True '
            While Listening
                Application.DoEvents()
            End While
            '打开时点击,则关闭串口
            Comm.Close()
            Closingg = False
        Else
            Comm.PortName = ComboPortName.Text
            Comm.BaudRate = Integer.Parse(ComboBaudrate.Text)
            Try
                Comm.Open()
            Catch ex As Exception
                '捕获到异常信息,创建一个新的comm对象,之前的不能用了。 
                Comm = New SerialPort
                '现实异常信息给客户。 
                MessageBox.Show(ex.Message)
            End Try
        End If

        '设置按钮的状态   
        BtnXOpen.Text = IIf(Comm.IsOpen, "Close", "Open")
        BtnXOpen.Enabled = Comm.IsOpen

    End Sub

    '动态的修改获取文本框是否支持自动换行。
    Private Sub CheckBoxNewLineGet_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles CheckBoxNewLineGet.CheckedChanged
        TxtGet.WordWrap = CheckBoxNewLineGet.Checked
    End Sub

    Private Sub BtnXSend_Click(sender As System.Object, e As System.EventArgs) Handles BtnXSend.Click
        Dim n As Integer = 0  '定义一个变量,记录发送了几个字节 
        If checkBoxHexSend.Checked Then   '16进制发送 
            '我们不管规则了。如果写错了一些,我们允许的,只用正则得到有效的十六进制数   
            Dim Mc As MatchCollection = Regex.Matches(TxtSend.Text.Trim, "(?i)[/da-f]{2}")   '"(?i)[/da-f]{2}"
            Dim buf As List(Of Byte) = New List(Of Byte)

            '依次添加到列表中   
            For Each m As Match In Mc
                '  buf.Add(Byte.Parse(m.Value))
                buf.Add(Byte.Parse(m.Value, System.Globalization.NumberStyles.HexNumber))
            Next

            '转换列表为数组后发送  
            Comm.Write(buf.ToArray, 0, buf.Count)
            n = buf.Count
        Else                             'ascii编码直接发送 
            '包含换行符
            If checkBoxNewlineSend.Checked Then
                Comm.WriteLine(TxtSend.Text)
                n = TxtSend.Text.Length + 2
            Else
                Comm.Write(TxtSend.Text)
                n = TxtSend.Text.Length
            End If
        End If

        SendCount += n    '累加发送字节数 
        labelSendCount.Text = "Send:" + SendCount.ToString
    End Sub

    Private Sub BtnXReset_Click(sender As System.Object, e As System.EventArgs) Handles BtnXReset.Click

        '复位接受和发送的字节数计数器并更新界面。
        SendCount = 0
        ReceiveCount = 0
        labelGetCount.Text = "Get:0"
        labelSendCount.Text = "Send:0"
        Builder.Clear()

    End Sub

    Private Sub BtxClear_Click(sender As System.Object, e As System.EventArgs) Handles BtxClear.Click
        TxtGet.Text = ""
        Builder.Clear()
    End Sub
End Class


 

VB.NET串口助手,亲测可用,简单实用。 网上大大部分都实用AXcom控件而非serial port,各种函数都不一样。 这是一个最新的用serial port 来写的,包括委托的线程的关系。 这是我3年前的一个例子,最近翻出来回忆一下。 串口是计算机上一种非常通用设备通信的协议。大多数计算机包含两个基于RS232的串口,现在配电脑好像只有一个。串口同时也是仪器仪表设备通用的通信协议;很多GPIB兼容的设备也带有RS-232口。同时,串口通信协议也可以用于获取远程采集设备的数据。串口通信在工控领域用途很广。 串口通信的概念非常简单,串口按位(bit)发送和接收字节。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。它很简单并且能够实现远距离通信。比如IEEE488定义并行通行状态时,规定设备线总常不得超过20米,并且任意两个设备间的长度不得超过2米;而对于串口而言,长度可达1200米。 典型地,串口用于ASCII码字符的传输。通信使用3根线完成:(1)地线,(2)发送,(3)接收。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其他线用于握手,但是不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通行的端口,这些参数必须匹配: a,波特率:这是一个衡量通信速度的参数。它表示每秒钟传送的bit的个数。例如300波特表示每秒钟发送300个bit。当我们提到时钟周期时,我们就是指波特率例如如果协议需要4800波特率,那么时钟是4800Hz。这意味着串口通信在数据线上的采样率为4800Hz。通常电话线的波特率为14400,28800和36600。波特率可以远远大于这些值,但是波特率和距离成反比。高波特率常常用于放置的很近的仪器间的通信,典型的例子就是GPIB设备的通信。 b,数据位:这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据不会是8位的,标准的值是5、7和8位。如何设置取决于你想传送的信息。比如,标准的ASCII码是0~127(7位)。扩展的ASCII码是0~255(8位)。如果数据使用简单的文本(标准 ASCII码),那么每个数据包使用7位数据。每个包是指一个字节,包括开始/停止位,数据位和奇偶校验位。由于实际数据位取决于通信协议的选取,术语“包”指任何通信的情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值