串口数据接收,该如何处理
串口数据接收
用串口读取仪表中的数据,为何第二次接收的数据有上一次的数据,并依此累推?第一次用串口,哪个参数设置错了?请大师们帮给看下
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
------解决思路----------------------
------解决思路----------------------
据说LZ已经解决问题了。
用串口读取仪表中的数据,为何第二次接收的数据有上一次的数据,并依此累推?第一次用串口,哪个参数设置错了?请大师们帮给看下
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已经解决问题了。