当前位置:编程学习 > VB >>

vb串口通信的疑难杂症!!!在线等,急急急急!!!

下面是我用VB做的串口通信部分的接收代码,由于几天找不到问题出现在哪里,希望好心人帮忙看看怎么回事,谢谢!

Option Explicit
Dim strbuff As String
Dim inbte() As Byte
Dim outdata As Variant
Dim n As Integer
Dim indata As String
Dim n1 As Integer
Dim dd As String

Private Sub MSComm1_OnComm() '接收事件
   Dim I As Integer
    Select Case MSComm1.CommEvent
        Case 2
            strbuff = MSComm1.Input
            inbte() = strbuff
            For I = 0 To UBound(inbte)
                   indata = indata & Right("0" & Hex(inbte(I)), 2)
            Next I

            If Mid(indata, 1, 4) = "5A79" Then
                indata = ""
                Timer1.Enabled = False
                
                Timer2.Enabled = True
            
            ElseIf dd = "AA" And Mid(indata, 1, 18) = "358220100304050607" Then 
                Shape1.FillColor = vbGreen
                indata = ""
                MsgBox "连机OK!"
                Timer2.Enabled = False
                Timer1.Enabled = True                          
                n = 0
                n1 = 0
            Else
                MsgBox "接收代码有误", , "错误"
                indata = ""
                n1 = 0
                Timer2.Enabled = True
                Timer1.Enabled = False

            End If

            
通信协议:38400,n,8,1  
        以二进制接收


代码大致意思是:当单击联机命令按钮时,timer1打开发送请求通信命令0XAA,如果收到下位机发来的0X5A79,则timer1关闭timer2(发送联机命令)打开,如果收到0X358220100304050607,则indata清空tiner2关闭

问题是:下位机发送的358220100304050607,我只收到前面16位,提示接收代码有误,这是怎么回事啊,我接收缓冲区设置的是1024,
      请大家帮忙看看!在线等,急急,QQ:479702007
--------------------编程问答-------------------- 建议你用串口调试器发送一下命令,看看接受是什么 --------------------编程问答-------------------- 从OnComm事件触发到数据被完整的接收是需要时间的,你的程序在触发OnComm事件的时候就把数据从缓冲区里读走了,但是这个时候数据可能还没有传输完成呢,所以你只能取到一部分咯! --------------------编程问答-------------------- Option Explicit 
Dim strbuff As String 
Dim inbte() As Byte 
Dim outdata As Variant 
Dim n As Integer 
Dim indata As String 
Dim n1 As Integer 
Dim dd As String 

Private Sub MSComm1_OnComm() '接收事件 
  Dim I As Integer 
    Select Case MSComm1.CommEvent 
        Case 2 
            strbuff = MSComm1.Input 
            inbte() = strbuff 
            For I = 0 To UBound(inbte) 
                  indata = indata & Right("0" & Hex(inbte(I)), 2) 
            Next I 

            If Mid(indata, 1, 4) = "5A79" Then 
                indata = "" 
                Timer1.Enabled = False 
                MSComm1.RThreshold = 9 '***************************************
                Timer2.Enabled = True 
            
            ElseIf dd = "AA" And Mid(indata, 1, 18) = "358220100304050607" Then 
                Shape1.FillColor = vbGreen 
                indata = "" 
                MsgBox "连机OK!" 
                Timer2.Enabled = False 
                Timer1.Enabled = True                          
                n = 0 
                n1 = 0 
            Else 
                MsgBox "接收代码有误", , "错误" 
                indata = "" 
                n1 = 0 
                Timer2.Enabled = True 
                Timer1.Enabled = False 

            End If 
--------------------编程问答-------------------- 不懂,路过 --------------------编程问答-------------------- 还是建议楼主先用串口调试器调试一下
我的资源中有一个串口调试器(附代码),你可以下载下来,单步调试一下,看看会有什么情况,两相对比,问题就明了了。 --------------------编程问答--------------------
引用 2 楼 CityBird 的回复:
从OnComm事件触发到数据被完整的接收是需要时间的,你的程序在触发OnComm事件的时候就把数据从缓冲区里读走了,但是这个时候数据可能还没有传输完成呢,所以你只能取到一部分咯!

有同解。 --------------------编程问答-------------------- '-------------------------------------------------------------------------------------------------------------------------
'MSComm1.RThreshold预先设的是多少?16吗?
'其实,完全可以抛开MSComm1_OnComm()用自己定义的状态来写程序。比较繁琐,可靠性更高。
'我是凭感觉改的,indata在下一个MSComm1_OnComm() 不被清空,Timer2.Enabled =True在执行Timer2.time()时调用MSComm1_OnComm() 。
'-------------------------------------------------------------------------------------------------------------------------

Private Sub MSComm1_OnComm()  
  Dim I As Integer 
    Select Case MSComm1.CommEvent 
        Case 2                                         '收到 Rthreshold 个字符。该事件将持续产生直到用 Input 属性从接收缓冲区中删除数据。
            strbuff = MSComm1.Input 
            inbte() = strbuff 
            For I = 0 To UBound(inbte) 
                  indata = indata & Right("0" & Hex(inbte(I)), 2) 
            Next I 
            If Mid(indata, 1, 4) = "5A79" Then 
                indata = "" 
                Timer1.Enabled = False 
                Timer2.Enabled = True 
            ElseIf dd = "AA"  Then 
if len(indata)>18 and Mid(indata, 1, 18) = "358220100304050607" then
Shape1.FillColor = vbGreen 
indata = "" 
MsgBox "连机OK!" 
Timer2.Enabled = False 
Timer1.Enabled = True                          
n = 0 
n1 = 0 
elseif len(indata)<18 then
Timer2.Enabled =True            '下一个循环继续接收字符。
MSComm1.RThreshold = 1 '为了接受准确,如果上次发了16个字符而下次只发2个字符MSComm1.RThreshold设置>2可能永远会报错。
else
MsgBox "接收代码有误", , "错误" 
indata = "" 
n1 = 0 
Timer2.Enabled = True 
Timer1.Enabled = False 
exit sub
endif
            Else 
                MsgBox "接收代码有误", , "错误" 
                indata = "" 
                n1 = 0 
                Timer2.Enabled = True 
                Timer1.Enabled = False 
exit sub
            End If 
--------------------编程问答--------------------
引用 3 楼 of123 的回复:
Option Explicit 
Dim strbuff As String 
Dim inbte() As Byte 
Dim outdata As Variant 
Dim n As Integer 
Dim indata As String 
Dim n1 As Integer 
Dim dd As String 

Private Sub MSComm1_OnComm() '接收事件 
  Dim I As Integer 
    Select Case MSComm1.CommEvent 
        Case 2 
            strbuff = MSComm1.Input 
            inbte() = strbuff 
            For I = 0 To UBound(inbte) 


我认为欠妥,1>MSComm1.RThreshold = 9这句加的位置有待商榷。2>如果下个循环只发2~3个字符,MSComm1_OnComm事件就不会发生。 --------------------编程问答-------------------- 串口的数据发送与TCP/IP 不同,不是分包的.当串口有数据到数,并不意味着所有的数据全部到达,所以这时你要就循环取数据,但这要求你的通信协议要完善,即使从中间拆开数据,也能将它们拼回.
补充:VB ,  网络编程
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,