串口读取数据为什么连读两次?

yuanchao1985 2010-07-12 10:49:33
以下是代码

下图是用串口调试工具,通过虚拟串口发送的数据

下面是debug显示的抓取的数据和缓冲区的剩余长度


代码:
Private Sub Form_Load()
If MSComm1.PortOpen = True Then
MSComm1.PortOpen = False
End If
MSComm1.PortOpen = True
MSComm1.RThreshold = 3
MSComm1.InputLen = 3
End Sub

Private Sub Form_Unload(Cancel As Integer)
If MSComm1.PortOpen = True Then
MSComm1.PortOpen = False
End If
End Sub

Private Sub MSComm1_OnComm()
Select Case MSComm1.CommEvent

Case comEvReceive


MSComm1.InputMode = comInputModeBinary
Dim temp() As Byte
temp = MSComm1.Input

Debug.Print "第一个数据:"; temp(0), "第二个数据:"; temp(1), "第三个数据:"; temp(2), "缓冲区剩余字节数:"; MSComm1.InBufferCount


End Select
End Sub



我只想读取一次共三个字节的数据做判断,然后再决定接下来的数据怎么收。为什么连读了两次数据?
还有怎样改代码可以实现只读一次,读三个
...全文
495 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuanchao1985 2010-07-12
  • 打赏
  • 举报
回复
谢谢大家,我的问题解决了
king06 2010-07-12
  • 打赏
  • 举报
回复
上面也有人说了,每接收到一次数据,使RThreshold=0,
然后一次从buffer里面取3个字节,取完了再设置RThreshold
king06 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 yuanchao1985 的回复:]
引用 9 楼 chinaboyzyq 的回复:
引用 5 楼 yuanchao1985 的回复:

我对MSComm1.RThreshold 和oncomm事件还有MSComm1.InputLen 理解不够。我想只从缓冲区读取3个,然后根据这三个数据决定是否继续读取、读取多少。缓冲区剩下的数据有用

触发事件的MSComm1.RThreshold与你读取的长度的MSComm1.Input……
[/Quote]
一次多接收些数据,RThreshold 设置大点
不过你这样有可能使缓冲区溢出
yuanchao1985 2010-07-12
  • 打赏
  • 举报
回复
收一大堆数据,只触发一次,然后接收3个,由这3个决定怎么处理数据,麻烦大家了,我新手,理解不深刻,经常问问题问不到点上
yuanchao1985 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 chinaboyzyq 的回复:]
引用 5 楼 yuanchao1985 的回复:

我对MSComm1.RThreshold 和oncomm事件还有MSComm1.InputLen 理解不够。我想只从缓冲区读取3个,然后根据这三个数据决定是否继续读取、读取多少。缓冲区剩下的数据有用

触发事件的MSComm1.RThreshold与你读取的长度的MSComm1.InputLen没有直接关系。
你可以设置MSComm1.……
[/Quote]
经过你的指点,我对这几个理解深刻了许多
我想做的是不管缓冲区有多少,我只读3个
然后再根据这3个决定下一步怎么处理数据
chinaboyzyq 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 yuanchao1985 的回复:]

你们在做项目的时候也是设置MSComm1.RThreshold = 1即一字节一触发事件的吗?会不会出现触发次数多了,卡
[/Quote]
我会收到第一个字节后的一定时间内让MSComm1.RThreshold = 0来禁止触发oncomm事件,等我处理完后,再设置MSComm1.RThreshold = 1
chinaboyzyq 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 yuanchao1985 的回复:]

我对MSComm1.RThreshold 和oncomm事件还有MSComm1.InputLen 理解不够。我想只从缓冲区读取3个,然后根据这三个数据决定是否继续读取、读取多少。缓冲区剩下的数据有用
[/Quote]
触发事件的MSComm1.RThreshold与你读取的长度的MSComm1.InputLen没有直接关系。
你可以设置MSComm1.RThreshold=9,而设置MSComm1.InputLen=3
即9字节一触发事件,每次读取3字节,记住你读了这三字节,这三字节在缓冲区内就没了,只有剩余部分。

