'通讯初始化   
With Me.MSComm1
    .CommPort = 1           '端口号com1
    .Settings = 4800,n,8,1  '波特,有无奇偶校验,几位数据,几个停止位。
    .InputLen = 0           '当输入占用时,告诉控件读入整个缓冲区。
    .InputMode = 1          '数据通过 Input 属性以二进制形式取回(数据中有嵌入控制字符、Nulls 等等)
    .RThreshold = 1         '接收缓冲区收到每一个字符都会使 MSComm 控件产生 OnComm 事件
    .SThreshold = 1         'OnComm 事件产生之前在传输缓冲区中的最小字符数
    .PortOpen = True        '打开端口。
End With
Sub Write_Port(s_port As Integer, addr As Integer, code0 As Integer, code1 As Integer)    Dim buf(0 To 3) As Byte
    Dim Outbuffer(1 To 10) As Variant
    Dim Code1Previous As Integer                    '传递两字节动作字的第二字节
    Dim AddrPrevious As Integer                     '传递两字节动作对象地址
        buf(0) = addr
        buf(1) = code0
        If code0 <> &H90 And code0 <> &H9C Then
            '先停
            buf(2) = CByte(Code1Previous)
            buf(3) = CByte((CInt(AddrPrevious) + CInt(&H90) + CInt(Code1Previous)) And &HFF) '37--&h25,293--&h125
            Outbuffer(1) = buf
            Select Case s_port
                Case 1, 2
                    Me.MSComm1.Output = Outbuffer(1)
            End Select
            '后动作
            buf(2) = CByte((CInt(addr) + CInt(code0)) And &HFF)
            buf(3) = 0
            Outbuffer(s_port) = buf            Select Case s_port
                Case 1, 2
                    Me.MSComm1.Output = Outbuffer(1)
            End Select
        Else
            If code0 = 154 Then             '&H9A
                Exit Sub
            End If
            buf(2) = CByte(code1)
            buf(3) = CByte((CInt(addr) + CInt(code0) + CInt(code1)) And &HFF) '37--&h25,293--&h125
            Outbuffer(s_port) = buf
            Select Case s_port
                Case 1, 2
                    Me.MSComm1.Output = Outbuffer(1)
            End Select
        End If
        AddrPrevious = addr
        Code1Previous = code0
End Sub

解决方案 »

  1.   

    minajo21(大眼睛):高,高手
    新年好啊:minajo21(大眼睛)
    噢,对了,还有楼主,新年好,顺便也多多关照一下啊。。
       
      

  2.   

    首先在公共模块中定义和ONCOMM有关的参数: 
    Global Const MSCOMM_EV_RECEIVE = 2‘收到 Rthreshold 个字 
    符。该事件将持续产生直到用 Input 属性从接收缓冲区中删除数据 
    。 
    Global Const MSCOMM_ER_RXOVER = 1008‘接受缓冲区溢出,接 
    收缓冲区没有空间。 
    Global Const MSCOMM_ER_TXFULL = 1010 ‘传输缓冲区已满。 
    传输字符时传输缓冲区已满。 
    在启动过程中对串口和输入输出缓冲区初始化: 
    Sub Form_Load () 
    comm1.Settings = "1200,n,8,1" 设定波特率1200bps,无校验,8 
    位数据位,1位停止位 
    comm1.CommPort = 1 串口1 
    comm1.InputLen = 1 一次从输入缓冲区中读取一个字符 
    comm1.InBufferSize = 512 定义输入缓冲区为512字节(bytes) 
    comm1.InBufferCount = 0 清空输入缓冲区 
    comm1.OutBufferCount = 0 清空输出缓冲区 
    comm1.PortOpen = True 启动串口 
    End Sub 
    下面是发送数传命令的子过程,启动该过程由一个定时器控制: 
    Sub sample_data () 
    comm1.RTSEnable = True 将Modem的PTT置高,同时打开对讲机 
    Call time_delay 适当延时 
    comm1.Output = "*TRNS" + Chr$(13) 发送命令 
    Do 
    该循环用来检测命令是否全部发送完毕 
    Loop Until comm1.OutBufferCount = 0 
    Call time_delay 
    适当延时 
    comm1.RTSEnable = False 将Modem的PTT置低,将对讲机改为接 
    受状态 
    comm1.InBufferCount = 0 清空接收缓冲区 
    comm1.Rthreshold = 1 设定Rthreshold = 1,等待出发OnComm事 
    件 
    End Sub 
    在OnComm编写接收和处理代码: 
    Sub Comm1_OnComm () 
    Select Case comm1.CommEvent 
    Case MSCOMM_ER_RXOVER 接收缓冲区溢出,可插入相应的代码 
    Case MSCOMM_ER_TXFULL 传输缓冲区已满,可插入处理代码 
    Case MSCOMM_ER_RECEIVE 收到1个字符,可进入以下处理过程 
    comm1.Rthreshold = 0 不再响应OnComm事件,转入查寻方式接收 
    ii = 0 
    iii = 0: sinn = Chr$(42): sinn1 = Chr$(42)初始化变量 
    Do 
    duration = Timer + .2 设定超时退出的时间值 
    iii = iii + 1 
    sinn1 = sinn 
    Do 该循环判断输入缓冲区是否有数据或是否超时 
    'dummy% = DoEvents() 
    Loop Until comm1.InBufferCount >= 1 Or Timer >= duration 
    If Timer >= duration Then 
    iii = iii - 1 
    overtime = True 确定超时退出,并非正常退出 
    Exit Do 
    End If 
    sinn = comm1.Input 正常退出,取值付给sinn 
    If header_er = 0 Then 
    GoTo test_header 
    End If 
    If Asc(sinn) > 175 Or Asc(sinn) < 160 Then 判断包头是否 
    正确 
    iii = 0 
    GoTo station_number_er 包头不正确,丢掉该数据 
    End If 
    test_header: 
    header_er = 0 包头正确,接受到包头,header_er=0 
    ssin(iii) = sinn 'put date into string dimantion 
    station_number = Asc(ssin(1)) 
    package_number = Asc(ssin(2)) 
    sentence_number = Asc(ssin(3)) 
    last_character = Asc(ssin(iii)) 
    station_number_er: Loop Until sinn1 = Chr$(10) and 
    sinn = Chr$(13) 当收到正确的包尾0A,0D后退出 
    If overtime = True Then 如果超时非正常退出 
    overtime = False 
    comm1.Rthreshold = 1 重新启动OnComm事件,等待接收下一包 
    timer6_wait.Enabled = True 
    GoTo endsub 
    End If 
    以下是接收数据正确以后的数据处理程序,包括解码和计算。 
    If package_number = 1 Then 如果接收数据正确,而且是最后一 
    包 
    timer2_sample.Enabled = True 启动控制数传命令定时器 
    comm1.RTSEnable = True 置PTT为高 
    comm1.OutBufferCount = 0 清空输出缓冲区 
    Call time_delay 
    适当延时 
    comm1.Output = "*MACK" + Chr$(13)发送清内存命令 
    Do 
    检测是否发送完毕 
    Loop Until comm1.OutBufferCount = 0 
    Call time_delay 适当延时 
    comm1.RTSEnable = False 置PTT为低 
    End If 
    If package_number > 1 Then 如果不是最后一包 
    comm1.Rthreshold = 1 
    启动OnComm准备接收下一包 
    timer6_wait.Enabled = True 
    End If 
    endsub: header_er = 1: comm1.InBufferCount = 0 
    'empty inbuffer protect from bed data on the inbuffer 
    End Select 
    End Sub