VB,处理串口接收到的字符串的问题

时间:2021-01-01 23:44:16
下位机上传的数据是这样的:
每次传8个字节(hex格式),例如AA 1 2 3 4 5 6 BB,这是一帧数据,AA和BB为起始和结束的标志位,中间没有空格的。

我现在定时器每个500ms取一次缓存区的数据,这次取到的数据是:
1 2 3 BB AA 1 2 3 4 5 6 BB AA 2 3 4 5 6 7 BB AA 5 6

我想去掉第一个AA前面的数和最后一个BB后面的数,然后取出中间的有效数据放在一个数组里。
这个应该用什么字符串处理函数呢?

10 个解决方案

#1


用下面函数即可:

Private Function strProcess(ByVal str As String) As String
Dim aStr, bStr As String
aStr = Mid(str, InStr(1, str, "AA"))
bStr = Mid(aStr, 1, InStrRev(aStr, "BB") + 1)
strProcess = bStr
End Function

#2


引用 1 楼 roock 的回复:
用下面函数即可:

VB code

Private Function strProcess(ByVal str As String) As String
Dim aStr, bStr As String
aStr = Mid(str, InStr(1, str, "AA"))
bStr = Mid(aStr, 1, InStrRev(aStr, "BB") + 1)
strPro……



' 用途:将十六进制转化为十进制
' 输入:Hex(十六进制数)
' 输入数据类型:String
' 输出:HEX_to_DEC(十进制数)
' 输出数据类型:Long
' 输入的最大数为7FFFFFFF,输出的最大数为2147483647
Public Function HEX_to_DEC(ByVal Hex As String) As Long
    Dim i As Long
    Dim B As Long
    Hex = UCase(Hex)
    For i = 1 To Len(Hex)
        Select Case Mid(Hex, Len(Hex) - i + 1, 1)
            Case "0": B = B + 16 ^ (i - 1) * 0
            Case "1": B = B + 16 ^ (i - 1) * 1
            Case "2": B = B + 16 ^ (i - 1) * 2
            Case "3": B = B + 16 ^ (i - 1) * 3
            Case "4": B = B + 16 ^ (i - 1) * 4
            Case "5": B = B + 16 ^ (i - 1) * 5
            Case "6": B = B + 16 ^ (i - 1) * 6
            Case "7": B = B + 16 ^ (i - 1) * 7
            Case "8": B = B + 16 ^ (i - 1) * 8
            Case "9": B = B + 16 ^ (i - 1) * 9
            Case "A": B = B + 16 ^ (i - 1) * 10
            Case "B": B = B + 16 ^ (i - 1) * 11
            Case "C": B = B + 16 ^ (i - 1) * 12
            Case "D": B = B + 16 ^ (i - 1) * 13
            Case "E": B = B + 16 ^ (i - 1) * 14
            Case "F": B = B + 16 ^ (i - 1) * 15
        End Select
        Next i
    HEX_to_DEC = B
End Function

#3


串口用中断好过定时器。

#4


最好用中断

#5



在中文系统中,用字符串方式处理会有问题吧?

#6


引用 1 楼 roock 的回复:
用下面函数即可:

VB code

Private Function strProcess(ByVal str As String) As String
Dim aStr, bStr As String
aStr = Mid(str, InStr(1, str, "AA"))
bStr = Mid(aStr, 1, InStrRev(aStr, "BB") + 1)
strPro……


不能这样用吧,因为AA这些数据都是十六进制的啊。不是字符串

#7


引用 3 楼 gzhjic 的回复:
串口用中断好过定时器。


支持3楼

#8


如果采用定时器方式,最好是令牌方式:主机先发出读取指令,然后再开启定时器,下位机接到读取指令后回发数据。定时器时间到后读取缓冲区,这样不会接受到许多重复数据;重复数据的处理在上位机也是比较麻烦的。

#9


下位机程序是你自己写的吗?如果是最好改一下,你的包结构不是很好,如果换到无线通讯或是设备安装比较复杂的环境,出问题的几率是很大的。

#10


引用楼主 lijuan1215_2009 的回复:
下位机上传的数据是这样的:
每次传8个字节(hex格式),例如AA 1 2 3 4 5 6 BB,这是一帧数据,AA和BB为起始和结束的标志位,中间没有空格的。

我现在定时器每个500ms取一次缓存区的数据,这次取到的数据是:
1 2 3 BB AA 1 2 3 4 5 6 BB AA 2 3 4 5 6 7 BB AA 5 6

我想去掉第一个AA前面的数和最后一个BB后面的数,然……


