我用VB写了一个关于MODBUS的协议
可是在接收时产生了问题
我用的是MSComm1_OnComm事件接受的,代码如下:
Dim nowstring As Variant
Dim i As Integer
Select Case MSComm1.CommEvent
Case comEvReceive '接收事件
'接收缓冲区收到Rthreshold个字符时触发
If MSComm1.InBufferCount Then
nowstring = MSComm1.Input
For i = LBound(nowstring) To UBound(nowstring)
InString = InString & CStr(Hex(Val(nowstring(i)))) & " "
Next i
nowstring = ""
end if
比如我发送的数据是 01 04 00 00 00 10 F1 C6
接收的数据应该为01 04 20 04 B2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 B1 1B
可是有时这个数据接收过来是正确的,有时只接受到01 04 20 04 B2 00 00 00
怎样才能正确接收啊?
我设置的MSCOMM的属性为
MSComm1.Settings = "19200,8,N,1"
MSComm1.CommPort =1
MSComm1.SThreshold = 1
MSComm1.RThreshold = 1
MSComm1.InputLen = 0
MSComm1.PortOpen=true
MSComm1.InputMode = comInputModeBinary请各位大侠帮忙啊!在下不胜感激!
可是在接收时产生了问题
我用的是MSComm1_OnComm事件接受的,代码如下:
Dim nowstring As Variant
Dim i As Integer
Select Case MSComm1.CommEvent
Case comEvReceive '接收事件
'接收缓冲区收到Rthreshold个字符时触发
If MSComm1.InBufferCount Then
nowstring = MSComm1.Input
For i = LBound(nowstring) To UBound(nowstring)
InString = InString & CStr(Hex(Val(nowstring(i)))) & " "
Next i
nowstring = ""
end if
比如我发送的数据是 01 04 00 00 00 10 F1 C6
接收的数据应该为01 04 20 04 B2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 B1 1B
可是有时这个数据接收过来是正确的,有时只接受到01 04 20 04 B2 00 00 00
怎样才能正确接收啊?
我设置的MSCOMM的属性为
MSComm1.Settings = "19200,8,N,1"
MSComm1.CommPort =1
MSComm1.SThreshold = 1
MSComm1.RThreshold = 1
MSComm1.InputLen = 0
MSComm1.PortOpen=true
MSComm1.InputMode = comInputModeBinary请各位大侠帮忙啊!在下不胜感激!
接收数据的长度是不固定的
MSComm1.CommPort = 1 'COM端口
MSComm1.Settings = "19200,n,8,1"
MSComm1.InputMode = comInputModeBinary '采用二进制传输
MSComm1.InBufferCount = 0 '清空接受缓冲区
MSComm1.OutBufferCount = 0 '清空传输缓冲区
'MSComm1.SThreshold = 1 '如果传输缓冲区完全空时产生MSComm事件
MSComm1.RThreshold = 1 '产生MSComm事件
MSComm1.PortOpen = True
Text3 = "" '打开端口
End SubPrivate Sub MSComm1_OnComm()
On Error Resume Next
Dim BytReceived() As Byte
Dim strBuff As String
Dim strData As String
Dim i As Integer
Dim x As Integer
Select Case MSComm1.CommEvent
Case 2
MSComm1.InputLen = 0
strBuff = MSComm1.Input
BytReceived() = strBuff
For i = 0 To UBound(BytReceived)
If Len(Hex(BytReceived(i))) = 1 Then
strData = strData & "0" & Hex(BytReceived(i))
Else
strData = strData & Hex(BytReceived(i))
End If
Next
Text3 = Text3 + strData
If Left(strData, 2) = "00" And Len(strData) = 8 Then '接收4字节
Text1(0).Text = Left(strData, 8)
Call DataClear
ElseIf Left(strData, 2) = "01" And Len(strData) = 74 Then '接收37字节
Text1(1).Text = Left(strData, 74)
Call DataClear
End If
End Select
End SubPublic Sub DataClear()
MSComm1.OutBufferCount = 0 '清空发送缓冲区
MSComm1.InBufferCount = 0
Text3 = ""
End Sub
我接受的数据不是固定的,这得看我发送的数据是多少
比如我发送的数据是
01 04 00 00 00 10 f1 c6
那么我的数据长度就是10,即16位
而此时我接受的数据就是16*2=32位
另外的数据是地址、功能和校验码
如果我发送的数据是,这里就是37位
01 04 00 00 00 07 B1 C8
那么数据长度就是07 ,即14位
接收的数据就为28位
如果再加上其他的数据总共是33位发送和接收的数据都是十六进制
现在这个问题我已经解决了
加入了延时,可是我还是不明白为什么加入延时才可以呢?
发送命令时间间隔调大些。
RS232串口连接距离不宜过长,可能有干扰。在接收代码中增加判断代码。
建议返回数据固定字节长,可补足字节长。不回接收出错,字节长尽可能为8的倍数。
Private Sub Timer1_Timer()
Dim i As Integer
Static j As Byte
Dim bytData(1) As Byte
j = j + 1
For i = 0 To 1
bytData(i) = &H0 + j
Next
If j >= 4 Then
j = j - 4
End If
Call SendData(bytData) '发送
End Sub
在窗体初始化设置
Timer1.Interval = 100 '数字可调,最小55,TIMER控件每秒系统提供18次变化
应该接收到01 04 14 04 B2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7B 67 可是为什么不设断点的时候就接收错误,只有设了断点以后逐步调试才能接收到正确的数据,这是为什么?
比如01 04 00 00 00 02 71 CB
01 04 00 00 00 06 70 08
01 04 00 00 00 0A 70 0D
01 04 00 00 00 0E 71 CE
01 04 00 01 00 02 20 0B
01 04 00 01 00 06 21 C8
01 04 00 01 00 0A 21 CD
01 04 00 01 00 0E 20 0E
01 04 00 02 00 02 D0 0B
01 04 00 02 00 06 D1 C8
01 04 00 02 00 0A D1 CD
01 04 00 02 00 0E D0 0E
。
01 04 00 0D 00 02 E0 08
01 04 00 0E 00 02 10 08
这些接收时必须要设短点才能接收到正确的结果,否则错误
如果用TIME等去查询,就失去了使用事件的意义,而且如果上位机工作压力过大的话,很有可以失掉数据,用TIME延时的时间也不好控制,太大了不好,太小了还是会丢数据.实际的根源在于:当你响应ON_COMM时,这时候,很有可能控件已经再接收到了新的数据,此时的数据数目已经不再是你刚进入事件处理程序时取得的数据长度了,所以,删除数据时的依据不能以刚刚进入程序时取得的数据长度为准.就说这么多了,希望对大家有点帮助.
1 检查你的初始化 是否正确, 波特率设置的不要太高建议使用9600,可能232的晶震不能提供这么高的频率
2 MSComm1.RThreshold 值根据需要设置可以设置的大一些.
3 用"串口调试助手"调试
4 如果你是要与单片机(C51 128 )通信应该使用 双字节的16进制编码.
怎么样双击表头进行双向排序
在网上找了一些例子不使用
不知道怎么写
有那位兄弟有这方面的事例
不是在(。NET)