我才完成了一个PC与单片机通讯的项目,写了几段代码,请高手指点一下这种方式是否可行?是否存在弊端?有没有更好的方式或者见意?
Option Explicit    '定义全局变量 
Dim CloseCount As Integer 
Dim commcount As Integer Private Sub Form_Load() 
CloseCount = 0                                                  '停止通讯计数器 
commcount = 0                                                  '通讯连接计数器 
Label3.Caption = ""        '串口测试显示为空 
MSComm1.InBufferSize = 40            '初始化串口 
MSComm1.InputMode = 0                '接收文本型数据 
Timer1.Interval = 500                '设置定时器事件间隔时间为500毫秒 
Timer1.Enabled = False              '启动定时器 
Timer2.Interval = 500 
Timer2.Enabled = False 
Timer10.Interval = 500 
Timer10.Enabled = False 
MSComm1.InputLen = 0 
End Sub Private Sub CommTestButton_Click() 
  On Error GoTo ErrorMessage 
If MSComm1.PortOpen = False Then 
  MSComm1.PortOpen = True 
  MsgBox Chr(13) + "串口打开成功!", vbOKOnly 
  CloseCount = 0                                      '停止通讯计数清零 
  commcount = 0                                        '串口连接计数清零 
End If 
Exit Sub 
ErrorMessage: 
  MsgBox Chr(13) + "串口打开失败!" + Chr(10) + "错误代码:" & Err.Number & Chr(10) + "原因:" & Err.Description, vbQuestion 
End Sub Private Sub StartCommButton_Click() 
If MSComm1.PortOpen = False Then    '触发器,通讯窗口无法输入代码 
  MSComm1.PortOpen = True 
End If 
  Timer1.Enabled = True 
  Timer2.Enabled = True 
  MSComm1.OutBufferCount = 0          '清空发送缓冲区 
End Sub 
'============================================================================ 
Private Sub Timer1_Timer() '定时自动从输入缓冲区读取字符 
  TextReceive.Text = MSComm1.Input 
If TextSend.Text = "h" And TextReceive.Text = "" Then    '当上位机发送通讯代码h到下位机 
  commcount = commcount + 1            '下位机没有返回数据时计数10秒断开连接并显示通讯故障 
Else 
  commcount = commcount + 0 
End If 
If commcount = 10 Then 
  Label3.ForeColor = &HFF& 
  Label3.Caption = "与单片机通讯建立失败,请检查通讯设置!" 
  Timer2.Enabled = False 
  commcount = 0                                                  '清空通讯连接测试计数器 
End If If TextReceive.Text = "h1" Then      '接收到单片机h1代码表示通讯已建立 
  TextSend.Text = "" 
  Label3.ForeColor = &HFF00& 
  Label3.Caption = "与单片机通讯已成功建立" 
  Timer2.Enabled = False 
End If If TextReceive.Text = "" And TextSend.Text = "z" Then 
  CloseCount = CloseCount + 1    '上位机发送z代码至下位机,当未收到下位机上传的数据后4秒关闭通讯 
If CloseCount = 4 Then 
  TextSend.Text = "" 
  TextReceive.Text = "" 
  Timer1.Enabled = False 
  Timer10.Enabled = False 
  MSComm1.InBufferCount = 0 
  MSComm1.OutBufferCount = 0 
  MSComm1.PortOpen = False 
End If 
End If 
End Sub Private Sub Timer2_Timer()              '与单片机通讯触发器 
  MSComm1.Output = TextSend.Text 
  TextSend.Text = "h" 
  MSComm1.OutBufferCount = 0 
End Sub 
                                      
Private Sub Timer10_Timer()            '结束测试按钮控制触发器 
  MSComm1.Output = TextSend.Text 
  TextSend.Text = "z" 
  MSComm1.OutBufferCount = 0 
End Sub Private Sub StopTestButton_Click() 
  Timer2.Enabled = False                              '当点按停止运行按钮后发送命令触发器 
  Timer1.Enabled = True 
  Timer10.Enabled = True 
  MSComm1.OutBufferCount = 0          '清空发送缓冲区 
End Sub h , h1 ,z 代码都是单片机与PC自定义的通讯代码

