VB串口发送一组168个字节的数据,其中前6个字节是发送16进制,后面160个字节是发送16进制的ASCII码,第167个字节是全面166个16进制数据的校检和取低位,再转换成16进制的ASCII码,就占了2个字节,全部数据就是168个字节的数据了这段代码可以实现发送数据了,但是好像稳定性不强,发送的数据可能会经常出错,是不是因为数据长度越大,出错的几率就越大?168个字节的数据发送出错几率大不大呢?有什么办法可以同样实现以上数据的发送,让发送的数据都正确,或者说可不可以优化一下这段代码呢?Private Sub clearDksj_Click() If MSComm1.PortOpen = False Then
 MsgBox "请先打开串口!", vbOKOnly + vbExclamation, "提示!"
 End If
 If MSComm1.PortOpen = False Then Exit Sub
 
 Dim send_buf() As Byte
 Dim Abyte(166) As Byte
 Dim ss As Single
 Dim XX As String
 
 Abyte(0) = &H1F
 Abyte(1) = &H6D
 Abyte(2) = &H30
 Abyte(3) = &H31
 Abyte(4) = &H2A
 Abyte(5) = &H2B
 
 For I = 6 To 165
Abyte(I) = &H30
NextFor I = 0 To 165
 ss1 = ss1 + Val(Abyte(I))
 Next
 
 Abyte(166) = ss1 Mod 256 XX = Right("00" & Hex(Abyte(166)), 2)
 
 send_buf = StrConv(Chr(&H1F) & Chr(&H6D) & Chr(&H30) & Chr(&H31) & Chr(&H2A) & Chr(&H2B) & Right(String(160, "0"), 160) & Right("00" & Hex(Abyte(166)), 2), vbFromUnicode)MSComm1.Output = send_bufEnd Sub