看你是在什么时候提取了,要是按照byte提取的话,那就在接受的时候就提取,自己再建一个byte的数组,把你接受的数据按照数组的顺序存储,要是接受玩了以后,再处理的话,就可以用right或者left或者mid函数,都可以了,关键是你的数据格式是不是每次都是这么几帧,这才是重点!

#1


用下面函数即可:

Private Function strProcess(ByVal str As String) As String
Dim aStr, bStr As String
aStr = Mid(str, InStr(1, str, "AA"))
bStr = Mid(aStr, 1, InStrRev(aStr, "BB") + 1)
strProcess = bStr
End Function

#2


引用 1 楼 roock 的回复:
用下面函数即可:

VB code

Private Function strProcess(ByVal str As String) As String
Dim aStr, bStr As String
aStr = Mid(str, InStr(1, str, "AA"))
bStr = Mid(aStr, 1, InStrRev(aStr, "BB") + 1)
strPro……



' 用途:将十六进制转化为十进制
' 输入:Hex(十六进制数)
' 输入数据类型:String
' 输出:HEX_to_DEC(十进制数)
' 输出数据类型:Long
' 输入的最大数为7FFFFFFF,输出的最大数为2147483647
Public Function HEX_to_DEC(ByVal Hex As String) As Long
    Dim i As Long
    Dim B As Long
    Hex = UCase(Hex)
    For i = 1 To Len(Hex)
        Select Case Mid(Hex, Len(Hex) - i + 1, 1)
            Case "0": B = B + 16 ^ (i - 1) * 0
            Case "1": B = B + 16 ^ (i - 1) * 1
            Case "2": B = B + 16 ^ (i - 1) * 2
            Case "3": B = B + 16 ^ (i - 1) * 3
            Case "4": B = B + 16 ^ (i - 1) * 4
            Case "5": B = B + 16 ^ (i - 1) * 5
            Case "6": B = B + 16 ^ (i - 1) * 6
            Case "7": B = B + 16 ^ (i - 1) * 7
            Case "8": B = B + 16 ^ (i - 1) * 8
            Case "9": B = B + 16 ^ (i - 1) * 9
            Case "A": B = B + 16 ^ (i - 1) * 10
            Case "B": B = B + 16 ^ (i - 1) * 11
            Case "C": B = B + 16 ^ (i - 1) * 12
            Case "D": B = B + 16 ^ (i - 1) * 13
            Case "E": B = B + 16 ^ (i - 1) * 14
            Case "F": B = B + 16 ^ (i - 1) * 15
        End Select
        Next i
    HEX_to_DEC = B
End Function

#3


串口用中断好过定时器。

#4


最好用中断

#5



在中文系统中,用字符串方式处理会有问题吧?

#6


引用 1 楼 roock 的回复:
用下面函数即可:

VB code

Private Function strProcess(ByVal str As String) As String
Dim aStr, bStr As String
aStr = Mid(str, InStr(1, str, "AA"))
bStr = Mid(aStr, 1, InStrRev(aStr, "BB") + 1)
strPro……


不能这样用吧,因为AA这些数据都是十六进制的啊。不是字符串

#7


引用 3 楼 gzhjic 的回复:
串口用中断好过定时器。


支持3楼

#8


如果采用定时器方式,最好是令牌方式:主机先发出读取指令,然后再开启定时器,下位机接到读取指令后回发数据。定时器时间到后读取缓冲区,这样不会接受到许多重复数据;重复数据的处理在上位机也是比较麻烦的。

#9


下位机程序是你自己写的吗?如果是最好改一下,你的包结构不是很好,如果换到无线通讯或是设备安装比较复杂的环境,出问题的几率是很大的。

#10


引用楼主 lijuan1215_2009 的回复:
下位机上传的数据是这样的:
每次传8个字节(hex格式),例如AA 1 2 3 4 5 6 BB,这是一帧数据,AA和BB为起始和结束的标志位,中间没有空格的。

我现在定时器每个500ms取一次缓存区的数据,这次取到的数据是:
1 2 3 BB AA 1 2 3 4 5 6 BB AA 2 3 4 5 6 7 BB AA 5 6

我想去掉第一个AA前面的数和最后一个BB后面的数,然……


看你是在什么时候提取了,要是按照byte提取的话,那就在接受的时候就提取,自己再建一个byte的数组,把你接受的数据按照数组的顺序存储,要是接受玩了以后,再处理的话,就可以用right或者left或者mid函数,都可以了,关键是你的数据格式是不是每次都是这么几帧,这才是重点!