解决方案 »

  1.   

    LZ:建议你接收用MSComm控件的OnComm事件来实现。MSComm控件的初始化设置尽可能使用控件的缺省设置:
        
        MSComm1.InBufferSize = 1024            '初始化串口
        MSComm1.OutBufferSize = 512
        MSComm1.RThreshold = 1
        MSComm1.InputMode = 0                '接收文本型数据
      

  2.   

    尽量不要使用MSCOMM控键,用CreateFile,WriteFile,ReadFile这几个API函数。
      

  3.   

    如果用oncomm事件的话,我担心可能无法实现,因为oncomm事件是如果缓存区有代码就上传,我还有个实时计数的模块,一共4个串口。如果使用oncomm事件的话应该如何去考虑,请教高手指点
      

  4.   

    4个串口,如果同时需通信用4个MSCOMM控件。
      

  5.   

    Private Sub MSComm1_OnComm()
        Select Case MSComm1.CommEvent
            Case 2
                txtReceive = MSComm1.Input
                TextReceive = txtReceive
                '写数据处理代码
        End Select
    End Sub
      

  6.   

    谢谢大家,现在正在用onComm测试中,测试完后给大家给分!
      

  7.   

    测试过后代码如下:    oncomm事件接收出现问题,当s发送后接收到s1,当h发送后接收到h1,但是这时候串口就需要的计数,所以一直要接收串口中的代码为n1,但n1接收后再发送代码z至单片机时,单片机就无法接收代码,串口调试工作也试了,
    窗体中看起来z一直在发送,但是实际没有传到串口中去,这是怎么回事?请高手指点,如有高手能解决,此贴再加50分,谢谢!
    Private Sub CommTest_Click()
       On Error GoTo ErrorMessage
    If MSComm1.PortOpen = False Then
       MSComm1.PortOpen = True
       MsgBox Chr(13) + "串口打开成功!", vbOKOnly
    End If
    Exit Sub
    ErrorMessage:
       MsgBox Chr(13) + "串口打开失败!" + Chr(10) + "错误代码:" & Err.Number & Chr(10) + "原因:" & Err.Description, vbQuestion
    End SubPrivate Sub Exit_Click()
    Timer1.Enabled = False
    If MSComm1.PortOpen = True Then
       MSComm1.PortOpen = False
    End If
    End
    End SubPrivate Sub Form_Load()
    MSComm1.InBufferSize = 512        ' 设置接收缓冲区512Byte
    MSComm1.InBufferCount = 0
    MSComm1.OutBufferSize = 512       ' 设置发送缓冲区512Byte
    MSComm1.OutBufferCount = 0
    MSComm1.RThreshold = 1            ' 每个字符到接收缓冲区都触发接收事件
    MSComm1.SThreshold = 1
    MSComm1.InputMode = 0                '接收文本型数据
    Timer1.Interval = 500                '设置定时器事件间隔时间为500毫秒
    Timer1.Enabled = False               '启动定时器
    Timer2.Interval = 500                '设置定时器事件间隔时间为500毫秒
    Timer2.Enabled = False               '启动定时器
    Timer3.Interval = 500                '设置定时器事件间隔时间为500毫秒
    Timer3.Enabled = False               '启动定时器
    MSComm1.InputLen = 2              ' 设置或返回一次从接收缓冲区中读取字节数,0表示一次读取所有数据
    End SubPrivate Sub MSComm1_OnComm()
    Select Case MSComm1.CommEvent
    Case comEvReceive
    TextReceive.Text = TextReceive.Text + MSComm1.Input
    End Select
    Select Case TextReceive.Text
    Case "s1"
       TextSend.Text = ""
       TextReceive.Text = ""
       Shape1.BackColor = &HFF00&
       MSComm1.InBufferCount = 0
       MSComm1.OutBufferCount = 0
       Timer1.Enabled = False
    Case "n1"
       TextSend.Text = ""
       TextReceive.Text = ""
       Shape2.BackColor = &HFF00&
       MSComm1.InBufferCount = 0
       MSComm1.OutBufferCount = 0
    Case "h1"
       TextSend.Text = ""
       TextReceive.Text = ""
       Shape3.BackColor = &HFF&
       MSComm1.InBufferCount = 0
       MSComm1.OutBufferCount = 0
       Timer2.Enabled = False
    Case "z1"
       TextSend.Text = ""
       TextReceive.Text = ""
       Shape4.BackColor = &HFF&
       MSComm1.InBufferCount = 0
       MSComm1.OutBufferCount = 0
       Timer3.Enabled = False
    End Select
    End SubPrivate Sub StartComm_Click()
    Timer2.Enabled = True
    End SubPrivate Sub StartTest_Click()
    Timer1.Enabled = True
    End SubPrivate Sub StopComm_Click()
    Timer3.Enabled = True
    End Sub'Private Sub TextReceive_Change()
    'End SubPrivate Sub Timer1_Timer()
    MSComm1.Output = TextSend.Text
    TextSend.Text = "s"
    MSComm1.OutBufferCount = 0
    End SubPrivate Sub Timer2_Timer()
    MSComm1.Output = TextSend.Text
    TextSend.Text = "h"
    MSComm1.OutBufferCount = 0
    End SubPrivate Sub Timer3_Timer()
    MSComm1.Output = TextSend.Text
    TextSend.Text = "z"
    MSComm1.OutBufferCount = 0
    End Sub
      

  8.   

    刚才又测试了一下,需要单片机发送n1的时候加上1秒钟的延时才能够发送z到单片机,如果不加延时就无法实现!请高手指点实时传送n1的时候同时能够发送z至单片机!谢谢!
      

  9.   

    LZ:看了你2处的回贴,仍无法知道你究竟有几个COM口与下位机通信,此外你须将通信协议叙述清楚,方能依据你的情况提供意见。
      

  10.   

    If MSComm1.PortOpen = False Then 
      MSComm1.PortOpen = True 
      MsgBox Chr(13) + "串口打开成功!", vbOKOnly 
    End If 
    从这句就可以看出来串口只有一个在与下位机通信!
    MSComm1.InputMode = 0                '接收文本型数据
    串口是自定义的通信协议,接收的是文本数据,也就是单片机返回的代码为
    Select Case TextReceive.Text 
    Case "s1" 
    Case "n1" 
    Case "h1"
    Case "z1" 
    这四个
    另外MSCOMM的波特率为4800,我也试过更高的波特率不过通讯还是有问题!如果叙述得还不清楚,你可以直接PM给我!
    如果你想测试可以直接将我第二次发送的代码粘贴到VB项目中运行,你可以用串口调试软件进行调试!谢谢!
      

  11.   

    CSDN这么多的高手就没有一个人做过这种项目的吗?
      

  12.   

    Option Explicit
        Dim strRec As String
    Private Sub CommTest_Click()
        On Error GoTo ErrorMessage
        If MSComm1.PortOpen = False Then
            MSComm1.PortOpen = True
            MsgBox "串口打开成功!"
        End If
        Exit Sub
    ErrorMessage:
        MsgBox Chr(13) + "串口打开失败!" + Chr(10) + "错误代码:" & Err.Number & Chr(10) + "原因:" & Err.Description, vbQuestion
    End SubPrivate Sub Exit_Click()
        Timer1.Enabled = False
        If MSComm1.PortOpen = True Then
            MSComm1.PortOpen = False
        End If
        End
    End SubPrivate Sub Form_Load()
        MSComm1.InBufferSize = 1024      ' 设置接收缓冲区512Byte
        MSComm1.InBufferCount = 0
        MSComm1.OutBufferSize = 512      ' 设置发送缓冲区512Byte
        MSComm1.OutBufferCount = 0
        MSComm1.RThreshold = 1            ' 每个字符到接收缓冲区都触发接收事件
        'MSComm1.SThreshold = 1
        MSComm1.InputMode = 0                '接收文本型数据
        Timer1.Interval = 0           '设置定时器事件间隔时间为500毫秒
        Timer1.Enabled = True             '启动定时器
        Timer2.Interval = 0          '设置定时器事件间隔时间为500毫秒
        Timer2.Enabled = True         '启动定时器
        Timer3.Interval = 0             '设置定时器事件间隔时间为500毫秒
        Timer3.Enabled = True             '启动定时器
        MSComm1.InputLen = 0        ' 设置或返回一次从接收缓冲区中读取字节数,0表示一次读取所有数据
    End SubPrivate Sub MSComm1_OnComm()
        Select Case MSComm1.CommEvent
            Case comEvReceive
                strRec = strRec + MSComm1.Input
                textreceive = strRec
            Select Case strRec
                Case "s1"
                    TextSend.Text = ""
                    strRec = ""
                    Shape1.BackColor = &HFF00&
                    MSComm1.InBufferCount = 0
                    MSComm1.OutBufferCount = 0
                    Timer1.Enabled = False
                Case "n1"
                    TextSend.Text = ""
                    strRec = ""
                    Shape2.BackColor = &HFF00&
        Timer3_Timer
                    MSComm1.InBufferCount = 0
                    MSComm1.OutBufferCount = 0
                Case "h1"
                    TextSend.Text = ""
                    strRec = ""
                    Shape3.BackColor = &HFF&
                    MSComm1.InBufferCount = 0
                    MSComm1.OutBufferCount = 0
                    Timer2.Enabled = False
                Case "z1"
                    TextSend.Text = ""
                    strRec = ""
                    Shape4.BackColor = &HFF&
                    MSComm1.InBufferCount = 0
                    MSComm1.OutBufferCount = 0
                    Timer3.Enabled = False
            End Select
        End Select
    End SubPrivate Sub StartComm_Click()
        'Timer2.Enabled = True
        Timer2_Timer
    End SubPrivate Sub StartTest_Click()
        Timer1_Timer
    End SubPrivate Sub StopComm_Click()
        Timer3_Timer
    End SubPrivate Sub Timer1_Timer()
        MSComm1.Output = TextSend.Text
        TextSend.Text = "s"
        MSComm1.OutBufferCount = 0
    End SubPrivate Sub Timer2_Timer()
        MSComm1.Output = TextSend.Text
        TextSend.Text = "h"
        MSComm1.OutBufferCount = 0
    End SubPrivate Sub Timer3_Timer()
        MSComm1.Output = TextSend.Text
        TextSend.Text = "z"
        MSComm1.Output = TextSend.Text
        MSComm1.OutBufferCount = 0
    End Sub
      

  13.   

    zdingyun   你的脚本我刚才试过了,虽然可以正常的发送代码到单片机,但上位机接收时由于接收速度太快,串口并不能判断指示灯的状态,我将脚本作出以下修改后n1和h1的指示灯能够正常显示,但是z1确不行,因为最后接收到的串口数据为多位,如:1n1z1,所以上位机无法判断接收到z1代码.还请zdingyun及其它高手指点!~
    Option Explicit
        Dim strRec As StringPrivate Sub CommTest_Click()
       On Error GoTo ErrorMessage
    If MSComm1.PortOpen = False Then
       MSComm1.PortOpen = True
       MsgBox Chr(13) + "串口打开成功!", vbOKOnly
    End If
    Exit Sub
    ErrorMessage:
       MsgBox Chr(13) + "串口打开失败!" + Chr(10) + "错误代码:" & Err.Number & Chr(10) + "原因:" & Err.Description, vbQuestion
    End SubPrivate Sub Exit_Click()
    Timer1.Enabled = False
    If MSComm1.PortOpen = True Then
       MSComm1.PortOpen = False
    End If
    End
    End SubPrivate Sub Form_Load()
    MSComm1.InBufferSize = 1024        ' 设置接收缓冲区1024Byte
    MSComm1.InBufferCount = 0
    MSComm1.OutBufferSize = 512       ' 设置发送缓冲区512Byte
    MSComm1.OutBufferCount = 0
    MSComm1.RThreshold = 1            ' 每个字符到接收缓冲区都触发接收事件
    MSComm1.InputMode = 0                '接收文本型数据
    Timer1.Interval = 50                '设置定时器事件间隔时间为50毫秒
    Timer1.Enabled = False               '启动定时器
    Timer2.Interval = 50                '设置定时器事件间隔时间为50毫秒
    Timer2.Enabled = False               '启动定时器
    Timer3.Interval = 50                 '设置定时器事件间隔时间为50毫秒
    Timer3.Enabled = False               '启动定时器
    MSComm1.InputLen = 2                 '设置或返回一次从接收缓冲区中读取字节数,0表示一次读取所有数据
    End SubPrivate Sub MSComm1_OnComm()
    Select Case MSComm1.CommEvent
            Case comEvReceive
                strRec = strRec + MSComm1.Input
                TextReceive.Text = strRec
    Select Case strRec
    Case "s1"
      TextSend.Text = ""
      strRec = ""
      Shape1.BackColor = &HFF00&
      MSComm1.InBufferCount = 0
      MSComm1.OutBufferCount = 0
      Timer1.Enabled = False
    Case "n1"
      strRec = ""
      Shape2.BackColor = &HFF00&
      MSComm1.InBufferCount = 0
      MSComm1.OutBufferCount = 0
      'TextSend.Text = ""
    Case "h1"
      Timer2.Enabled = False
      TextSend.Text = ""
      strRec = ""
      Shape3.BackColor = &HFF&
      MSComm1.InBufferCount = 0
      MSComm1.OutBufferCount = 0
    Case "z1"
      Timer3.Enabled = False
      TextSend.Text = ""
      strRec = ""
      Shape4.BackColor = &HFF&
      MSComm1.InBufferCount = 0
      MSComm1.OutBufferCount = 0
    End Select
    End Select
    End SubPrivate Sub StartComm_Click()
    Timer2.Enabled = True
    End SubPrivate Sub StartTest_Click()
    Timer1.Enabled = True
    End SubPrivate Sub StopComm_Click()
    Timer3.Enabled = True
    End SubPrivate Sub Timer1_Timer()
    MSComm1.Output = TextSend.Text
    TextSend.Text = "s"
    MSComm1.OutBufferCount = 0
    End SubPrivate Sub Timer2_Timer()
    MSComm1.Output = TextSend.Text
    TextSend.Text = "h"
    MSComm1.OutBufferCount = 0
    End SubPrivate Sub Timer3_Timer()
    MSComm1.Output = TextSend.Text
    TextSend.Text = "z"
    MSComm1.OutBufferCount = 0
    End Sub
      

  14.   

    Timer1.Interval = 50                '设置定时器事件间隔时间为50毫秒 
    而且不加入定时器时间根本就不能正常接收和发送数据
      

  15.   

    LZ:我感觉你做这个项目的思路使人琢磨不透。从你第1贴起就没看见过你的通信协议。PC机侧(下称上位机)与单片机通信,谁为主?必须有一方为主,另一方应答。
    那么多Timer控件是多余的。既然有
    z1确不行,因为最后接收到的串口数据为多位,如:1n1z1
    ???那它遵循何种指令要求及指令格式都须事先约定好。
    一个好的串口通信工程,除了硬件符合通信要求外,最重要的是通信协议的制定和按协议约定所做的算法及依据此写收发代码,那是做好串口通信的关键所在。
      

  16.   

    zdingyun 你所谓的通讯协议是指的什么?我一直不明白你所指的通讯协议!上位机和单片机靠串口通讯,串口又不是网络还有TCP/IP,UDP等协议传输!串口协议不过就是以单片机的控制为主,上位机发送代码去控制单片机,这之间的代码互传全用的是文本方式,我举个例简单的来说就是单片机在运行的时候,上位机发送代码h到单片机,单片机识别代码z之后返回给上位机一个z1,代表单片机和上位机之间的通讯已经连接,然后上位机再发送代码s到单片机表示要求单片机启动运行设备,单片机识别代码s后运行设备,如果运行设备正常就返回一个s1给上位机表示设备运行正常,他们之间这种通讯方式是不是就是你所谓的协议?这种协议本来就是搞上位机的和搞单片机软件的人相互定义的,本来项目就是很好,根本不需要太复杂的算法!不知道zdingyun 现在明白了没有?请指点迷津!
      

  17.   

    LZ:给你个通信协议参考:
    附录1:RS485通讯协议
    1. 概述
    在DRS1000 M系列变频器中提供了RS485通讯接口,用户可通过PC/PLC实现集中监控(设定变频器的工作参数和读取变频器的工作状态),以适应特定的使用要求。本附录的协议内容即是为实现上述功能而设计的。
    1.1 协议内容
    该串行通讯协议定义了串行通讯中传输的信息内容及使用格式。其中包括:主机轮询(或广播)格式;主机的编码方法,内容包括:要求动作的功能代码,传输数据和错误检验等。从机的响应也是采用相同的结构,内容包括:动作确认,返回数据和错误校验等。如果从机在接收信息时发生错误,或不能完成主机要求的动作,它将组织一个故障信息作为响应反馈给主机。
    1.2 适用范围 
    1.2.1  适用产品
    DRS2800 M系列变频器
    1.2.2  应用方式
    ⑴ 变频器接入具备RS485总线的“单主多从”PC/ PLC控制网。
    ⑵ 变频器接入具备RS485/ RS232(转换接口)的“点对点”方式的PC/ PLC监控后台。
    2.总线结构及协议说明
    2.1 总线结构
    (1) 接口方式
    RS485(RS232可选)
    (2) 传输方式 
    异步串行、半双工传输方式。在同一时刻主机和从机只能有一个发送数据,而另一个只能接收数据。数据在串行异步通讯过程中,是以报文的形式,一帧一帧发送。
    (3) 拓扑方式
    单主站系统,最多32个站,其中1个站为主机、31个站为从机。从机地址
    的设定范围为1~31,0为广播通讯地址。网络中的从机地址必须是唯一的。点对点方式实际是作为单主多从拓扑方式的一个应用特例,即只有一个从机的情况。
    2.2 协议说明
    DRS1000 M系列变频器通讯协议是一种串行的主从通讯协议,网络中只有一台设备(主机)能够建立协议(称为“查询/命令)。其它设备(从机)只能通过提供数据响应主机的查询/命令,或根据主机的命令/查询做出相应的动作。主机在此处指个人计算机(PC)﹑工控机和可编程控制器(PLC)等,从机指变频器。主机既能对某个从机单独访问,又能对所有的从机发布广播信息。对于单独访问的主机查询/命令,从机都要返回一个信息(称为响应);对于主机发出的广播信息,从机无需反馈响应给主机。2.2.1  数据格式
    3种数据传输格式可选:
    ⑴  1位起始位、8位数据位、1位停止位、无校验。
    ⑵  1位起始位、8位数据位、1位停止位、奇校验。
    ⑶  1位起始位、8位数据位、1位停止位、偶校验。
    从机默认:1位起始位、8位数据位、1位停止位、无校验。
    2.2.2  波特率 
    5种波特率可选:1200bps、2400bps、4800bps、9600bps、19200bps
    默认出厂值:9600bps
    2.2.3  通讯方式 
     利用变频器键盘设置变频器串行接口通讯参数,包括本机地址、波特率、数据格式。
    注:1、主机必须设置与变频器相同的波特率及数据格式。
           2、主机采用广播通讯(从机地址=0)时从机不需要应答
    2.2.4  通讯规则 
    ⑴  主机设计为三次握手呼叫过程,通讯失败或通讯故障后,主机最多可以对当前的报文重发3次。
    ⑵  数据帧之间要保证有4个字节以上的起动间隔时间,只有具备规定的起动间隔时间的报文被识别时才有效。
    ⑶  主机握手等待时间和变频器最长响应时间为8字节传输时间,超时则判定为通讯失败。
    2.3 报文结构
    每个报文共11个字节,包括三部分:帧头、用户数据、帧尾。
    发送顺序
    启始字节 从机地址 编码操作 编码地址址 参数值 操作字 设定值 校验数据
    发送字节数
    单字节 单字节 单字节 单字节 双字节 双字节 双字节 单字节
    定义 帧 头(3CH) 从机地址(1~31) 参数数据 命令数据 帧尾
    用户数据
    数据帧格式示意表:
    说明:
    ⑴ 帧    头:包括起始字节、从机地址
    ⑵ 帧    尾:包括校验数据(即校验和)
    ⑶ 用户数据:包括参数数据和过程数据。其中参数数据又包括:编码操作命令/响应、编码地址、编码设定/实际值。过程数据又包括:主机控制命令/从机响应、主机运行设定/从机运行实际值。
    2.3.1 主机命令帧
    主机发送的数据报文叫主机命令帧,其格式示意如下表:
    发送顺序 启始字节 从机地址 主机命令 编码地址 参数值 操作字 设定值 校验数据
    数据 3C 1 ~ 31
    发送字节数 1 1 1 1 2 2 2 1
    定义 帧 头 参数数据 过程数据 帧尾
    用户数据
    2.3.2 从机响应帧
    从机(变频器)发送的数据报文叫从机响应帧,其格式示意如下表:
    主机发送的数据报文叫主机命令帧,其格式示意如下表:
    发送顺序 启始字节 从机地址 从机响应 编码地址 参数值
    /错误码 状态字 实际值 校验数据
    数据 3C 1 ~ 31
    发送字节数 1 1 1 1 2 2 2 1
    定义 帧 头 参数数据 过程数据 帧尾
    用户数据
    2.4 报文数据编码
    2.4.1 帧头
    ⑴  启始字节
    本通讯协议规定:每个报文的启始字节均为3C,但是启始字节本身对于识别报文的启动是不充分的,因为3C身可能是报文中除启始字节外的其它数据。因此本协议在启始字节前定义了一个至少4个字节传输时间的启动间隔,启动间隔时间为工作报文的一部分。
    ⑵  从机地址
    变频器的本机地址,16进制数,占用1个字节,设置范围:0 ~ 30。
    2.4.2 用户数据
    ⑴  参数数据
    ◎ 主机命令码/从机响应码
    主机发送的命令码或从机对命令的响应码,其数据类型为: 16进制,单字节。
    参数数据 码值 描    述




    码 0 无任务:不做读取或更改参数数据的动作。
    1 读取参数数据:即读取从机编码地址指定的参数数据。
    2 更改参数数据:更改从机编码地址指定的参数数据,此数据在从机掉电后不保存。
    3 更改参数数据并存储至EEPROM中:更改从机编码地址指定的参数数据,并存储至EEPROM。 
    从 机 响 应 码 0 无任务响应:从机响应主机无任务命令信息。
    1 任务完成:从机完成主机命令码规定的任务。
    2 任务未能完成,参数值返回错误码:从机未能完成主机命令码规定的任务,未完成的原因以错误代码形式回传。
    3 通讯发生错误:校验和错误,或从机未接收到规定的字节数。
    ◎ 编码地址
    数据类型:16进制,单字节。
    从机参数的编码地址请参阅使用手册:第四章——参数功能介绍。
    ◎ 参数值/错误码
    数据类型:16进制,双字节。
    对于主机,参数值是指根据主机的命令码,对指定编码地址所提供的数据。当命令码为0或1时(即无任务或读参数数据时),该值可以是参数值值域内的任意值。 
    对于从机,参数值是指命令执行成功时配合具体的主机命令码所返回的数据。
    当命令执行失败时,所返回的参数值为错误码。详细错误码如下:
    0:参数修改被锁定(写不允许)
    变频器通过中级参数P.016的设定可以允许或禁止修改参数。试图修改被禁止改写的参数时将返回本错误提示。
    1:运行中参数不能修改(写不允许)
    某些参数在变频器运行过程中不能被修改,试图修改这些参数时将返回本错误提示。
    2:参数被隐含(读、写不允许)
    变频器中级、高级参数及内部参数可以被隐含,只有打开这些参数,才能对其进行读写操作。否则将返回本错误提示。
    3:保留参数(读、写不允许)
    变频器参数中有些是当前还未定义的保留参数,试图修改这些参数时将返回本错误提示。
    4:参数数值超限,写入失败
    试图修改的参数值超过变频器参数所设定的值域,此时将返回本错误提示。
    5:试图写入过程参数(状态监控参数)
    变频器的状态监控参数[d-00] ~ [d-33]不能被外部改写,试图修改这些参数时将返回本错误提示。
    6:非法功能码
    报文中指定的编码地址是无效的(即不是状态监控参数表和功能参数表中的指定的编码地址)时,将返回本错误提示。
    ⑵ 过程数据
    ◎ 操作字/状态字
    数据含义:主机控制从机运行或从机返回当前运行状态。   
    数据类型:16进制,双字节。
    操作字:(上位机 → 变频器)
    位 含 义 功 能 描 述
    0 保留
    1 正转运行 1:向从机(变频器)下达正转运行指令        0:无效
    2 反转运行 1:向从机(变频器)下达反转运行指令        0:无效
    3 故障复位 1:进行故障复位                         0:无效
    4 主站控制有效 1:当前数据帧中的控制字与设定值更新旧数据 
    0:当前数据帧中的控制字与设定值无效变频器保持前一次的控制字和设定值。
    5 保留
    6 保留
    7 保留
    8 自由停机 1:当主站控制有效位Bit4=1时,当前变频器自由停机
       当主站控制有效位Bit4=0时,当前变频器保持原状态
    0:自由停机命令无效
    9 保留
    10 保留
    11 保留
    12 保留
    13 保留
    14 正转点动 1:当主站控制有效位Bit4=1时,当前变频器正转点动
       当主站控制有效位Bit4=0,当前变频器保持原状态
    0:正转点动命令无效
    15 反转点动 1:当主站控制有效位Bit4=1,变频器反转点动
       当主站控制有效位Bit4=0,变频器保持原状态
    0:反转点动命令无效
    控制优先权顺序为:正转点动,反转点动,正转运行,反转运行,自由停机
    状态字:(变频器 → 上位机)
    位 含  义 功 能 描 述
    0 直流电压状态 1:直流电压正常            0:直流电压异常 
    1 电机转向 1:电机反转                0:电机正转
    2 输出相序 1:反相序                  0:正相序
    3 系统故障 1:变频器故障              0:变频器正常
    4 工作状态 1:变频器运行过程中        0:变频器停机
    5 故障试恢复等待 1:变频器正在故障试恢复等待中   0:变频器不在故障试恢复等待中
    6 保留
    7 直流制动 1:变频器正在进行直流制动       0:变频器不在直流制动状态
    8 自由停机 1:变频器在自由停机状态         0:变频器不在自由停机状态
    9 检速再启动 1:变频器正在进行检速再启动     0:变频器不在进行检速再启动
    10 加速过程中 1:变频器正在加速过程中         0:变频器不在加速过程中
    11 减速过程中 1:变频器正在减速过程中         0:变频器不在减速过程中
    12 电流限制动作 1:变频器限制电流功能动作       0:变频器限制电流功能不动作
    13 电压限制动作 1:变频器限制电压功能动作       0:变频器限制电压功能不动作
    14 点动运行 1:变频器在点动运行状态         0:变频器不在点动运行状态
    15 瞬时停机再启动等待 1:变频器在瞬时停机再启动等待状态  
    0:变频器不在瞬时停机再启动等待状态◎ 设定值/实际值
    数据含义:配合具体的命令响应码,提供主机设定或从机响应数据。
    数据类型:16进制,双字节。
    设定值:根据主机命令码,设定变频器运行频率。例如:50.00HZ 发送
            50.00×100=5000=1388H  
    实际值:根据主机命令码,返回变频器实际运行频率。如果变频器发生故障,实际值将返回相应故障代码。
    故障代码如下:
    故障代码 描   述 故障代码 描   述 故障代码 描   述
    0 无故障 7 停机状态中过压 13 干扰故障
    1 加速中过流 8 变频器运行中欠压 14 输出缺相
    2 减速中过流 9 变频器过载 15 IPM故障
    3 稳态运行中过流 10 适配电机过载 16 外部设备故障
    4 加速中过压 11 变频器过热 17 电流检测回路故障
    5 减速中过压 12 接地故障 18 通讯故障
    6 稳态运行中过压
    2.4.3 帧尾(校验和)
    数据含义:数据帧校验和计算结果。
    数据类型:16进制,单字节。
    计算方法:把从“启始字节”到“用户数据”全部字节连续累加。校验和取累加和除以256的余数。校验和错误将导致通讯发生错误。3.使用范例 
    范例1:将6号变频器的数字频率(参数P.002)设定为50.00Hz。
    主机发送帧:  3C  06  03  02 (88 13)(01 00) (00 00) E3
    从机响应帧:  3C  06  01  02 (88 13)(01 00) (00 00) E1
    (说明:从机任务正确实现)范例2:将0号变频器的负载电机额定频率(参数P.021)设定为60.00Hz。
    主机发送帧:  3C  00  03  06 (70 17) (12 00) (00 00) DE
    从机响应帧:  3C  00  01  06 (70 17) (01 00) (00 00) CB
    (说明:从机任务正确实现)
    3C  00  02  06 (01 00) (11 00) (00 00) 56
    (说明:从机正在运行中,该参数不能修改)范例3:控制1号变频器按10.30Hz的频率正转。
    主机发送帧:  3C  01  00  00  00  00 (12 00) (06 04)  59  
    从机响应帧:  3C  01  00  00  00  00 (11 00) (06 04)  58
    (说明:从机任务正确实现)
    3C  01  00  00  00  00 (09 00) (01 00)  47
    (说明:从机加速运行中发生过流)
      

  18.   

    上位机与单片机通讯一般都是用RS232串口,RS485一般用在现场设备的串口连接!
      

  19.   

    项目其实已经做完了再调试,我只是担心到时候我要用一台上位机做为服务器,通过这台服务器用TCP/IP连接另外几台客户机的时候通讯会出现问题!不过你指点我这么多了还是先把分给你好了,呵呵!
      

  20.   

     
    zdingyun
     
    等 级:  #24楼 得分:0回复于:2009-02-26 09:45:43VB codeOption Explicit
        Dim strRec As String
    Private Sub CommTest_Click()
        On Error GoTo ErrorMessage
        If MSComm1.PortOpen = False Then
            MSComm1.PortOpen = True
            MsgBox "串口打开成功!"
        End If
        Exit Sub
    ErrorMessage:
        MsgBox Chr(13) + "串口打开失败!" + Chr(10) + "错误代码:" & Err.Number & Chr(10) + "原因:" & Err.Description, vbQuestion
    End SubPrivate Sub Exit_Click()
        Timer1.Enabled = False
        If MSComm1.PortOpen = True Then
            MSComm1.PortOpen = False
        End If
        End
    End SubPrivate Sub Form_Load()
        MSComm1.InBufferSize = 1024      ' 设置接收缓冲区512Byte
        MSComm1.InBufferCount = 0
        MSComm1.OutBufferSize = 512      ' 设置发送缓冲区512Byte
        MSComm1.OutBufferCount = 0
        MSComm1.RThreshold = 1            ' 每个字符到接收缓冲区都触发接收事件
        'MSComm1.SThreshold = 1
        MSComm1.InputMode = 0                '接收文本型数据
        Timer1.Interval = 0           '设置定时器事件间隔时间为500毫秒
        Timer1.Enabled = True             '启动定时器
        Timer2.Interval = 0          '设置定时器事件间隔时间为500毫秒
        Timer2.Enabled = True         '启动定时器
        Timer3.Interval = 0             '设置定时器事件间隔时间为500毫秒
        Timer3.Enabled = True             '启动定时器
        MSComm1.InputLen = 0        ' 设置或返回一次从接收缓冲区中读取字节数,0表示一次读取所有数据
    End SubPrivate Sub MSComm1_OnComm()
        Select Case MSComm1.CommEvent
            Case comEvReceive
                strRec = strRec + MSComm1.Input
                textreceive = strRec
            Select Case strRec
                Case "s1"
                    TextSend.Text = ""
                    strRec = ""
                    Shape1.BackColor = &HFF00&
                    MSComm1.InBufferCount = 0
                    MSComm1.OutBufferCount = 0
                    Timer1.Enabled = False
                Case "n1"
                    TextSend.Text = ""
                    strRec = ""
                    Shape2.BackColor = &HFF00&
        Timer3_Timer
                    MSComm1.InBufferCount = 0
                    MSComm1.OutBufferCount = 0
                Case "h1"
                    TextSend.Text = ""
                    strRec = ""
                    Shape3.BackColor = &HFF&
                    MSComm1.InBufferCount = 0
                    MSComm1.OutBufferCount = 0
                    Timer2.Enabled = False
                Case "z1"
                    TextSend.Text = ""
                    strRec = ""
                    Shape4.BackColor = &HFF&
                    MSComm1.InBufferCount = 0
                    MSComm1.OutBufferCount = 0
                    Timer3.Enabled = False
            End Select
        End Select
    End SubPrivate Sub StartComm_Click()
        'Timer2.Enabled = True
        Timer2_Timer
    End SubPrivate Sub StartTest_Click()
        Timer1_Timer
    End SubPrivate Sub StopComm_Click()
        Timer3_Timer
    End SubPrivate Sub Timer1_Timer()
        MSComm1.Output = TextSend.Text
        TextSend.Text = "s"
        MSComm1.OutBufferCount = 0
    End SubPrivate Sub Timer2_Timer()
        MSComm1.Output = TextSend.Text
        TextSend.Text = "h"
        MSComm1.OutBufferCount = 0
    End SubPrivate Sub Timer3_Timer()
        MSComm1.Output = TextSend.Text
        TextSend.Text = "z"
        MSComm1.Output = TextSend.Text
        MSComm1.OutBufferCount = 0
    End Sub
     请问该位仁兄,中间这句textreceive=strRec是指数据的接受文本框吗?这句是把数据送到该文本显示吗?