⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 communication.bas

📁 基于RS-232的
💻 BAS
📖 第 1 页 / 共 3 页
字号:
Attribute VB_Name = "communication"
Option Explicit
'命令种类
Public Const NO_CMD As Byte = 0
Public Const UP_UI As Byte = &H11&
Public Const DOWN_IO As Byte = &H12&
Public Const DOWN_OCTIME As Byte = &H13&
Public Const DOWN_STDTIME As Byte = &H14&
Public Const UP_HISRECORD As Byte = &H15&
Public Const UP_TIME As Byte = &H16&
Public Const DOWN_CANBITRATE As Byte = &H17& '下传CAN总线波特率
'目标地址
Private Const T_ADDR1 As Byte = &H1&  '1号站点
Private Const T_ADDR2 As Byte = &H2&
Private Const T_ADDR3 As Byte = &H3&
Private Const T_ADDR4 As Byte = &H4&
Private Const T_ADDR5 As Byte = &H5&
Private Const T_ADDR6 As Byte = &H6&
Private Const T_ADDR7 As Byte = &H7&

Private Const PC_ADDR1 As Byte = &H8& 'PC机A
Private Const PC_ADDR2 As Byte = &H9& 'PC机B
Private Const CAN_ADDR As Byte = &HFE&  'can总线网络地址
'目标地址数组
Public COMM_MachineADDR(50) As Byte
'设置CAN总线的波特率
'10K,20K,40K,50K,80K,100K,125K,200k 对应0-7
'Public COMM_BITRATE As Variant
Public COMM_TerminateSendByForce As Boolean '强行中断传输标志,用于传送历史数据时
'包头
Private Const PKStart As Byte = &H7E&
Private Const PKEND As Byte = &H7E&
'下位机应答量
Private Const ACK_OK As Byte = &H1&
Private Const ACK_FAIL As Byte = &H2&
Private Const ACK_OVERTIME As Integer = 500 '超时时间1秒
'当前发送的命令
Private COMM_CurCmd As Byte
'当前发送包的索引号
'Public COMM_CurPacketIndex As Integer
'打包要传送的数据
'包头包尾判别标志
Private COMM_PKStartFlag As Boolean, COMM_PKEndFlag As Boolean
'收到包的个数
Private COMM_RcvDataNum As Integer, COMM_RcvData() As Byte, tmp_Rcvdata() As Byte
'Public Type SENDPACKETTYPE '发送数据时可连续打几个包
'  Dim data() As Byte
'  Dim isSendOverFlag As Boolean
'End Type
Private COMM_SendPacket() As Byte '当前发送的包
Private COMM_ReSendTimes As Integer '记录重传次数
Public COMM_isSendOverFlag As Boolean   '发送是否结束
Private COMM_isACKFlag As Boolean '检测是否有应答
Private overtime_timer As Timer '超时时钟
Private COMM_RcVMSCOMM As MSComm, COMM_SendMSCOMM As MSComm
Private Const HISPACKETNUM As Integer = 100 '历史包的总包数(待定)
Private COMM_CurHisPackIndex As Integer   '当前发送的历史包序列号
Private COMM_CurDestADDR As Byte  '当前访问下位机的地址
Private Const logfileName = "d:\testcom.log" '日志文件
'Private DataBaseObj As Database '用于访问数据及设置参数的数据库对象
'Private tmpdata() As Byte
Private RcvDataByteIndex As Integer '接收字节的索引号
Private WaitSendFlagNum As Double '等待发送标志计数
Private MyMachineAdd As Byte
'Private waitSendFlagTimer As Timer
Type COMM_CmdMessageType
 cmd As Byte
 station As Integer
 BeenUsedFlag As Boolean
End Type

Private COMM_CMDGroup() As COMM_CmdMessageType  '消息队列

Public Sub COMM_Init(ovtime As Timer, rcvComm As MSComm, sendComm As MSComm, MyAdd As Byte)  ', dbobj As Database)

If MyAdd = 1 Then
  MyMachineAdd = PC_ADDR1 'A本机地址
ElseIf MyAdd = 2 Then
  MyMachineAdd = PC_ADDR2 'B本机地址
End If

'包头包尾标志,接收包时对完整包进行判别
COMM_PKStartFlag = False
COMM_PKEndFlag = False
'接收属于包内数据的个数,即COMM_RCVDATA的个数
COMM_RcvDataNum = 0
COMM_ReSendTimes = 0 '重传次数尾0
COMM_isACKFlag = False '下位机是否应答标志
'超时时钟间隔
COMM_TerminateSendByForce = False '强行中断发送命令
Set overtime_timer = ovtime
overtime_timer.interval = ACK_OVERTIME
overtime_timer.Enabled = False
RcvDataByteIndex = 0 '接收字节索引号
'发送及接收通信串口
ReDim COMM_RcvData(400): ReDim tmp_Rcvdata(400)
Set COMM_RcVMSCOMM = rcvComm
Set COMM_SendMSCOMM = sendComm

