VB.NET实现串口16进制数据收发

目录

1.案例描述

2.输入数据到串口写入数据转换

3.串口数据读取与数据转换

4.完整代码展示


 

1.案例描述

本案例使用VB.net做的一个16进制数据串口收发小工具,支持modbus协议格式数据收发。文中重点描述VB.net中16进制输入数据转换到串口Write()函数参数的过程,还有串口Read()函数读取结果转换到16进制字符串显示的过程。最终效果如下图。

案例代码:https://download.csdn.net/download/weixin_44322043/89607533

453ed6374c8d448abff50ec78ff38d11.png

2.输入数据到串口写入数据转换

输入数据到串口写入数据转换有两种方式,方式1见下方代码,hexString(String类型)为界面输入16进制字符串(不含空格),byteArray为串口Write()函数参数。

Dim byteArray As Byte() = Enumerable.Range(0, hexString.Length).Where(Function(X) X Mod 2 = 0).Select(Function(X) Convert.ToByte(hexString.Substring(X, 2), 16)).ToArray()

方式2见下方代码,hexString(String类型)为界面输入16进制字符串(不含空格),byteArray为串口Write()函数参数。

Dim byteArray(0 To (Len(hexString) / 2 - 1)) As Byte
For i = 1 To (Len(hexString)) Step 2
    byteArray((i - 1) / 2) = Val("&H" + Mid(hexString, i, 2))
Next i

3.串口数据读取与数据转换

为了使数据接收及时,使用SerialPort控件的DataReceived事件,如下图

ea2140e08c46418ea0e8555d2306ac87.png

PortDataReceived事件函数代码如下,PortReading为读数据函数。

Public Sub PortDataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived '接受函数
    Me.BeginInvoke(New EventHandler(AddressOf PortReading)) '调用读数据函数
End Sub

读数据函数PortReading代码和处理逻辑如下

    Public Sub PortReading(ByVal sender As Object, ByVal e As EventArgs)
        Try
            If SerialPort1.BytesToRead > 0 Then
                Dim byteToRead As Int16 = SerialPort1.BytesToRead
                Dim ReadByte(byteToRead) As Byte
                Dim bytesRead As Int16 = 0
                Dim indata As String = ""

                bytesRead = SerialPort1.Read(ReadByte, 0, byteToRead)
                For i As Int16 = 0 To bytesRead - 1
                    indata = indata & DecToHex(ReadByte(i))
                Next

                Dim timeStr As String = DateTime.Now.ToString("HH.mm.ss.") + AddZero(DateTime.Now.Millisecond.ToString) + " R: " + indata.Trim + vbCrLf
                TextBox2.Text += timeStr
            End If


            SerialPort1.DiscardInBuffer()

        Catch ex As Exception
            MessageBox.Show(ex.Message)

        End Try
    End Sub

    Public Function DecToHex(ByVal DecNumber As Byte) As String '转换成十六进制字符串,添加空格
        If DecNumber <= 15 Then
            DecToHex = " 0" & Hex(DecNumber)
        Else
            DecToHex = " " & Hex(DecNumber)
        End If
    End Function

4.完整代码展示


