VB串口Mscomm接收字符串数据怎样才能这样处理和整理?

在用VB6编写一个软件,这个软件调用了VB中的Mscomm控件,通过此控件不断接收到从单片机或者PLC等下位机串口传输过来的字符串信息。
这些信息格式为字符串形式,如“A1245ZA1243ZA1242ZA1241ZA1242Z……A0001Z”,其实就是每组有用的数据为4位,这个4位的数字用“A”和“Z”包裹起来,因为接收串口的数据是用无线传输的方式进行的,往往会产生数据的丢失,所以,这里就需要一个方法,怎么能让用VB编的这个程序实现这个功能:判断接收到的4位数字的前面有一个“A”,后面还有一个“Z”,那么这就是一个有效的数据,否则这个数据就是无效的,需要丢弃?
另外,Mscomm控件是用实时响应接收好还是调用Timer控件做定时的串口数据查询接收好呢?我试过了Mscomm的实时响应接收,在数据快速传送时,CPU占有率会达到100%!
希望大家的帮忙,谢谢~
如果每接收一个字符触发一次事件,那么以9600bps接收的话,每秒钟需要处理960个事件~怎么能让程序能够及时判断有“A”的到来,有“Z”的结束,这时就需要触发一个事件~否则就什么都不要干。如果“接收的字符是否为6个,不是则丢弃”这种判断字符多少的方法也好像不妥,假如我先只接到了“45ZA12”,而后面是一组“34ZA13”,那么这两组数据虽然单独判断都是错误数据,但是其实这两组数据组合,里面包含了一个正确的数组,就是“A1234Z”,怎样可以把它提出来?另外,无线传输目前采用的是只为单向传输的,即单工通信,一边只能收,一边只能发。 仪器也只有一套,上位机是负责接收和数据整理记录功能的。如果有好的思路或办法,请用代码的形式回答,如
Private Sub Timer1_Timer()
End Sub
如果以思路的办法来回答的话,估计你很难理解其中的困难的,因为我已经做了很多尝试,谢谢~
zdingyun的程序我试过了,还是不太好用呀,还有我忘了,接收的数据是如“A1245ZA1243ZA1242ZA1241ZA1242Z……A125Z……A1Z”的,即发送的数减小,位数也跟着减小。还有,真的别让我再用MSComm1_OnComm() 来触发啦,连续快速接收的时候真的会程序假死的! 附数据接收情况如:

Option Explicit
Dim sj As String
Private Sub Form_Load()
MSComm1.Settings = "9600,n,8,1"
MSComm1.InputMode = comInputModeText
MSComm1.RThreshold = 1 '当接收缓冲区到达1-8字节产生1次OnComm事件
MSComm1.CommPort = 1
MSComm1.PortOpen = True
End Sub

Private Sub MSComm1_OnComm()
Select Case MSComm1.CommEvent
Case 2
sj = sj & MSComm1.Input
If Left(sj, 1) = "A" And Right(sj, 1) = "Z" Then
Text1 = Mid(sj, 2, Len(sj) - 2)
sj = ""
Else
MSComm1.PortOpen = False
sj = ""
MSComm1.PortOpen = True
End If
End Select
End Sub
回复LZ:"还有,真的别让我再用MSComm1_OnComm() 来触发啦,连续快速接收的时候真的会程序假死的!"
这种情况是存在的,就是有线连接串口通信也存在通信假四现象.但也不是不可解决的.
请参阅:
http://topic.csdn.net/u/20080220/23/f8b5fc30-7fd3-4db9-8eb0-0262b87e8089.html
http://topic.csdn.net/u/20071220/21/2dd86b50-2f5d-47b0-b4a9-3b232b493396.html
温馨提示:内容为网友见解,仅供参考
第1个回答  2009-03-21
双击MSCOMM控件进入OnComm,当有数据传输到PC机时就会触发这个事件,所以不需要在Timer中来实时监测。
下面是一个例子可以参考一下:
'*****************************************
'串口处理
'*****************************************
Private Sub MSComm_OnComm()

On Error GoTo hak:
Dim intInputLen As Integer
Dim str As String
Dim temp As Integer
Dim fl As Single
Dim i As Integer
Select Case MSComm.CommEvent
Case comEvReceive
RX = RX + 1
StatusBar1.Panels(4).Text = "接收:" & RX
intInputLen = MSComm.InBufferCount '是指调制解调器已接收,并在接收缓冲区等待被取走的字符数。
ReDim inbyte(intInputLen) ' 重新定义数组长度
inbyte = MSComm.Input
'按字符接收
If OpType(0).Value = True Then
For i = LBound(inbyte) To UBound(inbyte)
str = str + Chr(inbyte(i))
Next i
txtReceive.Text = txtReceive.Text & str
'十六进接收
ElseIf OpType(1).Value = True Then
For i = LBound(inbyte) To UBound(inbyte)
str = str + CStr(Hex(inbyte(i))) + Chr(32)
If Len(Hex(inbyte(i))) <= 1 Then
txtReceive.Text = txtReceive.Text & "0" & str
Else
txtReceive.Text = txtReceive.Text & str
End If
Next i
'整型接收
ElseIf OpType(2).Value = True Then
Dim bit As Byte
bit = inbyte(0)
For i = LBound(inbyte) To UBound(inbyte)
temp = temp + CLng(inbyte(i))
Next i
If bit >= 128 Then '判断是否为负
txtReceive.Text = txtReceive.Text & (temp - 255) & " "
Else
txtReceive.Text = txtReceive.Text & temp & " "
End If
End If
End Select
MSComm.InBufferCount = 0
hak:
MSComm.InBufferCount = 0
End Sub
第2个回答  推荐于2018-03-29
只能分时接收了
比如 char rev_buf[1024]
现接收1024个
在循环判断
rev[i]=='A'
rev[i+4]=='Z'
则为有效数字

另外:你的仪器为一台
这种单工通信还行
如果不止一台
则会有干扰
还不如不要上位机
当然 这只是我的想法而已本回答被网友采纳
第3个回答  2009-03-21
把comm控件设置为每6个字符激发一次oncomm事件。

这样实时读取就可以了。

用时钟控件也是可以的,定期把缓冲区的数据读出来,

再整理处理。
相似回答