'Set waitSendFlagTimer = checkSendflagtime
'Set DataBaseObj = dbobj
'初始化发送和接收串口设置
 Dim recordDb As Recordset
 On Error Resume Next
 Set recordDb = db.OpenRecordset("文件路径")
COMM_RcVMSCOMM.Settings = "19200,n,8,1"
 'COMM_RcVMSCOMM.Settings = "9600,n,8,1"
 COMM_RcVMSCOMM.commport = recordDb.Fields("通信端口").Value
 COMM_RcVMSCOMM.InBufferCount = 0                         ' 清接收缓冲区
 COMM_RcVMSCOMM.RThreshold = 1                            ' 接收数据长度
 COMM_RcVMSCOMM.OutBufferCount = 0
 COMM_RcVMSCOMM.InputMode = comInputModeBinary
 If COMM_RcVMSCOMM.PortOpen = False Then
 COMM_RcVMSCOMM.PortOpen = True
 End If
 Set COMM_SendMSCOMM = COMM_RcVMSCOMM
 'COMM_SendMSCOMM.Settings = "9600,n,8,1"
 'COMM_SendMSCOMM.commport = recordDB.Fields("通信端口").Value
 'COMM_SendMSCOMM.InBufferCount = 0                         ' 清接收缓冲区
 'COMM_SendMSCOMM.RThreshold = 1                            ' 接收数据长度
 'COMM_SendMSCOMM.OutBufferCount = 0
 'COMM_SendMSCOMM.InputMode = comInputModeBinary
 'If COMM_SendMSCOMM.PortOpen = False Then
 'COMM_SendMSCOMM.PortOpen = True
 'End If
 recordDb.Close
 Set recordDb = Nothing
COMM_isSendOverFlag = True

COMM_CurHisPackIndex = 0 '上传历史包号
'COMM_BITRATE = Array(0, 1, 2, 3, 4, 5, 6, 7)

'可访问各机地址
COMM_MachineADDR(0) = T_ADDR1
COMM_MachineADDR(1) = T_ADDR2
COMM_MachineADDR(2) = T_ADDR3
COMM_MachineADDR(3) = T_ADDR4
COMM_MachineADDR(4) = T_ADDR5
COMM_MachineADDR(5) = T_ADDR6
COMM_MachineADDR(6) = T_ADDR7
For I = 7 To StioNum
COMM_MachineADDR(I) = &H20& + I - 7 '多余站点地址从20开始
Next I
COMM_MachineADDR(48) = PC_ADDR1
COMM_MachineADDR(49) = PC_ADDR2
COMM_MachineADDR(50) = CAN_ADDR
'COMM_MachineADDR = Array(T_ADDR1, T_ADDR2, T_ADDR3, T_ADDR4, T_ADDR5, T_ADDR6, T_ADDR7, PC_ADDR1, PC_ADDR2, CAN_ADDR)
'If StioNum > 6 Then '增加下位机地址
'   Dim num As Integer
'   num = UBound(COMM_MachineADDR)
'   ReDim Preserve COMM_MachineADDR(num + StioNum - 6)
'   Dim I As Integer
'   For I = 1 To StioNum - 6
'     COMM_MachineADDR(num + I) = &H15& + I
'   Next I
'End If
Open logfileName For Binary As #1
'存储和提取数据模块的初始化
SED_Init 'DataBaseObj
'WaitSendFlagNum = 0 '等待发送标志计数值
ReDim COMM_CMDGroup(0) '0号单元不用

End Sub

Private Sub COMM_PacketData(cmd As Byte, ADDR As Byte, data() As Byte, senddata() As Byte)
 'cmd  为下传命令
 'addr 为下传的地址
 'data 为需下传的原始数据
 'senddata 为打包好的数据
 'Put #1, , "start_FUN_comm_packetdata: cmd: " & Hex(cmd) & vbCr & vbLf
