liufuyao1234
级别: 略有小成
精华主题: 0
发帖数量: 128 个
工控威望: 443 点
下载积分: 747 分
在线时间: 120(小时)
注册时间: 2011-03-24
最后登录: 2021-05-13
查看liufuyao1234的 主题 / 回贴
楼主  发表于: 2015-06-24 15:35
  对VB不是很了解,现遇到个读取端口数据处理的问题。

Public Function ReceiveData() As String
    Dim I As Integer                    '
    Dim cnum As Integer                 '定义为接收到的字符个数
    Dim ChRcv(1 To 100) As String * 2 '定义为
    Dim strRcv As String                '定义为接收字符的存放字符串
    Dim InputRcv As Variant             '定义为接收缓冲区数据的暂存处
    Dim LoopCheck As Byte               '定义为用于循环检测的变量
    cnum = 0
    I = 0
    FormMain.TimerRcvDelay.Enabled = True           '接收延时计时器打开
    LoopCheck = 0
    strRcv = ""
    InputRcv = ""

    FormMain.MSComm1.InputLen = 1                                '逐个读取字符。
    '接收操作,循环
    Do
        DoEvents                                             '当COM端口不对时,DO..loop循环便执行该空操作,若无此句,陷入死循环
        If DelayTime > 2000 Then GoTo ERROR             '超时1s 提示错误
        If FormMain.MSComm1.InBufferCount > 0 Then               '判断接收缓存字节>0
            InputRcv = FormMain.MSComm1.Input
            I = I + 1
            DataRcv(I) = InputRcv(0)
            LoopCheck = InputRcv(0)                     'LoopCheck变量用于循环条件的检测,不可直接用InputRcv来检测,因为COM端口不对时,InputRcv = FORMMAIN.MSComm1.Input 不执行,InputRcv(0)为可变型,而AscB("}")为Byte类型,产生数据类型不匹配的错误
        End If
   Loop Until (LoopCheck = CInt(&H7D))            '条件中的单变量 要变为(0),即InputRcv -》InputRcv(0),不知道为什么???
    
    FormMain.TimerRcvDelay.Enabled = False              '数据接收完毕后,延时定时器停止
    DelayTime = 0                                       '延时计时器清零
        cnum = I                                            '字符个数
    For I = 1 To cnum
                'ChRcv(I) = Hex(DataRcv(I))
        'ChRcv(I) = Chr(DataRcv(I))
     ChRcv(I) = String(2 - Len(Hex(DataRcv(I))), "0") & Hex(DataRcv(I))  '在换算成十六进制数一位时前面+"0"
     strRcv = strRcv + ChRcv(I)
    Next I
      FormMain.Label15.Caption = strRcv                  '显示到主页面
      ReceiveData = strRcv                                '返回函数值
  
    Exit Function
   ERROR:
    MsgBox "无法接收下位机响应数据,请更换COM端口或检查接线!", vbOKOnly, "通知你"
    If FormMain.MSComm1.PortOpen = True Then FormMain.MSComm1.PortOpen = False
    FormMain.TimerRcvDelay.Enabled = False                       '延时定时器停止
    DelayTime = 0                                       '延时计时器清零

End Function
这段程序一般情况下没什么问题,当下位机返回值与贞尾字符一样时就会读取字符不全,造成错误。
如 返回值:7B 00 0D 0C F0 00 00 2C 7D AA AA 06 7D  ;
当第9个字节与最后一个字节相同时 只读取了第一个(7D)前面的字符这时就出错了。7至9字节是下位机返回的测量值。第十二字节是校验和,也有可能会出现(7D)字符。下位机还会返回设置完成的应答字符串(7B 00 09 0C 5A 80 00 EF 7D)这个返回的值是固定的。

请教各位高手我要怎么来处理这个应答。
liufuyao1234
级别: 略有小成
精华主题: 0
发帖数量: 128 个
工控威望: 443 点
下载积分: 747 分
在线时间: 120(小时)
注册时间: 2011-03-24
最后登录: 2021-05-13
查看liufuyao1234的 主题 / 回贴
1楼  发表于: 2015-06-24 19:35
当应答字符串中间有7D时这个循环就结束了 Loop Until (LoopCheck = CInt(&H7D))
7B 00 0D 0C F0 00 00 2C 7D
用什么条件来结束这个DO    L00P Until  不会出错呢?
892777011
级别: 略有小成
精华主题: 0
发帖数量: 213 个
工控威望: 334 点
下载积分: 1052 分
在线时间: 181(小时)
注册时间: 2014-06-24
最后登录: 2021-11-21
查看892777011的 主题 / 回贴
2楼  发表于: 2015-06-24 20:11
引用
引用第1楼liufuyao1234于2015-06-24 19:35发表的  :
当应答字符串中间有7D时这个循环就结束了 Loop Until (LoopCheck = CInt(&H7D))
7B 00 0D 0C F0 00 00 2C 7D
用什么条件来结束这个DO    L00P Until  不会出错呢?

你是和什么通讯的,我用vb和基恩士GT2通讯是直接读取MSComm1.Input接受到的数据,VB会自动把接收到的通讯码转换为字符和十进制数值,再用字符串指令取出数值就行了,没有你这么麻烦啊
892777011
级别: 略有小成
精华主题: 0
发帖数量: 213 个
工控威望: 334 点
下载积分: 1052 分
在线时间: 181(小时)
注册时间: 2014-06-24
最后登录: 2021-11-21
查看892777011的 主题 / 回贴
3楼  发表于: 2015-06-24 20:14
试试在这里加一个条件,当接收的数据大于某个值并且  LoopCheck = CInt(&H7D))时再退出,例如  Loop Until (LoopCheck = CInt(&H7D) and i >10 )
liufuyao1234
级别: 略有小成
精华主题: 0
发帖数量: 128 个
工控威望: 443 点
下载积分: 747 分
在线时间: 120(小时)
注册时间: 2011-03-24
最后登录: 2021-05-13
查看liufuyao1234的 主题 / 回贴
4楼  发表于: 2015-06-24 21:20
引用
引用第3楼892777011于2015-06-24 20:14发表的  :
试试在这里加一个条件,当接收的数据大于某个值并且  LoopCheck = CInt(&H7D))时再退出,例如  Loop Until (LoopCheck = CInt(&H7D) and i >10 )

是同下位机通讯,智能仪器,如果加个条件的话I>10 或其他的数的话,当出现7D的话还是会出错的。因为第二条应答指令的结束符和第一条出现7D是在同一个位置的。大于这个位置的话 第二条指令就读不到了 会不会。
liufuyao1234
级别: 略有小成
精华主题: 0
发帖数量: 128 个
工控威望: 443 点
下载积分: 747 分
在线时间: 120(小时)
注册时间: 2011-03-24
最后登录: 2021-05-13
查看liufuyao1234的 主题 / 回贴
5楼  发表于: 2015-06-24 21:26
我想要用有效字节数来判断  7B 00 0D 0C F0 00 00 2C 7D AA AA 06 7D  就是第二和第三个字节, 即00 0D,当第三个字节值= i 时就结束循环 认为指令读取完成,这个程序应该怎么写。