串口数据接收,该如何处理

串口数据接收
用串口读取仪表中的数据,为何第二次接收的数据有上一次的数据,并依此累推?第一次用串口,哪个参数设置错了?请大师们帮给看下
Dim flag      As Boolean

'=====================================================================================
Sub Chushihua(chuankou As Integer, Bote As String, xiaoyan As String, shuju As Integer, tizhi As Integer) '串口初始化
    On Error GoTo Err
    If MSComm1.PortOpen = True Then
        MSComm1.PortOpen = False
    End If                                                                      '先判断串口是否关闭,如果打开则关闭
    MSComm1.CommPort = chuankou                                                 '设置端口
    MSComm1.Settings = Bote & " , " & xiaoyan & " , " & shuju & " , " & tizhi   '设置波特率,校验位,数据位,停止位
    MSComm1.InBufferSize = 1024                                                 '接受缓冲区为1024字节
    MSComm1.OutBufferSize = 2048                                                '发送缓冲区位2048字节
    MSComm1.SThreshold = 1
    MSComm1.InBufferCount = 0                                                   '输入区清空
    'MSComm1.InBufferCount = 1
    MSComm1.OutBufferCount = 0                                                  '输出区清空
    MSComm1.RThreshold = 1                                                      '设置接受缓冲区获得一个字符时触发oncomm 事件
    MSComm1.PortOpen = True                                                     '打开串口,测试是否成功
    MSComm1.InputMode = comInputModeBinary
     Cmdopen.Caption = "关闭串口"
    If MSComm1.PortOpen = True Then
        
    End If
    Exit Sub

Err:
    MsgBox "端口被占用或无"
    Closechukou

End Sub
'=====================================================================================
Sub Reset(chuankou As Integer, Bote As String, xiaoyan As String, shuju As Integer, tizhi As Integer)
    On Error GoTo Err

    If MSComm1.PortOpen = True Then MSComm1.PortOpen = False                    '先判断串口是否关闭,如果打开则关闭
    MSComm1.CommPort = chuankou                                                 '设置端口
    MSComm1.Settings = Bote & " , " & xiaoyan & " , " & shuju & " , " & tizhi   '设置波特率,校验位,数据位,停止位
    MSComm1.PortOpen = True                                                     '打开串口

    If MSComm1.PortOpen = True Then
      
        Cmdopen.Caption = "关闭串口"
        '            Label7.Caption = "Statu  :" & C1.Text & "  open  " & " , " & C2.Text & " , " & C3.Text & " , " & C4.Text & " , " & C5.Text
      
    End If

    Exit Sub                                                                    '一定注意,否则当成功打开portopen时,会继续执行err,执行里面的关闭串口事件
Err:
    MsgBox "串口被占用或无"
    Closechukou
End Sub
'=================================================================
Sub Closechukou()
    If MSComm1.PortOpen = True Then MSComm1.PortOpen = False                    '先判断串口是否关闭,如果打开则关闭
    Cmdopen.Caption = "开启串口"
    '     Label7.Caption = " Statu : port is closed"
    'MsgBox "fasfds"


End Sub
'=================================================================
Sub Startchukou()
    If MSComm1.PortOpen = True Then MSComm1.PortOpen = False                    '先判断串口是否关闭,如果打开则关闭
    Call Reset(Val(Mid(C1.Text, 4, 1)), C2.Text, Left(C3.Text, 1), C4.Text, C5.Text)
End Sub
Private Sub cmdopen_Click()
    If MSComm1.PortOpen = True Then
        flag = True
    Else
        flag = False
    End If
    If flag = False Then
        Call Startchukou                                                        '打开串口
    Else
        Call Closechukou                                                        '关闭串口
    End If


End Sub

Private Sub Form_Load()
    On Error GoTo Err
    If MSComm1.PortOpen = True Then MSComm1.PortOpen = False                    '先判断串口是否关闭,如果打开则关闭
    Call Chushihua(Val(Mid(C1.Text, 4, 1)), C2.Text, Left(C3.Text, 1), C4.Text, C5.Text)

Err:
End Sub
'===============================================================================================

'================================================================================================

Private Sub MSComm1_OnComm()                                                    '当接收到一个字符时,触发oncomm事件

    Select Case MSComm1.CommEvent
        Case 2                                                                  '即commreceive 接受触发事件
'            MSComm1.RThreshold = 9
'            MSComm1.RThreshold = 51
            MSComm1.InputLen = 0
''''            一次读完发送缓冲区的内容,即每次缓冲区清空,若要设置其他值,必须比MScomm1.RThreshold值小,
''''            其代表每次读取发送缓冲区中的字符数,如剩余,会自动作为下次+几个字符=RThrshold值时,发送。这样的过程一直执行

            Text2.Text = HexJieShou
    End Select
End Sub