Dim start As String, I, K As Integer
Dim ub, lb, num As Integer, t As Byte
Dim LenIn As Integer, LenOut As Integer, RealLen As Integer
ReDim senddata(100) As Byte

      senddata(0) = PKStart
      senddata(1) = ADDR
      
      senddata(2) = MyMachineAdd 'PC_ADDR1 '本机地址
      senddata(3) = 0
      senddata(4) = cmd
      COMM_CurCmd = cmd '当前包类型
    If (cmd = UP_UI Or cmd = UP_TIME) Then
      '上传
   
      LenIn = 5
       
    ElseIf cmd = UP_HISRECORD Then
      '上传历史数据+包号,共280记录
    
      
      t = (COMM_CurHisPackIndex And &HFF00&) / 256
      senddata(5) = t ' 取高位???
      t = (COMM_CurHisPackIndex And &HFF&)
      senddata(6) = t '取地位?????????
      LenIn = 7
     
     
    
    ElseIf (cmd = DOWN_IO Or cmd = DOWN_OCTIME Or cmd = DOWN_STDTIME Or cmd = DOWN_CANBITRATE) Then
      '下传
      
      ub = UBound(data)
      lb = LBound(data)
      num = ub - lb + 1
      
      K = 0
      For I = 5 To 4 + num Step 1
      senddata(I) = data(lb + K)
      K = K + 1
      Next
      LenIn = 5 + num
        
    End If
    
     COMM_Add7DFlag senddata, 1, LenIn, LenOut ' 1-4之间数据寻找7D7E做转换(除去包头)
      
     senddata(LenOut) = COMM_GenerateCRC(senddata, 1, LenOut - 1)
     COMM_Add7DFlag senddata, LenOut, LenOut + 1, RealLen
     senddata(RealLen) = PKEND
      
     
     ReDim Preserve senddata(RealLen)
     Put #1, , "FUN_comm_packetdata_down" & ConvertChar(senddata) & vbCr & vbLf


End Sub


Private Sub COMM_Add7DFlag(dataArray() As Byte, indexS As Integer, LenIn As Integer, LenOut As Integer)
'index表明从dataarray数组的第及位开始查找
Dim istart, iend As Integer, I, K As Integer
'istart = LBound(dataArray)
'iend = UBound(dataArray)
Dim dat() As Byte
ReDim dat(200) As Byte
'Put #1, , "start_FUN_comm_add7dflag" & vbCr & vbLf

For K = 0 To indexS - 1
dat(K) = dataArray(K)
Next K
Dim Pos As Integer
Pos = indexS
'If Pos < 0 Then Pos = 0

For K = indexS To LenIn - 1 Step 1 '排除包头和包尾
   
 If dataArray(K) = &H7E& Then
   dat(Pos) = &H7D&: dat(Pos + 1) = &H5E&
   Pos = Pos + 2
 ElseIf dataArray(K) = &H7D& Then
   dat(Pos) = &H7D&: dat(Pos + 1) = &H5D&
   Pos = Pos + 2
 ElseIf dataArray(K) = &HFF& Then
   dat(Pos) = &H7D&: dat(Pos + 1) = &H5F&
   Pos = Pos + 2
 Else
   dat(Pos) = dataArray(K)
   Pos = Pos + 1
 End If
Next K


For K = 0 To Pos - 1
dataArray(K) = dat(K)
Next K
LenOut = Pos
Erase dat
End Sub



Private Sub COMM_Add7DFlag_old(dataArray() As Byte, indexS As Integer, indexE As Integer)
'index表明从dataarray数组的第及位开始查找
Dim istart, iend As Integer, I, K As Integer
istart = LBound(dataArray)
iend = UBound(dataArray)

'Put #1, , "start_FUN_comm_add7dflag" & vbCr & vbLf

For K = indexS To indexE Step 1  '排除包头和包尾
 If dataArray(indexS) = &H7E& Then
   iend = iend + 1
   ReDim Preserve dataArray(istart To iend) As Byte
   For I = iend To indexS + 2 Step -1
     dataArray(I) = dataArray(I - 1)
   Next I
     dataArray(indexS) = &H7D&
     dataArray(indexS + 1) = &H5E&
     indexS = indexS + 2
     
 ElseIf dataArray(indexS) = &H7D& Then
   iend = iend + 1
   ReDim Preserve dataArray(istart To iend) As Byte
   For I = iend To indexS + 2 Step -1
     dataArray(I) = dataArray(I - 1)
   Next I
     dataArray(indexS) = &H7D&
     dataArray(indexS + 1) = &H5D&
     indexS = indexS + 2
 'OXFF---7d5F
 ElseIf dataArray(indexS) = &HFF& Then
   iend = iend + 1
   ReDim Preserve dataArray(istart To iend) As Byte
   For I = iend To indexS + 2 Step -1
     dataArray(I) = dataArray(I - 1)
   Next I
     dataArray(indexS) = &H7D&
     dataArray(indexS + 1) = &H5F&
     indexS = indexS + 2
     
     
 Else
     indexS = indexS + 1
 End If
 
 Next K
End Sub
Private Sub COMM_Del7DFlag(dataArray() As Byte, indexS As Integer, indexE As Integer)
'index表明从dataarray数组的第及位开始查找
Dim istart, iend As Integer, I, K, num As Integer
istart = LBound(dataArray)
iend = RcvDataByteIndex  'UBound(dataArray)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -