PC连接一个多画面合成器,波特率:9600,1位起始位,8位数据,1位校验位,1位停止位。
     发往下位机的命令由两字节构成:55H(地址码)--命令码,第一字节为地址码(十六进制数55H);第二字节为命令码,两字节间时延不要超过50毫秒(这个我就不太明白了)。命令码依次为31H,32H,33H,34H,35H,36H,37H,38H,39H,3AH,3BH,3CH,3DH。
     我现在刚刚开始学习,还不太清楚,请问我应该如何编写。谢谢。     分不多了,挤出一半给大家分。

解决方案 »

  1.   

             比如这样写可以吗?(千万别笑我)         MSComm1.CommPort = 1       
              MSComm1.Settings = "9600,n,8,1"       
              MSComm1.InputLen = 0       
              MSComm1.PortOpen = True           dim  a()  as  byte   
        
             redim   a(2)   
        
              a(0)=&H55   
              a(1)=&H31   
       
               mscomm.output   =   a   
      

  2.   

    估计就是这样Option ExplicitPrivate Sub Command1_Click()
        Dim a(0 To 1) As Byte
        a(0) = &H55
        a(1) = &H31
        MSComm1.Output = a
    End SubPrivate Sub Form_Load()
        MSComm1.CommPort = 1       '"选用com1串行口
        
        MSComm1.Settings = "115200,n,8,1"       '"波特率9600,无奇偶校验位,8位数据位1位停止位
        
        MSComm1.InputLen = 1       '"读取input接收缓冲区全部字节
        
        MSComm1.InBufferSize = 1024       '"设置接收缓冲区的字节长度
        
        MSComm1.InBufferCount = 0       '"清除发送缓冲区数据
        
        MSComm1.OutBufferCount = 0       '"清除接收缓冲区数据
        
        MSComm1.InputMode = 1       '"输入模式为binary
        
        MSComm1.RThreshold = 1       '"控件收到数据时将触发OnComm事件
        
        MSComm1.Handshaking = 2
        MSComm1.PortOpen = True
    End SubPrivate Sub MSComm1_OnComm()
        Dim a() As Byte
        a = MSComm1.Input
        Dim i As Long
        Debug.Print UBound(a)
        'For i = 0 To UBound(a)
        '    Debug.Print Hex$(a(i)) & " ";
        'Next i
    End Sub
      

  3.   

         感谢jennyvenus!
         我去试试... 
      

  4.   

    依照工控RTU标准,超过50毫秒,将被认为指令结束。50毫秒后面的数据将被认为是新的指令。
    但依照ASC2标准,就没有这个限制,ASC2标准当受到完整起始字符时,才算一个新指令的开始。
      

  5.   

    不过放心,MSComm控件的发送缓存可保证良好的通讯速度。
      

  6.   

    把一切发送设置好后。注意波特率,楼上的115200和9600不分,不知何故。然后:MSComm1.Output=cha(&H55) & char(&H31) & cha(....) &  ...........'我就不罗嗦了。之后不断判断接收区的长度,如果长度超过画面合成器应该返回的数据量后,就去读接收缓冲区。3楼的思路是正确的,只是指令队列的生成方法好像不好,必须用string类型,虽然Byte是相当的,但VB的串口发送缓冲区是16位一个字符的。并且不会做byte相关的自动处理。
      

  7.   

    说白了MSComm1.Output是VB字符串,VB字符串是16位一个字符。不是8位
      

  8.   

    Private Sub Form_Load()
        '设置打开端口
        If OpenPort(3) = False Then
            MsgBox "串口打开失败!"
        End If
    End SubPrivate Sub Command1_Click()
        Dim sBuf(2) As Byte
        sBuf(0) = &H55
        sBuf(1) = &H31
        sBuf(2) = &HFF
        If SendByte(sBuf) = False Then
            
        End If
    End Sub'收到数据产生MSComm事件
    Private Sub MSComm1_OnComm()
        Dim i As Integer
        Dim rBuf() As Byte
        rBuf = MSComm1.Input
        For i = 0 To UBound(rBuf)
            Debug.Print rBuf(i)
        Next i
    End Sub'串口初始化
    Private Function OpenPort(PortNum As Integer) As Boolean
        On Error GoTo ErrExit       '出错转移到ErrExit处理
        With Me.MSComm1
            .CommPort = PortNum     '端口号
            .Settings = "9600,n,8,1"    '波特率=9600bps;n(无奇偶校验)e(偶校验)o(奇校验);8位数据位;1位停止位
            .InputMode = 1          '采用二进制数据传输
            .NullDiscard = False    'NULL字符从端口传送到接受缓冲区
            .DTREnable = False      'DTR线无效
            .EOFEnable = False      '不寻找EOF符
            .RTSEnable = False      'RTS线无效
            .InBufferCount = 0      '清空接受缓冲区
            .OutBufferCount = 0     '清空传输缓冲区
            .SThreshold = 0         '不产生MSComm事件
            .RThreshold = 1         '产生MSComm事件
            .InputLen = 0           '当输入占用时,告诉控件读入整个缓冲区。
            .InBufferSize = 256     '接收缓冲区 默认为1024个字节
            .OutBufferSize = 256    '发送缓冲区 默认为512个字节
            .PortOpen = True        '打开端口
        End With
        OpenPort = True             '标明串口打开
        Exit Function               '函数结束
    ErrExit:                        '错误处理
        OpenPort = False            '标明串口打开失败
    End Function                    '函数结束'以二进制发送byte数组
    Private Function SendByte(Buf() As Byte) As Boolean
        On Error GoTo ErrExit       '出错转移到ErrExit处理
        With MSComm1
            .OutBufferCount = 0     '清空接收缓冲区
            .Output = Buf           '发送数据
        End With
        SendByte = True             '标明数据发送成功
        Exit Function               '函数结束
    ErrExit:                        '错误处理
        SendByte = False            '标明串口发送失败
    End Function
      

  9.   

    LZ:你的说明未说明校验是奇校验?偶校验?无校验?,以下代码是按无奇偶校验。你说无反应,我估计是未设置MSComm1.RThreshold=1Option Explicit
        Dim sjByte(1) As Byte
        Dim BytReceived() As Byte
        Dim strData As String
        Dim openFlag As BooleanPrivate Sub Command1_Click()
        If openFlag Then
            Timer1.Enabled = False '停止论询
             Command1.Caption = "Send"
        Else
            Timer1.Enabled = True '执行论询
             Command1.Caption = "Stop"
        End If
        openFlag = Not openFlag
    End SubPrivate Sub Form_Load()
        MSComm1.CommPort = 1
        MSComm1.Settings = "9600,N,8,1" 'N是无奇偶校验
        MSComm1.InputMode = comInputModeBinary '二进制方式接收
        MSComm1.RThreshold = 1 '产生OnComm事件
        MSComm1.PortOpen = True
        Timer1.Interval = 50
        Timer1.Enabled = False
    End SubPrivate Sub MSComm1_OnComm() '接收数据
        Dim strBuff As String
        Text1 = ""
        Select Case MSComm1.CommEvent
            Case 2
                MSComm1.InputLen = 0
                strBuff = MSComm1.Input
                BytReceived() = strBuff
                jieshou
                Text1 = strData
        End Select
    End SubPrivate Sub Timer1_Timer() '论询命令生成
        Static sum As Integer
        sjByte(0) = &H55
        sum = sum + 1
        sjByte(1) = 48 + sum
        MSComm1.Output = sjByte
        If sum >= 13 Then
            sum = sum - &HD
        End If
    End Sub
    Public Sub jieshou() '接收处理为16进制显示
        Dim i As Integer
        For i = 0 To UBound(BytReceived)
            If Len(Hex(BytReceived(i))) = 1 Then
                strData = strData & "0" & Hex(BytReceived(i))
            Else
                strData = strData & Hex(BytReceived(i))
            End If
        Next
    End Sub
      

  10.   

    LZ:
    请确定校验是何种校验,以便正确设置MSCOMM控件的Settings,不然无法正常通信,达不到你的目的.
    以下引自MSDN:
    Settings 属性
    设置并返回波特率、奇偶校验、数据位、停止位参数。
    语法
    object.Settings[ = value]
    Settings 属性语法包括下列部分:
    部分 描述 
    object 对象表达式,其值是“应用于”列表中的对象。 
    value 字符串表达式,说明通讯端口的设置值,如下所述。 
    说明
    当端口打开时,如果 value 非法,则 MSComm 控件产生错误 380(非法属性值)。
    Value 由四个设置值组成,有如下的格式:
    "BBBB,P,D,S"
    BBBB 为波特率,P 为奇偶校验,D 为数据位数,S 为停止位数。value 的缺省值是:
    "9600,N,8,1"
    下表列出合法的波特率:
    设置值
    110 
    300 
    600 
    1200 
    2400 
    9600(缺省) 
    下表说明合法的奇偶校验值。
    设置值 描述 
    E 偶数 (Even) 
    M 标记 (Mark) 
    N  缺省 (Default) 
    None   
    O 奇数 (Odd) 
    S 空格 (Space) 
    下表列出合法的数据位值。
    设置值




    8 (缺省) 
    下表列出合法的停止位值。
    设置值   
    1  (缺省) 
    1.5   
    2   
      

  11.   

    LZ:从你说明看属轮询方式,需注意下位机是单工还是双工.
    单工的话下位机收和发需分开进行,也就是说,PC机侧发送一个命令后需等待下位机返回数据后再发新的轮询命令,不然下位机会出错.
      

  12.   

    我现在用comdebug调试,连接单片机测试发送数据正常了。我现在只想分别实现其中的一种命令,例如55 31、55 32,或55 3D等等
    可是我用程序运行就没有反应,我用的程序如下,大家帮我看看是哪里的问题,谢谢Private Sub Command1_Click()
    Text1.Text = "此时输出多画面。      '其中的一个命令
        
        Dim a(0 To 1) As Byte        a(0) = &H55
            a(1) = &H3D
        
        MSComm1.Output = aEnd SubPrivate Sub Form_Load()    MSComm1.CommPort = 1       '"选用com1串行口
         MSComm1.Settings = "9600,O,8,1"       '"波特率9600,奇校验,8位数据位,1位停止位
         MSComm1.InputLen = 1       '"读取input接收缓冲区全部字节
         MSComm1.InBufferSize = 1024      '"设置接收缓冲区的字节长度
         MSComm1.InBufferCount = 0       '"清除发送缓冲区数据
         MSComm1.OutBufferCount = 0       '"清除接收缓冲区数据
         MSComm1.InputMode = 1       '"输入模式为binary
        MSComm1.RThreshold = 1       '"控件收到数据时将触发OnComm事件
         MSComm1.Handshaking = 2
        MSComm1.PortOpen = TrueEnd SubPrivate Sub MSComm1_OnComm()
     
        Dim a() As Byte        a = MSComm1.Input
            Dim i As Long
            Debug.Print UBound(a)End Sub
      

  13.   

    LZ:建议暂时不使用硬件握手设置MSComm1.Handshaking=2.此外OnComm事件带代码你处理过于草率.Option ExplicitPrivate Sub Command1_Click()
        Text1.Text = "此时输出多画面。      '其中的一个命令 "
        Dim a(0 To 1) As Byte
        a(0) = &H55
        a(1) = &H3D
        MSComm1.Output = a
    End SubPrivate Sub Form_Load()
        MSComm1.CommPort = 1       '"选用com1串行口
        MSComm1.Settings = "9600,O,8,1"       '"波特率9600,奇校验,8位数据位,1位停止位
        MSComm1.InputLen = 1       '"读取input接收缓冲区全部字节
        MSComm1.InBufferSize = 1024      '"设置接收缓冲区的字节长度
        MSComm1.InBufferCount = 0       '"清除发送缓冲区数据
        MSComm1.OutBufferCount = 0       '"清除接收缓冲区数据
        MSComm1.InputMode = 1       '"输入模式为binary
        MSComm1.RThreshold = 1       '"控件收到数据时将触发OnComm事件
        'MSComm1.Handshaking = 2
        MSComm1.PortOpen = True
    End SubPrivate Sub MsComm1_OnComm()
        Dim a() As Byte
        Dim i As Long
        Select Case MSComm1.CommEvent
            Case comEvReceive
                a = MSComm1.Input
                Print UBound(a)
        End Select
    End Sub以下引自MSDN:
    OnComm 事件示例
    下例说明如何处理通讯错误和事件。可以在相关的 Case 语句之后插入代码来处理特定的错误或事件。Private Sub MSComm_OnComm ()
        Select Case MSComm1.CommEvent
            ' Handle each event or error by placing 
            ' code below each case statement
            ' 错误
             Case comEventBreak   ' 收到 Break。
             Case comEventCDTO   ' CD (RLSD) 超时。
             Case comEventCTSTO   ' CTS Timeout。
             Case comEventDSRTO   ' DSR Timeout。
             Case comEventFrame   ' Framing Error
            Case comEventOverrun   '数据丢失。
             Case comEventRxOver'接收缓冲区溢出。
             Case comEventRxParity' Parity 错误。
             Case comEventTxFull   '传输缓冲区已满。
             Case comEventDCB   '获取 DCB] 时意外错误
             ' 事件
             Case comEvCD   ' CD 线状态变化。
             Case comEvCTS   ' CTS 线状态变化。
             Case comEvDSR   ' DSR 线状态变化。
             Case comEvRing   ' Ring Indicator 变化。
             Case comEvReceive   ' 收到 RThreshold # of chars.
            Case comEvSend   ' 传输缓冲区有 Sthreshold 个字符                     '
            Case comEvEof   ' 输入数据流中发现 EOF 字符
        End Select
    End Sub
      

  14.   

    MSComm1.CommPort = 1        
    MSComm1.Settings = "9600,n,8,1"        
    MSComm1.InputLen = 0        
    MSComm1.InputMode=0
    MSComm1.PortOpen = True   
    dim  a()  as  byte         
    dim I as integer
    redim   a(2)         
    a(0)=&H55 
    for I=1 to 13
        Sleep(1000)
        a(1)=&H30+i
        MSComm1.output=a
    next I    
        
               mscomm.output   =   a    
      

  15.   

          
         我终于调通了,通过这次试验我真是学到了不少东西。
          
          没想到有这么多朋友帮忙,真的很感谢大家,特别感谢:jennyvenus,ba_wang_mao, lqq7072000,zdingyun和ZW_LM!!!      接分吧。
      

  16.   

    #includ<stdio.h>
    puts("rinimama");
      

  17.   

    27楼和我的问题一样,我也试过了,可是还是不行!
    我只要传ASCI数据,可是串口传出的数据仍然看不到!