解决方案 »

  1.   


    ss1 = ss1 + Val(Abyte(I))ss1在哪定义的
      

  2.   

    Chr 函数
          返回 String,其中包含有与指定的字符代码相关的字符 。语法Chr(charcode)必要的 charcode 参数是一个用来识别某字符的 Long。说明0 到 31 之间的数字与标准的非打印 ASCII 代码相同。例如,Chr(10) 可以返回换行字符。charcode 的正常范围为 0 – 255。然而,在 DBCS 系统,charcode 的实际范围为 -32768 到 65535。注意   ChrB 函数作用于包含在 String 中的字节数据。ChrB 总是返回一个单字节,而不是返回一个字符,一个字符可能是一个或两个字节。ChrW 函数返回包含 Unicode 的 String,若在不支持 Unicode 的平台上,则其功能与 Chr 函数相同。Hex 函数
          返回代表十六进制数值的 String。语法Hex(number)必要的 number 参数为任何有效的数值表达式或字符串表达式。说明如果 number 还不是一个整数,那么在执行前会先被四舍五入成最接近的整数。如果 number 为 所得为 
    Null Null 
    Empty 零 (0) 
    任何其他的数字 最多可到八个十六进制字符。 
    适当范围内的数字,前缀以 &H,可以直接表示十六进制数字。例如,十六进制表示法的 &H10 代表十进制的 16。
      

  3.   


     send_buf = StrConv(Chr(&H1F) & Chr(&H6D) & Chr(&H30) & Chr(&H31) & Chr(&H2A) & Chr(&H2B) & Right(String(160, "0"), 160) & Right("00" & Hex(Abyte(166)), 2), vbFromUnicode)看看chr和hex的,你发的就不是16进制的ascii码,还有strconv的用法,应该这样用:
    strconv(abyte,vbUnicode)
      

  4.   

    前面6个字节发送的是16进制,后面的162个字节要求是16进制的ASCII码
      

  5.   


    发送端不必将发送数据转换成字符串。当其中有大于 128 的十六进制数时,中文操作系统会自作聪明地进行处理。
    Dim Abyte(167) As ByteAbyte(0) = &H1F
    Abyte(1) = &H6D
    Abyte(2) = &H30
    Abyte(3) = &H31
    Abyte(4) = &H2A
    Abyte(5) = &H2B
      
    For I = 6 To 165
    Abyte(I) = &H30
    NextFor I = 0 To 165
    ss1 = ss1 + Val(Abyte(I))
    NextXX = Right("0" & Hex(ss1), 2)
    Abyte(166) = Asc(Left(XX, 1))
    Abyte(167) = Asc(Right(XX, 1))MSComm1.Output = Abyte
      

  6.   

    我认为发送不是问题,只要你的发送缓冲区足够大是没有问题的。问题可能出在你处理字符的问题上。就如楼上所说,ASCII的可表达范围是:&H00~&H7F,如果大于这个数据就不是ASCII码了,你得转换可能需要ChrW来处理了。
      

  7.   

    168个字节应该不会的,mscomm默认OutBufferSize是512,你也可以加大
      

  8.   

     send_buf = StrConv(Chr(&H1F) & Chr(&H6D) & Chr(&H30) & Chr(&H31) & Chr(&H2A) & Chr(&H2B) & Right(String(160, "0"), 160) & Right("00" & Hex(Abyte(166)), 2), vbFromUnicode)MSComm1.Output = send_buf这样发绝对死翘翘,做那么多字符串操作,谁知道在哪里就不能识别了。不论你发的是什么数据,强烈建议都以二进制方式,存在byte数组里,一个字节一个字节的发。
      

  9.   

    我的串口设置是这样的:
    If cmdSwitchPort.Caption = "打开串口" Then
    ' Timer1.Enabled = False
     MSComm1.InBufferSize = 350 '初始化串口
     MSComm1.InBufferCount = 0
     MSComm1.InputMode = comInputModeBinary '二进制方式
     MSComm1.CommPort = CmbPortName.ListIndex + 1  '1
     MSComm1.Settings = "9600,N,8,1"
     MSComm1.RThreshold = 1
     MSComm1.InputLen = 0                                 '每次读入缓冲区所有字符
     MSComm1.PortOpen = True                          '打开串口
     cmdSwitchPort.Caption = "关闭串口"
     Shape1.FillColor = RGB(0, 255, 0)
    Else
     MSComm1.PortOpen = 0
     cmdSwitchPort.Caption = "打开串口"
     Shape1.FillColor = RGB(255, 0, 0)
     
    End If
    现在已经是二进制方式发送了是吗?
    串口这样设置可以吗?
      

  10.   

    如果你是以二进制发送,那么你的命令就是错误的你要把所有数据都存入数组,然后output=数组名  就可以了
      

  11.   

    楼主可以参考一下这个程序,串口调试器代码:
    http://download.csdn.net/source/1262066
      

  12.   

     Dim send_buf() As Byte
     Dim Abyte(167) As Byte
     Dim ss As Single
     Dim ss1 As Single
     Dim XX As String
     
     Abyte(0) = &H1F
     Abyte(1) = &H6D
     Abyte(2) = &H30
     Abyte(3) = &H31
     Abyte(4) = &H2A
     Abyte(5) = &H2B
     
     For I = 6 To 165
    Abyte(I) = &H30
    NextFor I = 0 To 165
     ss1 = ss1 + Val(Abyte(I))
     Next
     
     ss = ss1 Mod 256 XX = Right("00" & Hex(ss), 2)
     Abyte(166) = Asc(Left(XX, 1))
     Abyte(167) = Asc(Right(XX, 1))MSComm1.Output = Abyte
    End Sub
    现在我改成了这种方式发送,也可以发送数据
    我搞不明白的是,楼上的朋友说 以二进制发送,我的命令就是错误的,那为什么我之前的程序也可以发送数据,和单片机连接后可以发送正常的指令呢?
      

  13.   

    MSComm1.Output = Abyte
    用这种方法发送数组数据的时候,跟串口调试器测试发现那些数据又完全没有问题,为什么跟单片机传送数据的时候会经常出现数据错误呢,因为数据正确的话,单片机会返回一些指令回来,数据错误单片机则没有反映
    是发送数据的问题还是什么问题呢?