Private Sub Command1_Click()

TXstr = "01034C436C02D30000000000000000436C02D300000000436C02D300000000000000000000000000000000BEC80000BEC80000C04800003F480000BEC80000BEC80000C048000000000000BF7FFFFE63C3"
Text1.Text = TXstr
HexFaSong (Text1.Text)
End Sub
Private Sub Command2_Click()
Text2.Text = ""
End Sub

Private Sub Command7_Click()
'TXstr = "01030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2V2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F"
'TXstr = "01030000003CC5C8"
TXstr = "01034C436C02D30000000000000000436C02D300000000436C02D300000000000000000000000000000000BEC80000BEC80000C04800003F480000BEC80000BEC80000C048000000000000BF7FFFFE63C3"
Text1.Text = TXstr
End Sub

模块
Dim RXstr As String
Dim aa() As Byte
Dim sj As Byte
Dim StrB() As String
Dim Strudate  As String
Public Function HexFaSong(HexShu As String)  '处理十六进制时output的发送事件
'==============================================================
'十六进制必须是两位
'==============================================================
With Form1
    Dim sj() As Byte
    
  If .MSComm1.PortOpen = True Then '如果comm 口打开,则执行
        If Trim(HexShu) = "" Then
        MsgBox "发送字节不能为空"
        Exit Function
        End If
 '=============================================================
        '如果发送区为空,则退出程序
'=============================================================

            .MSComm1.InputMode = comInputModeBinary
'=============================================================
'       调用十六进制发送hexsend子程序
        '=============================================================
  
    struf = Trim(HexShu)
    If Len(struf) Mod 2 = 0 Then
        ReDim sj(Len(struf) / 2 - 1) '重新定义,把两个字符作为数组的一项,所以除2,第一项位0,所以减一
        For i = 0 To Len(struf) - 1 Step 2 '连个作为一项,所以除2,又以0开始,所以减1,所以一共是这么多项
            sj(i / 2) = Val("&H" & Mid(struf, i + 1, 2)) '两个作为一项,十六进制按每次从第i+1项开始,保留2位字符。记住不会有01只有1,所以Jieshouchuli()子程序添加0!!!!!!!!!!!!!!!!!!!
        Next i
        .MSComm1.Output = sj() '以数组形式发送,RThresold=1 ,则数组以一项发送,触动一次Oncomm事件,触发一次则两个字符,也是一个十六进制
    Else
        MsgBox "数据格式不对"
    End If
    Else
    MsgBox "串口关闭"
    Exit Function
 End If
 End With
 
End Function


Public Function HexJieShou() As String '处理十六进制和二进制的oncomm事件
With Form1

  If .MSComm1.PortOpen = True Then '如果comm 口打开,则执行
        aa() = .MSComm1.Input
        For i = LBound(aa) To UBound(aa)
            If Len(Hex(aa(i))) = 1 Then
                Strudate = Strudate & "0" & Hex(aa(i))
            Else
                Strudate = Strudate & Hex(aa(i))
            End If
        Next i
       HexJieShou = Strudate & vbNewLine
        Else
    MsgBox "串口关闭"
    Exit Function
End If

         End With
End Function







------解决思路----------------------
'定义一个数据缓冲池,这里用Collection对象作缓冲池,你也可以用数组或其他东西
Dim coldata As Collection
  
Private Sub Form_Load()
    '初始化数据缓冲池
    Set coldata = New Collection
  
    '初始化并打开串口
    MSComm1.CommPort = 1
    MSComm1.Settings = "9600, n, 8, 1"
    MSComm1.RThreshold = 1     '设置为每收到一个字节数据触发一次Oncomm事件
    MSComm1.InputMode = comInputModeBinary
    MSComm1.PortOpen = True
End Sub
  
Private Sub MSComm1_OnComm()
Dim yy As Long
Select Case MSComm1.CommEvent
Case comEvReceive
    Dim xx() As Byte
    xx = MSComm1.Input
    For yy = 0 To UBound(xx) '把串口接收到的所有数据都先保存到数据缓冲池暂时不去处理,因为无法保证数据已经接收完整
        coldata.Add xx(yy)
    Next yy
End Select
End Sub
  
'用Timer控件循环对接收到的数据进行处理
Private Sub Timer1_Timer()
    if coldata.count<6 then exit sub   '收到的数据不足6个
  
    Dim xx As Long
    For xx = 1 To coldata.Count     '遍历所有串口收到的数据
         if coldata.item(1)<>&H3F then 
            coldata.remove(1)    '收到的第一个字节不是3F,丢弃
            exit for
        end if
  
        '……  代码略,按照通讯协议对串口收到的数据进行分析和处理
        '…… 处理完成及时把已处理的数据从缓冲池中移除
    Next xx
End Sub

------解决思路----------------------
据说LZ已经解决问题了。