yuanchao1985 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 zdingyun 的回复:]
如果每次都是接收9字节数据,实际上设置MSComm1.RThreshold为9,MSComm1.InputLen为0.
全部读入接收缓冲区内容,由依据通行信协议来判断处理.
[/Quote]
我发的贴有问题,没有说清楚,所以大家没弄明白我在问什么?我的错!我的意思是,下位机发给我很多数据,这些数据全部在缓冲区里,我想从缓冲区先抓3个出来,然后再根据这3个字节的数据决定接下来怎样读取缓冲区的其他数据
zdingyun 2010-07-12
  • 打赏
  • 举报
回复
如果每次都是接收9字节数据,实际上设置MSComm1.RThreshold为9,MSComm1.InputLen为0.
全部读入接收缓冲区内容,由依据通行信协议来判断处理.
yuanchao1985 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 chinaboyzyq 的回复:]
与你的oncomm事件代码无关。
因为你设置MSComm1.RThreshold = 3,给程序规定3字节一触发事件,所以你发送9个数(9字节)应该触发3次你的oncomm事件(执行你的代码3次)才对。

你想只触发一次事件,你要设置MSComm1.RThreshold = 9

一般是设置MSComm1.RThreshold = 1即一字节一触发事件,以延时超过多长时间为界,然后一次性……
[/Quote]

你们在做项目的时候也是设置MSComm1.RThreshold = 1即一字节一触发事件的吗?会不会出现触发次数多了,卡
yuanchao1985 2010-07-12
  • 打赏
  • 举报
回复
我对MSComm1.RThreshold 和oncomm事件还有MSComm1.InputLen 理解不够。我想只从缓冲区读取3个,然后根据这三个数据决定是否继续读取、读取多少。缓冲区剩下的数据有用
zdingyun 2010-07-12
  • 打赏
  • 举报
回复
1楼的分析是正确的.
chinaboyzyq 2010-07-12
  • 打赏
  • 举报
回复
与你的oncomm事件代码无关。
因为你设置MSComm1.RThreshold = 3,给程序规定3字节一触发事件,所以你发送9个数(9字节)应该触发3次你的oncomm事件(执行你的代码3次)才对。

你想只触发一次事件,你要设置MSComm1.RThreshold = 9

一般是设置MSComm1.RThreshold = 1即一字节一触发事件,以延时超过多长时间为界,然后一次性读取所有数据,然后在收到的数据中截取你有用的数据。
yuanchao1985 2010-07-12
  • 打赏
  • 举报
回复
串口调试工具一次发9个数据

我想一次只收3个
不知道为什么下面这段代码执行了2次
Private Sub MSComm1_OnComm()
Select Case MSComm1.CommEvent

Case comEvReceive


MSComm1.InputMode = comInputModeBinary
Dim temp() As Byte
temp = MSComm1.Input

Debug.Print "第一个数据:"; temp(0), "第二个数据:"; temp(1), "第三个数据:"; temp(2), "缓冲区剩余字节数:"; MSComm1.InBufferCount


End Select
End Sub
chinaboyzyq 2010-07-12
  • 打赏
  • 举报
回复
1、mscomm没有初始化?
MSComm1.RThreshold = 3三字节一触发事件的设置与MSComm1.InputLen = 3一次读取长度的设置可能有问题,可以设置MSComm1.InputLen = 0来一次读取所有内容,这样你一次发送接收端只触发一次事件。

2、触发一次事件后,可设置MSComm1.RThreshold = 0来禁止触发第二次oncomm事件,下次接收数据前设置MSComm1.RThreshold = 3。


Private Sub iniMscomm()
'On Error Resume Next
'=====-----初始化通信串口-----=====

MSComm1.CommPort = 1 '使用 COM1
MSComm1.Settings = "9600,N,8,1" '9600 波特,无奇偶校验,8 位数据,一个停止位
MSComm1.PortOpen = True '打开端口

MSComm1.RThreshold = 1 '缓冲区有1个字节就产生OnComm事件
MSComm1.InputLen = 0

MSComm1.InputMode = comInputModeText
MSComm1.RTSEnable = True
MSComm1.InBufferCount = 0 '清空缓冲区

End Sub


7,785

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