您现在所在的是:

串口通信

回帖:4个,阅读:1619 [上一页] [1] [下一页]
920
suly2001
文章数:6
年度积分:50
历史总积分:920
注册时间:2005/3/23
发站内信
发表于:2005/4/29 21:03:00
#0楼
有一个无线网络仪器,能够和若干个仪器组成分组网,每个仪器本身也有IP地址,同时组成的网络里面也有网关地址什么的,当发送报文时仪器本身会在发出报文后自动发给包含刚才发出去的报文数据的网络ID,如果目的仪器收到发送方发过来的数据后就会给发送方一个确认信息,发送方根据这个包含网络ID的确认信息给发送方终端软件一个确认数据帧,
如发送的数据:
C0 32 0 0 1E 14 12 0 0 FF 11 18 7F FE 0 0 1 FE 0 0 2  31 32 33 0 0 C0 其中C0是帧头标志,第二个C0是结尾标志,32是命令字,0 0 是服务类型,1E是总长度,14 12 是用户自定义的报文ID,仪器会根据这个数生成一个随机的仪器网络ID, 0  0 是分片偏移,FF是生存期,11 是协议类型,18 7F 是前边十个Byte的校验和,Fe 0 0 1 是发送源IP,Fe 0 0 2 是目的IP,31 32 33 是要发送的数据 123,0  0 是发送时间,C0是帧尾
.
发送完数据后仪器会马上把自身生成的ID号信息传送过来,格式为:
 C0 61 6 14 12 0 0 4 0 C0     同样两个C0是帧头帧尾,61是命令字,14 12 就是刚才发出去数据的用户ID,0 0 表示时间,4  0 是仪器生成的网络ID.
 接收方收到发送方发出的数据后就会返回确认信息,发送方接收到这个确认信息后就给终端软件发一串表示对方已经正常接收的确认数据:C0 62 2 4 0  C0          两个C0同样是帧头帧尾,62是命令字,2 是数据长度, 4 0是仪器生成的网络ID      
 如果对方多长时间没有给发送方回执的话,发送方会自动给终端软件一个确认失败,对方没有受到的信息
    C0 63 2 4 0 C0           两个C0同样是帧头帧尾,63是命令字,2 是数据长度, 4 0是仪器生成的网络ID

mscomm的属性如下:
 settings=9600,n,8,1
 handshaking=comRTS
 rthhold=1
 inputlen=0
 
我采取在On_Comm中启动计时器接收的方法,在一个一个单个发送数据的时候没有什么问题,返回确认信息的正确率很高,但是在间隔1秒钟自动发送的情况下就很糟糕,收到的返回确认信息要缺少好多,用串口调试助手接收没有问题,确认信息全能收到,排除了仪器本身的问题,我不知道这是为什么,在这里把源代码给出来,大家交流一下.我怀疑产生丢帧的原因是每次取数据的时候取得有问题,也怀疑是因为定时器的时间间隔有问题,但是具体什么原因我还是没有搞明白,不知道怎么解决才好,希望各位高手能指点一下.我得QQ号码:42294060,如果有什么想法大家可以交流一下(晚上9点后在线)  

源代码如下(发送事件从略,就是mscomm.output一下就好)


'每次接收接受到一个字符时候就产生一次ON_comm事件,在ON_comm事件中把定时接收打开,定时器的interval是200ms,但是在实际运行过程中却出现丢数据帧的情况,我所要的数据是C0 .....C0之间的数据.
Public Sub MSComm_OnComm()
   Select Case MSComm.CommEvent
       Case 2
        If RecFlag = False Then
          'MSComm.RTSEnable = False
          'MSComm.DTREnable = False
          TmrDealRec.Enabled = True  '打开定时器
       End If
   End Select
End Sub

Private Sub TmrDealRec_Timer()
  Dim midInbuffer() As Byte              '每次产生On_Comm事件时接收到的数据存入该数组中
  Dim midBound As Integer
  ReDim midInbuffer(0) As Byte          
  Dim ReadLoop As Integer
  Dim rec As String
  Dim B() As Byte                         '中间数组,把收到的数据存入到该数组中,该数组作为中转数组
  Dim timeout As Double                   ' 定义超时时间
  Dim MyArray() As Byte                   '把中转数组B()中的数据存入该数组
  timeout = 0.07                          '定义超时时间
  midBound = 0
 
  Dim i As Integer
  Dim j As Integer
  Start = Timer
 
  TmrDealRec.Enabled = False              '关闭定时器
  Do While Timer < Start + timeout
  If MSComm.InBufferCount > 0 Then
    B = MSComm.Input
  ReDim Preserve midInbuffer(midBound + UBound(B) - LBound(B) + 1)
  For iBoundLoop = LBound(B) + 1 To UBound(B) + 1 Step 1
    midInbuffer(midBound + iBoundLoop) = B(iBoundLoop - 1)
    rec = rec + Hex(midInbuffer(midBound + iBoundLoop)) + Chr(32)
  Next
     midBound = UBound(midInbuffer)
  End If
 DoEvents
 Loop
FrmRec.Text1.Text = FrmRec.Text1.Text + rec + vbNewLine      '把收到的数据放入text控件中,但是显示结果缺少若干数据帧

'从数组中选出整帧的数据'即C0 ......C0
   j = 1
   For i = 2 To UBound(midInbuffer)
   If midInbuffer(i) = 192 And midInbuffer(i - 1) <> 192 Then
     ReDim MyArray(i - j)
 
      For j = j To i
        MyArray(i - j) = midInbuffer(j)
      Next
        Call DealData1(MyArray)   '调用处理程序处理整帧的数据
      j = i + 1
   End If
  Next
