串口发送数据问题

qq_30626551 2015-09-13 11:49:09
串口下挂1个数据采集设备,16个开关量采集,还有模拟量输出。使用MSComm1串口1,我现在使用timer轮询每个开关量输入通道采集输入状态,但在此过程中也需要点击command1来通过串口发送模拟量输出数据,请问如何在timer循环过程中当点击command1时能停止timer循环先发送模拟量输出的数据。如果在command1_click中写:
timer1.enabled=false
MSComm1.Output = ****
这样肯定不行。
需要在后面加什么语句才能判断timer1停止后串口中无数据,再发送模拟量输出的数据呢。
表述不清请谅解,新手。
...全文
1994 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_30626551 2015-09-16
  • 打赏
  • 举报
回复
引用 8 楼 bakw 的回复:
不用在oncomm事件里等返回,查询mscomm控件的接收区缓存大小就知道有没有数据了,那个接收应该是有独立线程的,反正VB死等不会影响到它接收数据的。好象是.inputcount吧,记不太清了
查询接收区缓存是否清空也会有问题。比如一个timer循环语句刚结束,下个计时开始,此时点击command时,timer.enabled=false,查询到的缓存区是空的,但timer还是要等下一个计时停止,此刻command中和timer中语句同时往串口发数据,就又冲突报错了。之后加个计时死等倒是可以解决,但总觉得这样有点浪费时间了。。。
笨狗先飞 2015-09-16
  • 打赏
  • 举报
回复
没事的,死等可以把事情简化掉,我一直都是这么干的,不然oncomm事件的介入时机也是个问题,除非你是定长数据包,不然事件触发了,数据也不一定是完整的,还是要花时间等。毫秒级的等待真的很短
qq_30626551 2015-09-15
  • 打赏
  • 举报
回复
我现在的解决方法是把command中的事件也写入timer中了,让它们一起循环发送。加一个中间变量,然后再通过command改变中间变量的值,实现接收到command事件里返回的值。这样可以解决问题,但串口发送的数据量就变大了,循环一个周期时间也会变长,如果下挂设备多了的话,循环周期太不乐观了。。。
qq_30626551 2015-09-15
  • 打赏
  • 举报
回复
引用 3 楼 bakw 的回复:
VB是单线程的,你command1_click事件中不会对timer有影响,你可以把收发的代码全实现在这个函数中,这样就好了,除非你用了doevents,那就麻烦大了,搞不好连程序都结束不掉。
确实是,我现在的操作就相当于两线程了。因为timer中也是一直循环在收发数据,所以不能都写在command中吧。
qq_30626551 2015-09-15
  • 打赏
  • 举报
回复
引用 2 楼 of123 的回复:
串口通讯是双方都可以主动发送的。 因此,如果你使用同一个串口,不存在定时采集的问题的。你采用定时器,实际上是检查接收缓存中是否已经有进来的数据。 此外,也不存在你可以中断已经触发的 Time_On 事件的可能性。timer1.enabled=false 只不过是暂停下一次 Time_On 事件触发。 比较简单在做法,是 command1 点击事件中,也做一下 Time_On 中所做的缓存读取操作。有则取来,无则空走。不必对 Timer 做开关操作。 当然,我更倾向的方式,是利用串口的 MSComm1_On 事件进行进入数据的处理,而不是使用 Timer 定时。这样的话,在 command1 点击事件中就不必做任何处理。
在timer循环中是一直往设备发送查询数据的,因为设备的设置就是必须要发送查询命令,才会返回值。是不是相当于mscomm_on事件一直在循环触发的。
笨狗先飞 2015-09-15
  • 打赏
  • 举报
回复
不用在oncomm事件里等返回,查询mscomm控件的接收区缓存大小就知道有没有数据了,那个接收应该是有独立线程的,反正VB死等不会影响到它接收数据的。好象是.inputcount吧,记不太清了
笨狗先飞 2015-09-15
  • 打赏
  • 举报
回复
你发完之后用do loop,加个计时死等就行了,超过多少时间就算超时,一般100个毫秒就可以算超时了 看起来这个函数占用时间挺长,其实正常通讯时,占用的时间很短的,就算超时也不过是0.1秒,而且因为是单线程的程序,所以挺安全的。
of123 2015-09-14
  • 打赏
  • 举报
回复
串口通讯是双方都可以主动发送的。 因此,如果你使用同一个串口,不存在定时采集的问题的。你采用定时器,实际上是检查接收缓存中是否已经有进来的数据。 此外,也不存在你可以中断已经触发的 Time_On 事件的可能性。timer1.enabled=false 只不过是暂停下一次 Time_On 事件触发。 比较简单在做法,是 command1 点击事件中,也做一下 Time_On 中所做的缓存读取操作。有则取来,无则空走。不必对 Timer 做开关操作。 当然,我更倾向的方式,是利用串口的 MSComm1_On 事件进行进入数据的处理,而不是使用 Timer 定时。这样的话,在 command1 点击事件中就不必做任何处理。
笨狗先飞 2015-09-14
  • 打赏
  • 举报
回复
VB是单线程的,你command1_click事件中不会对timer有影响,你可以把收发的代码全实现在这个函数中,这样就好了,除非你用了doevents,那就麻烦大了,搞不好连程序都结束不掉。
zdingyun 2015-09-13
  • 打赏
  • 举报
回复
可以在使Timer控件的Enabled属性False后再发送,发送完后再使Enabled = True。

863

社区成员

发帖
与我相关
我的任务
社区描述
VB COM/DCOM/COM+
c++ 技术论坛(原bbs)
社区管理员
  • COM/DCOM/COM+社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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