我写了一个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 ,不知道我的理解哪里不对,还请帮我指点迷津,谢谢各位了 

解决方案 »

  1.   

    1)OnComm接收事件的必要条件是Rthreshold设置为不为0的正整数.
    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 & .....
    故能得到正确的接收结果.
      

  2.   

    若 Rthreshold 属性设置为 0,则当接收字符后,不产生 OnComm 事件。
    设置 Rthreshold 为 1,接收缓冲区收到每一个字符都会使 MSComm 控件产生 OnComm 事件。
      

  3.   

    我以前的一些做法,仅供参考:
    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
      

  4.   

    给你一个VB的串口调试器源码,你可以借鉴它的,搞懂了这个,可以说你就理解了串口通信。
    http://download.csdn.net/source/1262066
      

  5.   

    再给你推荐一个串口通信的书籍,参考一下:
    http://download.csdn.net/source/1498637
    http://download.csdn.net/source/1498644
      

  6.   

    下面给你关闭和打开comm事件的控制方法:
    Public Sub CloseOnComm()''关闭
    MobComm.RThreshold = 0
    MobComm.InputMode = comInputModeText
     
    End Sub
    Public Sub OpenOnComm()'打开MobComm.RThreshold = 1
    MobComm.InputMode = comInputModeBinaryEnd Sub