我写了一个com口程序,是用来发送16进制数的,也是在网上七拼八凑也算做成功了虽然功能能实现,因为程序有部分是在网上搜到得,有一些还不理解,希望能在这找到答案
主要是接受部分的程序:
Private Sub MsComm1_OnComm() '接收数据
Dim strData As Variant
Dim BytReceived() As Byte
Dim strBuff As String
Select Case MSComm1.CommEvent
Case 2
strBuff = MSComm1.Input '
BytReceived() = strBuff '如果是二进制接收模式则进行数据处理,否则直接显示字符串 Dim i As Integer
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
End Select Text2=strData
现在我发送 02 03 00 01 00 01 D5 F9 给com口,com口 接收到得数据和发送的一样,也就是说程序时没问题的, 但我现在就有个疑问,MsComm1_OnComm()事件是串口里一旦有字符了,就执行,即使数据还在往串口里发,如果总共有8个字符需要发送,目前已经收到了1个,应该就执行MsComm1_OnComm()事件了,然后就执行下面这句:
Select Case MSComm1.CommEvent
Case 2 通过查帮助得知: 收到 Rthreshold 个字符。该事件将持续产生直到用 Input 属性从接收缓冲区中删除数据。
也就是说收到在Rthreshold 中定义的字节数就会产生2的事件,我在Rthreshold 里写的是0,应该是一有数据,
而且通讯无误就返回一个2,这也没错。问题就在这个for循环上 Dim i As Integer
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 Text2 = strData 如果才刚刚接受到了一个字符,虽然还有7个还没收到,那也就是说程序也开始触发执行了,到上面这句FOR循环上,这句程序的意思就是将每个字符值连起来,但目前才一个字符,比如02,执行完已经是strData为02了,因为BytReceived(0)为存放第一个值的数组项,然后再循环,i=1了,由于可能其他7个字符还没有收到(不会那么巧,一个循环后,另外一个
字符到达),而前面的数据被清除了,那BytReceived(1)可能就是0了,又一次循环后,理论上讲就应该是 strdata为02 00 了,但执行结果却是正确的02 03 00 01 00 01 D5 F9 ,不知道我的理解哪里不对,还请帮我指点迷津,谢谢各位了
主要是接受部分的程序:
Private Sub MsComm1_OnComm() '接收数据
Dim strData As Variant
Dim BytReceived() As Byte
Dim strBuff As String
Select Case MSComm1.CommEvent
Case 2
strBuff = MSComm1.Input '
BytReceived() = strBuff '如果是二进制接收模式则进行数据处理,否则直接显示字符串 Dim i As Integer
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
End Select Text2=strData
现在我发送 02 03 00 01 00 01 D5 F9 给com口,com口 接收到得数据和发送的一样,也就是说程序时没问题的, 但我现在就有个疑问,MsComm1_OnComm()事件是串口里一旦有字符了,就执行,即使数据还在往串口里发,如果总共有8个字符需要发送,目前已经收到了1个,应该就执行MsComm1_OnComm()事件了,然后就执行下面这句:
Select Case MSComm1.CommEvent
Case 2 通过查帮助得知: 收到 Rthreshold 个字符。该事件将持续产生直到用 Input 属性从接收缓冲区中删除数据。
也就是说收到在Rthreshold 中定义的字节数就会产生2的事件,我在Rthreshold 里写的是0,应该是一有数据,
而且通讯无误就返回一个2,这也没错。问题就在这个for循环上 Dim i As Integer
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 Text2 = strData 如果才刚刚接受到了一个字符,虽然还有7个还没收到,那也就是说程序也开始触发执行了,到上面这句FOR循环上,这句程序的意思就是将每个字符值连起来,但目前才一个字符,比如02,执行完已经是strData为02了,因为BytReceived(0)为存放第一个值的数组项,然后再循环,i=1了,由于可能其他7个字符还没有收到(不会那么巧,一个循环后,另外一个
字符到达),而前面的数据被清除了,那BytReceived(1)可能就是0了,又一次循环后,理论上讲就应该是 strdata为02 00 了,但执行结果却是正确的02 03 00 01 00 01 D5 F9 ,不知道我的理解哪里不对,还请帮我指点迷津,谢谢各位了
2)FOR NEXT循环中使用了字符串连接方法
If Len(Hex(BytReceived(i))) = 1 Then
strData = strData & "0" & Hex(BytReceived(i))
Else
strData = " " & strData & Hex(BytReceived(i))
End If
strData = strData & .....
故能得到正确的接收结果.
设置 Rthreshold 为 1,接收缓冲区收到每一个字符都会使 MSComm 控件产生 OnComm 事件。
mscomm主要设置如下:Private Sub iniMscomm()
On Error Resume Next
'=====-----初始化通信串口-----=====
MSComm1.CommPort = 1 '使用 COM1
MSComm1.Settings = "9600,N,8,1" '9600 波特,无奇偶校验,8 位数据,一个停止位
MSComm1.PortOpen = True '打开端口
MSComm1.RThreshold = 1 '缓冲区有1个字节就产生OnComm事件
MSComm1.InputLen = 0 '为 0 时,使用 Input 将使 MSComm 控件读取接收缓冲区中全部的内容。
MSComm1.InputMode = comInputModeBinary 'Input以二进制形式取回用comInputModeBinary,以文本形式取回是(缺省项)
MSComm1.RTSEnable = True
MSComm1.InBufferCount = 0 '清空缓冲区
End SubMSComm1.RThreshold = 1说明缓冲区有1个字节就产生oncomm事件,
如果你想8个字节一触发oncomm事件,那么你要MSComm1.RThreshold = 8,这对定长串接收特别有用。很多时候我们的串长度不定,那么我们就要用MSComm1.RThreshold = 1,一字节一触发事件,然后累计串。
这有几种处理方式:
1、让缓冲区替我们累加串Private Sub MSComm1_OnComm()
Dim t1 As Long
t1 = Timer
Select Case MSComm1.CommEvent
Case comEvReceive '收到 RThreshold定义的字符数1字节
Do
DoEvents
Loop While Timer - t1 < 1.5'1.5秒后上一次数据发完,且下一次数据不会到达,时间自己调
Call Receive '调用数据处理
End Select
End Sub
Private Sub Receive()
Dim str1 As String, com_String() As Byte
Dim i As Integer, L As Integer
com_String = MSComm1.Input'在这一次读取8字节数据,然后进行处理
L = UBound(com_String)
For i = 0 To L
str1 = str1 & Chr(com_String(i))
Next
If InStr(str1, "SEND OK") Then
send_ok = True
ElseIf InStr(str1, "@@") Then
Timer3.Enabled = False
intoDatabase com_String
End IfEnd Sub
2、自己累加,用不着循环
Private Sub MSComm1_OnComm()
Dim t1 As Long
static L_str as string
t1 = Timer
Select Case MSComm1.CommEvent
Case comEvReceive '收到 RThreshold定义的字符数1字节
com_String = MSComm1.Input
L_str = L_str & com_String '触发事件就累加串
if instr(L_str,"@") then'收到结束符就去处理这一句
call ...
L_str=""
endif
End Select
End Sub
http://download.csdn.net/source/1262066
http://download.csdn.net/source/1498637
http://download.csdn.net/source/1498644
Public Sub CloseOnComm()''关闭
MobComm.RThreshold = 0
MobComm.InputMode = comInputModeText
End Sub
Public Sub OpenOnComm()'打开MobComm.RThreshold = 1
MobComm.InputMode = comInputModeBinaryEnd Sub