单片机发的数据第9位都是0
但上位机下发数据要求 : 
          发地址帧第9位为1 即 9600,m,8,1
          发命令帧第9位为0 即 9600,s,8,1但上位机接收数据要求:第9位都是0 这点与单片机发的数据都是偶校验是一致的
现在问题是:上位机发地址帧要先设置成"9600,m,8,1" 然后又要马上设置成"9600,s,8,1",等待接收 这两个设置之间时间差要多少才合适,太快的话 地址帧第9位变为0 太慢的话 上位机接收的数据第9位变为1
有没有办法让 不管上位机设置成以下哪一种:
1. 9600,m,8,1
2. 9600,s,8,1
3. 9600,n,8,1
只要单片机发的数据是一样 ,上位机接收显示出来的数据都是一样的

解决方案 »

  1.   

    上位机的校验位设置应该与单片机相同。我在http://topic.csdn.net/u/20090323/16/07649395-4e4a-48a6-b078-d1534c81026d.html答复中的表格数据证实此点。
    上位机的校验位设置应该与单片机相同。我在答复中的表格数据证实此点。
    你的问题是上位机与RS485转RS232口的单片机通信,如果单片机仅按1种校验方式收和发数据,上位机的MSCOMM控件能很方便改变Settings 属性,如果需要控制时间差,可将发送指令放1个TIMER计时器,由发送地址完成后调用该TIMER的Enabled的True来发送.在Timer1_Timer事件中完成发送指令后使Timer1.Enabled = False
    以下代码未使用TIMER计时器供参考,接收放MSComm1_OnComm事件完成.
    Option Explicit
        Dim strHex As StringPrivate Sub Command1_Click()
        Print Timer
        Dim sendSj() As Byte
        ReDim sendSj(1)
        sendSj(0) = &H1
        sendSj(1) = &HA0
        MSComm1.Settings = "9600,o,8,1" 'o奇校验
        Print Timer
        MSComm1.Output = sendSj
        Print Timer
        MSComm1.Settings = "9600,e,8,1" 'e偶校验
        ReDim sendSj(5)
        sendSj(0) = &HFF
        sendSj(1) = &HA0
        sendSj(2) = &H1A
        sendSj(3) = &HA0
        sendSj(4) = &H1B
        sendSj(5) = &HA0
        Print Timer
        MSComm1.Output = sendSj
        Print Timer
    End SubPrivate Sub Form_Load()
        MSComm1.Settings = "9600,e,8,1" 'e偶校验
        MSComm1.RThreshold = 1
        MSComm1.InputMode = comInputModeBinary
        MSComm1.PortOpen = True
    End SubPrivate Sub MSComm1_OnComm()
        Dim buffer() As Byte
        Dim i As Integer
        Select Case MSComm1.CommEvent
            Case comEvReceive
            buffer = MSComm1.Input
            For i = 0 To UBound(buffer)
                strHex = strHex & Right("0" & Hex(buffer(i)), 2)
            Next
            '写数据处理代码
            Text1 = strHex
        End Select
    End Sub
      

  2.   


    像你这样,单片机发送的都是 Space, 而不是偶校验。一般的情况下,应该是上位机发送 Mark,单片机也发送 1。也就是说,在同一个会话中不需要变更设置,而会话总是又上位机发起。 因此,上位机可以从容地变更设置。像你这种情况,恐怕要采用 API 了。发送命令后,可以立即变更设置,转入接收。如果使用 MSComm 控件,就要和单片机调试应答延迟,至少用 Mark 发送地址命令的会话中需要延迟应答。因为你必须 Close MSComm 控件才能更改设置。而 Close 是相当慢的。不存在太快的问题,因为你可以监控发送缓存,如果空,就是发送出去了。恐怕问题是太慢,等你换过来,单片机已经发过了。
      

  3.   

    LZ:下午对你另一贴的答复是在WIN98系统测试的,在WINXP系统下,发送按无校验位设置,接收分别改变校验位设置,发送同样字节数据,接收随校验位设置不同接受有变化.WIN98系统则与之相反,接收端按无校验位设置,发送端改变校验位设置,接收随发送端校验位设置改变而改变.
    看来系统对通信状态有影响.
      

  4.   

    最近较忙,不过4月1号之前会来结贴
    希望到时有好的方案来解决
    在这里先感谢下zdingyun先生,每次都很热心的回答我的问题
      

  5.   

    LZ:关于3楼贴的现象,我分析与PC机的硬件配置有关。WIN98的机器是最早的P3机,WINXP的机器是P4双核机。它可能与串口信号波形的脉冲上升和下降有关系,低速机前沿和后沿占用时间较高速机大,以至造成串口接收的位信号判断存在差异。
    我单位有台设备,当时配置的串口通信电脑是386机型笔记本,后来电脑坏了,改换了486电脑,系统是DOS6,运行软件仍是原来的,就发现通信连接出现问题,不得已去找了台386的台式机,才解决问题。
    我将在1楼的代码作修改,添加了TIMER计时器,以解决校验位设置问题,延迟可修改TIMER计时器的时间设置。
    Option Explicit
        Dim strHex As String
        Dim sendSj() As BytePrivate Sub Command1_Click()
        Debug.Print Timer
        ReDim sendSj(1) '地址
        sendSj(0) = &H1
        sendSj(1) = &HA0
        MSComm1.Settings = "9600,o,8,1" 'o奇校验
        Debug.Print Timer
        Debug.Print MSComm1.Settings
        MSComm1.Output = sendSj
        Debug.Print Timer
        MSComm1.PortOpen = False
        MSComm1.Settings = "9600,e,8,1" 'e偶校验
        MSComm1.PortOpen = True
        Timer1.Enabled = True
    End SubPrivate Sub Form_Load()
        MSComm1.Settings = "9600,e,8,1" 'e偶校验
        MSComm1.RThreshold = 1
        MSComm1.InputMode = comInputModeBinary
        MSComm1.PortOpen = True
        Timer1.Enabled = False
        Timer1.Interval = 100 '设置延迟100ms发送指令,可依据实际修改
    End SubPrivate Sub MSComm1_OnComm()
        Dim buffer() As Byte
        Dim i As Integer
        Select Case MSComm1.CommEvent
            Case comEvReceive
            buffer = MSComm1.Input
            For i = 0 To UBound(buffer)
                strHex = strHex & Right("0" & Hex(buffer(i)), 2)
            Next
            '写数据处理代码
            Text1 = strHex
        End Select
    End SubPrivate Sub Timer1_Timer()
        ReDim sendSj(5)
        sendSj(0) = &HFF
        sendSj(1) = &HA0
        sendSj(2) = &H1A
        sendSj(3) = &HA0
        sendSj(4) = &H1B
        sendSj(5) = &HA0
        Debug.Print Timer
        MSComm1.Output = sendSj
        Debug.Print Timer
        Debug.Print MSComm1.Settings
        Timer1.Enabled = False
    End Sub
      

  6.   

    MSComm1.PortOpen = False
    接收 buffer 中没有处理的数据恐怕要被清除了!这样一来你可能有数据丢失的现象