'Else
'MsgBox " buquan'  "
 
'End If
' Erase midInbuffer

' MSComm.RThreshold = 1
'MSComm.DTREnable = True
recbuf = ""

'下面代码本来是想存储没有帧尾的数据的,但是好像不起什么作用
  Dim k As Integer
  Dim position As Integer
  Dim StartArray() As Byte
  Dim EndArray() As Byte
  If midInbuffer(LBound(midInbuffer)) <> &HC0 Then
     For k = LBound(midInbuffer) To UBound(midInbuffer)
       If midInbuffer(k) = &HC0 Then
          positon = k
         Exit For
        End If
     Next
 
     ReDim StartArray(0 To position)
     For k = LBound(midInbuffer) To position
        StartArray(k) = midInbuffer(k)
     Next
 
 ElseIf midInbuffer(UBound(midInbuffer)) <> &HC0 Then
    For k = UBound(midInbuffer) To 1 Step -1
      If midInbuffer(k) = &HC0 Then
          position = k
        Exit For
      End If
  Next
 
 ReDim EndArray(0 To UBound(midInbuffer) - position)
 For k = position To UBound(midInbuffer)
     EndArray(k - position) = midInbuffer(k)
 Debug.Print EndArray(k - position)
 Next

End If
End Sub


处理一帧一帧的数据
Private Sub DealData1(A() As Byte)
Dim strxuyao(1 To 300) As Byte         '存储接收到的所有数据
Dim fanhui As String
Dim ChuShiIP As String                 '定义初IP地址
Dim count As Integer                   '用于存放有几个需要替换的DBDC DBDD,总共替换了多少次
ReDim B(0 To UBound(A))
Dim RowCount As Integer                 '记录当前总共有已发出的数据
Dim DTENetID As String                  '记录用户生成的网络ID
Dim PruNetID As String                  '记录仪器本身生成的网络ID
Dim PruFanID As String                  '记录仪器本身确认信息的网络ID
For i = 0 To UBound(A)
  B(i) = A(UBound(A) - i)
Next
 
 If UBound(C) > 3 Then
 
   B(0) = &HC0 And B(1) = &H62 Then
            For i = 0 To UBound(B)
             
             Next
             DTENetID = Hex(Val(B(3))) & Hex(Val(B(4)))                 '记录用户生成的网络ID
             PruNetID = Val(B(7)) & Val(B(8))                           '记录仪器自身生成的网络ID
             For RowCount = 1 To MSFlexGrid2.Rows - 1
                 If MSFlexGrid2.TextMatrix(RowCount, 1) = DTENetID Then MSFlexGrid2.TextMatrix(RowCount, 9) = PruNetID
             Next

  ElseIf B(0) = &HC0 And B(1) = &H62 Then
             PruFanID = Val(C(3)) & Val(C(4))
              For RowCount = 1 To MSFlexGrid2.Rows - 1
                 If MSFlexGrid2.TextMatrix(RowCount, 9) = PruFanID Then
                    MSFlexGrid2.TextMatrix(RowCount, 2) = "成功"
                    MSFlexGrid2.TextMatrix(RowCount, 7) = Time
                 End If
             Next
 ElseIf B(0) = &HC0 And B(1) = &H63 Then
            PruFanID = Val(B(3)) & Val(B(4))
              For RowCount = 1 To MSFlexGrid2.Rows - 1
                 If MSFlexGrid2.TextMatrix(RowCount, 9) = PruFanID Then
                    MSFlexGrid2.TextMatrix(RowCount, 2) = "失败"
                    MSFlexGrid2.TextMatrix(RowCount, 7) = Time
               End If
              Next


End If
End If
End Sub
29673
思南 管理员
文章数:14047
年度积分:62
历史总积分:29673
注册时间:2001/3/12
发站内信
发表于:2005/4/30 8:06:00
#1楼
请有相关经验的网友前来解答。
图
如您对论坛有好的建议或创想,请加大版主微信号:gkong2015
大版主推荐【工控百家谈】微信公众号,业界大拿原创内容分享
9012
吴辉
文章数:2351
年度积分:50
历史总积分:9012
注册时间:2002/1/15
发站内信
发表于:2005/5/3 9:49:00
#2楼
我一看文字就头大!
你把发送方接收方用图形比画一下
例如:
                     pc----(data1)---->plc  (data1:xxxxv)
正确响应:      pc<--(data2)------plc  (data2:xxxxv)
确认信息:      pc----(data3)---->plc  (data3-xxxxv)
错误响应:      pc<----(data2)----plc  (data-xxxxv)
9012
吴辉
文章数:2351
年度积分:50
历史总积分:9012
注册时间:2002/1/15
发站内信
发表于:2005/5/3 9:58:00
#3楼
不在timer处理
放到接收事件里去
增加判断标志,改变接收事件触发字节。
增加一个timer,用做watchdog

920
suly2001
文章数:6
年度积分:50
历史总积分:920
注册时间:2005/3/23
发站内信
发表于:2005/5/9 22:34:00
#4楼
谢谢各位的回复,我改变了接收方式,基本上能正常接收发送了。

关于我们 | 联系我们 | 广告服务 | 本站动态 | 友情链接 | 法律声明 | 非法和不良信息举报

工控网客服热线:0755-86369299
版权所有 工控网 Copyright©2024 Gkong.com, All Rights Reserved

62.4004