Public Class Form1

    Private Sub BtnConnect_Click(sender As Object, e As EventArgs) Handles BtnConnect.Click '打开/关闭串口按钮
        Try
            If BtnConnect.Text = "打开串口" Then
                SerialPort1.PortName = CBComName.Text
                SerialPort1.BaudRate = 115200
                SerialPort1.StopBits = IO.Ports.StopBits.One
                SerialPort1.Parity = IO.Ports.Parity.None
                SerialPort1.DataBits = 8
                SerialPort1.ReadBufferSize = 5120
                SerialPort1.ReadTimeout = 1000

                SerialPort1.Open()
            Else
                SerialPort1.Close()
            End If

            If SerialPort1.IsOpen Then
                BtnConnect.Text = "关闭串口"
            Else
                BtnConnect.Text = "打开串口"
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

    End Sub


    Public Function RemoveSpace(ByVal strText As String) As String '移除空格
        Return System.Text.RegularExpressions.Regex.Replace(strText, " ", String.Empty, System.Text.RegularExpressions.RegexOptions.IgnoreCase)
    End Function

    Private Sub WriteData(hexStringO As String) '写数据转换与写数据到串口
        '去除空格
        Dim hexString As String = RemoveSpace(hexStringO)

        '转换方式1
        Dim byteArray As Byte() = Enumerable.Range(0, hexString.Length).Where(Function(X) X Mod 2 = 0).Select(Function(X) Convert.ToByte(hexString.Substring(X, 2), 16)).ToArray()

        '转换方式2
        'Dim byteArray(0 To (Len(hexString) / 2 - 1)) As Byte
        'For i = 1 To (Len(hexString)) Step 2
        '    byteArray((i - 1) / 2) = Val("&H" + Mid(hexString, i, 2))
        'Next i

        If SerialPort1.IsOpen Then
            BtnConnect.Text = "关闭串口"

            SerialPort1.DiscardOutBuffer()
            SerialPort1.Write(byteArray, 0, byteArray.Length)
            Dim timeStr As String = DateTime.Now.ToString("HH.mm.ss.") + AddZero(DateTime.Now.Millisecond.ToString) + " W: " + hexStringO + vbCrLf

            TextBox2.Text += timeStr
        Else
            BtnConnect.Text = "打开串口"
        End If

    End Sub

    Public Sub PortDataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived '接受函数
        Me.BeginInvoke(New EventHandler(AddressOf PortReading)) '调用读数据函数
    End Sub

    Public Function DecToHex(ByVal DecNumber As Byte) As String '转换成十六进制字符串,添加空格
        If DecNumber <= 15 Then
            DecToHex = " 0" & Hex(DecNumber)
        Else
            DecToHex = " " & Hex(DecNumber)
        End If
    End Function

    Public Sub PortReading(ByVal sender As Object, ByVal e As EventArgs) '读串口与数据处理
        Try
            If SerialPort1.BytesToRead > 0 Then
                Dim byteToRead As Int16 = SerialPort1.BytesToRead
                Dim ReadByte(byteToRead) As Byte
                Dim bytesRead As Int16 = 0
                Dim indata As String = ""

                bytesRead = SerialPort1.Read(ReadByte, 0, byteToRead)
                For i As Int16 = 0 To bytesRead - 1
                    indata = indata & DecToHex(ReadByte(i))
                Next

                Dim timeStr As String = DateTime.Now.ToString("HH.mm.ss.") + AddZero(DateTime.Now.Millisecond.ToString) + " R: " + indata.Trim + vbCrLf
                TextBox2.Text += timeStr
            End If


            SerialPort1.DiscardInBuffer()

        Catch ex As Exception
            MessageBox.Show(ex.Message)

        End Try
    End Sub

    Private Function AddZero(strMs As String) As String 'ms显示补齐3位
        AddZero = strMs
        If strMs.Length < 3 Then
            For num = 0 To 3 - strMs.Length - 1
                AddZero = "0" & AddZero
            Next
        End If
    End Function

    Private Sub BtnSend1_Click(sender As Object, e As EventArgs) Handles BtnSend1.Click '发送按钮点击事件
        WriteData(TextBox1.Text.Trim)
    End Sub

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

        Dim portNames() As String = IO.Ports.SerialPort.GetPortNames() '获取所有串口名称

        For Each port In portNames
            CBComName.Items.Add(port) '将串口名称添加到串口下拉选择框
        Next
        If portNames.Length > 0 Then
            CBComName.SelectedIndex = 0
        End If

    End Sub

    Private Sub CBTime1_CheckedChanged(sender As Object, e As EventArgs) Handles CBTime1.CheckedChanged '定时发送开启关闭勾选框
        If CBTime1.Checked Then
            Timer1.Interval = Val(TBTime1.Text)
            Timer1.Start()
        Else
            Timer1.Stop()
        End If
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick '定时发送计时器
        WriteData(TextBox1.Text.Trim)
    End Sub

    Private Sub BtnClear_Click(sender As Object, e As EventArgs) Handles BtnClear.Click '清除显示
        TextBox2.Text = ""
    End Sub
End Class

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

99.999...%

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值