单片机发的数据第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
只要单片机发的数据是一样 ,上位机接收显示出来的数据都是一样的
但上位机下发数据要求 :
发地址帧第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
只要单片机发的数据是一样 ,上位机接收显示出来的数据都是一样的
上位机的校验位设置应该与单片机相同。我在答复中的表格数据证实此点。
你的问题是上位机与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
像你这样,单片机发送的都是 Space, 而不是偶校验。一般的情况下,应该是上位机发送 Mark,单片机也发送 1。也就是说,在同一个会话中不需要变更设置,而会话总是又上位机发起。 因此,上位机可以从容地变更设置。像你这种情况,恐怕要采用 API 了。发送命令后,可以立即变更设置,转入接收。如果使用 MSComm 控件,就要和单片机调试应答延迟,至少用 Mark 发送地址命令的会话中需要延迟应答。因为你必须 Close MSComm 控件才能更改设置。而 Close 是相当慢的。不存在太快的问题,因为你可以监控发送缓存,如果空,就是发送出去了。恐怕问题是太慢,等你换过来,单片机已经发过了。
看来系统对通信状态有影响.
希望到时有好的方案来解决
在这里先感谢下zdingyun先生,每次都很热心的回答我的问题
我单位有台设备,当时配置的串口通信电脑是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
接收 buffer 中没有处理的数据恐怕要被清除了!这样一来你可能有数据丢失的现象