MSComm1.CommPort = 1
MSComm1.Settings = "9600,N,8,1"
MSComm1.RThreshold = 17
MSComm1.InputLen = 0
MSComm1.SThreshold = 1
MSComm1.InputMode = comInputModeBinary
If MSComm1.PortOpen = False Then MSComm1.PortOpen = True
如上代码,我写在Form_Load()中。MSComm1.RThreshold被我写死了。与一个设备或者同类型设备通信时没有问题。
但是我现在要添加其他的设备,还包括与单片机通信,这样,返回的数据长度就有可能不一样(都使用modbus协议)。
请问,当与多个设备通信,返回的数据长度不同,在MSComm1_OnComm()中如何判断接收呢?
解决方案 »
- 无法上传文件到Linux FTP服务器
- vb程序打包 哪种方法好
- 一个非夷所思的问题!!!?
- 请教用SENDMESSAGE对LISTVIEW的某项进行选定的方法(也就是把某一行的颜色都变为深蓝色)
- 请问制作chm文件,大家都用什么工具?
- 做共享软件的朋友:请问国内有哪些信用度较高的共享软件代理网站或代理商?在线等待...
- 怎样动态生成、排列控件?(急)
- 关于"vb程序员是些什么货色"文章,我发表一些小看法。xixi。
- 在使用adodb.connection.rollbacktrans 前如何判断connection 是否处于活动事务状态?
- 我想问一下vb和vbscript在区别到底在哪里???请详细一点!!拜托!!!!
- 问下,怎么样才能固定数位?
- 关于picturbox尺寸不一的问题
MSComm1.RThreshold = 1
在OnComm事件的接收代码中按各自数据帧的约定进行判断,如字节长度,帧头帧尾判断.
不能的长度,需要你自己定义一个协议
您的意思是不是先判断第一个地址号,然后再读操作号,再根据第三个BYTE的数据长度的值,读取数据长度+2的BYTE的数据,然后将这些数据看成一帧,然后再进行处理?如果多台外设同时发送数据给上位机程序,怎么做才能不让这些数据相互参杂,从而保证数据的正确性呢。软件延时是否能达到这个作用呢?
在发送命令前,根据预期的反馈数据长度动态设置 RThreshold。
2.如果需要xon、xoff,采用单字符接受直接用语句去判断11 和 13.
不要采用mscomm自带的西欧你、xoff功能。停的慢容易产生override.
3.一般的数据采集,没有必要用中断
4.尽量采用简单的方法去解决复杂的问题
5.自控---简单就意味这可靠
6.如果采用字符长度进行接受,如果采集对象中途关机。关机的干扰也会采进来。
这里的延迟主要考虑3方面:
1)轮询数据帧字节数和波特率,如果波特率是9600,每秒理论可传输960字节,也就是说每字节至少需要1MS,如果发送10字节数据帧,则为10MS
2)发送和接收的串口将位电平信号硬件处理的时间,一般远在MS数量级下.
3)下位机接收和返回数据的时间.
采用TIMER计时器设置100-200MS周期是较为恰当的.
波特率是4800,查询是8字节,返回的最多为17字节,这样的话TIMER设置100-200MS应该也可以。再将MSComm1.RThreshold = 1 一次接收完。理论上应该没问题了。下次需要到机房试试。
MSComm1.RThreshold = 1
这个标志字节是什么呢?是地址码吗? 还是帧的开始和结束标志?OnComm()接收到的数据中没看到开始和结束标志啊
我告诉你吧 可能是 大概是:假设是情况2:那要简单点,首先要说的是 要用oncomm事件,那么会出现接收超过8字节会多次进入oncomm程序的情况,要想进入一次oncomm就全部接受帧的所有字节,就要加延时,在Case comEvReceive后面 加延时,延时多长时间呢,比如说一个帧20个字节,那么你就延时30毫秒,应该没有问题。如果有问题,就加大延时时间。然后再判断接收的帧的长度IF (接收到单片机A的9个帧) then
ReceiveFrame() = MSComm1.Input '接收的帧转移到数组里面
判断接收的帧是否符合你的协议
ELSE IF (接收到单片机B的8个帧) then
ReceiveFrame() = MSComm1.Input '接收的帧转移到数组里面
判断接收的帧是否符合你的协议
ELSE
MSComm1.InBufferCount = 0'清空缓存好情况2到此结束。现在说情况1
情况1就麻烦了,我也没有试过
还是不说了
============================================9楼说的很好,一个字节一个字节的接收 对于处理不定长的情况很好
我现在想到的方法是 inputlen = 1
MSComm1.RThreshold = 1 不知道能不能实现一个字节一个字节的接收。
那就需要定时器,如果设定时间内没有接收到数据 就认为本帧传输完毕。以后有时间 要试一试==========================================
一般来说 发送数据采用轮询 接收数据采用中断
Dim coldata As CollectionPrivate Sub Form_Load()
'初始化数据缓冲池
Set coldata = New Collection '初始化并打开串口
MSComm1.CommPort = 1
MSComm1.Settings = "9600, n, 8, 1"
MSComm1.RThreshold = 1 '设置为每收到一个字节数据触发一次Oncomm事件
MSComm1.InputMode = comInputModeBinary
MSComm1.PortOpen = True
End SubPrivate Sub MSComm1_OnComm()
Dim yy As Long
Select Case MSComm1.CommEvent
Case comEvReceive
Dim xx() As Byte
xx = MSComm1.Input
For yy = 0 To UBound(xx) - 1 '把串口接收到的所有数据都先保存到数据缓冲池暂时不去处理,因为无法保证数据已经接收完整
coldata.Add xx(yy)
Next yy
End Select
End Sub'用Timer控件循环对接收到的数据进行处理,如果你会用多线程的话可以另开一个线程来单独处理
Private Sub Timer1_Timer()
Dim xx As Long
For xx = 1 To coldata.Count '遍历所有串口收到的数据
'代码略,按照通讯协议对串口收到的数据进行分析和处理
'处理完成及时把已处理的数据从缓冲池中移除
Next xx
End Sub