系统如下:
    pc机通过485卡与多个51单片机进行主从式通讯,要求上位机将单片机RB8位置1或0,RB8位为1时单片机接收地址,为0时接收数据。
问题是:如何通过MSCOMM控件将其置为1或0?

解决方案 »

  1.   

    看看 我的代码: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
      

  2.   

    你把单片机的一个口子接到串口RTS或DTR之类的端口处。你上位机可以MSComm1.RTSEnable = True
    MSComm1.DTREnable = False的方法来控制端口是高电平还是低电平
    在单片机处,你可以使用外部中断来更改rb7这个位你还可以使用定时器查询来更改rb7这个位有问题请发消息给哦!
      

  3.   

    多谢楼上两位!
    我现在用的是研祥的485通讯卡,通讯线为A、B、GND三根线。
    能否通过MSCOMM控件控制单片机的RB8位?
    我原来用奇偶校验位控制,地址和命令就要分清,
    比如发地址3和5时,RB8可以为一种电平,但4就为另一种电平。
    多谢各位!
      

  4.   

    在VB里写发送的十六进制程序如下:
    Private Sub writerotation_Click()  '写转向
      Dim buf$
      Dim ExclusivOR As Byte
      Dim lb(13) As Byte
      lb(0) = &H4                      'EOT
      lb(1) = &H30                     'address of inverter
      lb(2) = &H31
      lb(3) = &H2                      'STX,start of text
      lb(4) = &H30                     'address of parameter 
      lb(5) = &H33
      lb(6) = &H30
      lb(7) = &H32
      lb(8) = &H0                      'value of parameter
      lb(9) = &H0
      lb(10) = &H0
      lb(11) = &H1
      lb(12) = &H3                     'EOT,end of text
      ExclusivOR =lb(4)Xorlb(5)Xor lb(6)Xorlb(7) Xor lb(8) Xor lb (9)
                  Xor lb(10) Xor lb(11) Xor lb(12)  '异或计算
      If ExclusivOR < &H20 Then        '如果异或值小于&H20,则加上&H20
      ExclusivOR = ExclusivOR + &H20
      End If
      lb(13) = ExclusivOR
      MSComm1.OutBufferCount = 0
      MSComm1.InBufferCount = 0
      buf = lb
      MSComm1.Output = buf             '发送
    End Sub
    用串口调试程序在别的计算机里却得不到所需要的十六进制“04 30 31 02 30 33 30 32 00 00 00 01 03 XOR”,得到的是“3F 3F 3F 48 55 00 28 21 3F”,不知是不是十六进制的表示有问题,而且也得到的十六进制的数量也不符。楼上高手请赐教
      

  5.   

    用VB可以进行通讯的,直接用MSCOMM控件就可以,我正在搞类似的项目,几乎跟你讲
    的一样,也是上位机通过485与单片机通讯,希望能互相学习。
    单片机的rb8(单片机串口通讯方式3),即第九位也就是MSCOMM控件中的奇偶校验位。
    地址(1)用mask方式
    数据(0)用space方式
      

  6.   

    generalj(冬日酷热) :
       多谢,我试一下,这两种方式我没试过!
       希望多交流。
       e-mail:[email protected]