请教使用select 监控读写 串口函数如何监测串口发送数据

请教一个关于串口通信控件MSComm接收的问题我需要从串口读取下位机发过来的数据包,并提取出相应的命令帧,再根据命令帧中不同的命令字来执行相应的操作。下位机发过来的命令帧格式是这样的:& 帧头2字节(3F D7)+命令字1字节+数据字节(不同的命令长度不同)+帧尾3字节(0F 0F 0F)向大家请教一下在MSComm1_OnComm()事件中我该怎么操作才能实现?
回答1:逐个字节接收数据,加两个静态变量,分别表示(当前为固定编码|可变编码位置)和(可变编码剩余字节数)。下面的编程就好办了。
回答2:  VB code  '定义一个数据缓冲池,这里用Collection对象作缓冲池,你也可以用数组或其他东西
Dim coldata As Collection
Private Sub Form_Load()
'初始化数据缓冲池
Set coldata = New Collection
'初始化并打开串口
MSComm1.Settings = &9600, n, 8, 1&
MSComm1.RThreshold = 1
'设置为每收到一个字节数据触发一次Oncomm事件
MSComm1.InputMode = comInputModeBinary
MSComm1.PortOpen = True
Private Sub MSComm1_OnComm()
Dim yy As Long
Select mEvent
Case comEvReceive
Dim xx() As Byte
xx = MSComm1.Input
For yy = 0 To UBound(xx) '把串口接收到的所有数据都先保存到数据缓冲池暂时不去处理,因为无法保证数据已经接收完整
coldata.Add xx(yy)
End Select
'用Timer控件循环对接收到的数据进行处理
Private Sub Timer1_Timer()
if coldata.count&6 then exit sub
'收到的数据不足6个
Dim xx As Long
For xx = 1 To coldata.Count
'遍历所有串口收到的数据
if coldata.item(1)$$H3F then
coldata.remove(1)
'收到的第一个字节不是3F,丢弃
代码略,按照通讯协议对串口收到的数据进行分析和处理
'…… 处理完成及时把已处理的数据从缓冲池中移除
xinlan_love
回答3:MSComm1.RThreshold = 3MSComm1.InputMode = comInputModeBinaryPrivate Sub MSComm1_OnComm()Dim bytData() As Byte, bytHeader() As ByteSelect mEventCase comEvReceive
MSComm1.InputLen = 3
bytHeader = MSComm1.Input
If bytHeader(0) $<$ &H3F Or bytHeader(1) $<$ &HD7 Then
Select Case bytHeader(2)
'根据命令字确定接收数据的长度
MSComm1.InputLen = xx
'等待数据和结束字符接收完毕
Do Until MSComm1.InBufferCount = MSComm1.InputLen + 3
'可以加上超时处理
bytData = MSComm1.Input
'提取到接收数据
MSComm1.InputLen = 3
bytHeader = MSComm1.Input
'接收结束字符
If bytHeader(0) $<$ &HF Or bytHeader(1) $<$ &HF
Or bytHeader(2) $<$ &HF Then
End SelectEnd Sub
回答5:上位机和下位机要有约定的,发送什么格式的数据代表什么意思遵守什么协议探讨非常感谢,我感觉理论上是行得通的,但是有一个小小的疑问,假如我说的是假如,下位机发送的第一个字节不是帧头怎么办?君,已阅读到文档的结尾了呢~~
广告剩余8秒
文档加载中
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
串口通信中用到的函数
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口通过串口发送手机短信_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
通过串口发送手机短信
上传于||暂无简介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
下载文档到电脑,查找使用更方便
还剩10页未读,继续阅读
你可能喜欢下次自动登录
现在的位置:
& 综合 & 正文
linux串口数据传输出现问题的几点总结
(一)很多时候当在使用串口的时候你会发现在read串口设备时会出现当机现象,出现这种现象的原因可能是你在open设备的时候没有使用非阻塞的方式打开,在使用串口发送数据和接收数据的时候,或者注意select的配合使用达到非阻塞的读取。
(二)在系统头文件&termios.h&中定义了终端控制结构struct termios,tcgetattr()和tcsetattr()两个系统函数获得和设置这些属性。结构struct termios中的域描述的主要属性包括:
: 控制选项 c_lflag
: 线选项 c_iflag
: 输入选项 c_oflag
:输出选项 c_cc
:控制字符 c_ispeed :输入数据波特率 c_ospeed :输出数据波特率
如果要设置某个选项,那么就使用"|="运算,如果关闭某个选项就使用"&="和"~"运算。本文使用的各个选项的意义定义如下:
c_cflag: CLOCAL 本地模式,不改变端口的所有者
表示使能数据接收器
表示偶校验
PARODD 表示奇校验 CSTOPB
使用两个停止位 CSIZE
对数据的bit使用掩码 CS8
数据宽度是8bit c_lflag:
ICANON 使能规范输入,否则使用原始数据(本文使用) ECHO
回送(echo)输入数据 ECHOE
回送擦除字符 ISIG
使能SIGINTR,SIGSUSP, SIGDSUSP和 SIGQUIT 信号 c_iflag:
使能输出软件控制
使能输入软件控制
允许任何字符再次开启数据流
把字符NL(0A)映射到CR(0D)
忽略字符CR(0D)
把CR(0D)映射成字符NR(0A)
c_oflag: OPOST
输出后处理,如果不设置表示原始数据(本文使用原始数据)
c_cc[VMIN]:
最少可读数据 c_cc[VTIME]: 等待数据时间(10秒的倍数) 如果以上的标志没有正确的屏蔽或设置,你的串口所收发的数据可能也不会正确,一定要注意这点
(三)由于串口设备经常在linux下使用,注意你要打开的终端设备名称是否正确,"/dev/ttys0"注意不要省略根目录符号,对于多串口通讯的芯片,注意打开的设备名称对应。
&&&&推荐文章:
【上篇】【下篇】在vb6.0下,怎样通过串口通信,实现实时监测外部数据,监测到数据有变化时,系统能够做出相应的处理,不过不能占用系统太多资源,在网上找了一下,发现用多线程能实现,可是,vb6.0不支持多线程编程,怎么办呢?有没有其他好的办法?请各位大侠帮帮忙!!
另外,我想确切指到,vb6.0到底支不支持多线程编程,权威的解答!!!!
回复讨论(解决方案)
VB6支持,但想要实现很好的支持很难。
你的要求只要写OnComm事件就可以了。
用oncomm事件吧,把rtthreshold设成1,这样有数据来就会产生事件,然后在事件中接收数据并进行处理!
但是,我查了一下,oncomm事件,使用了MSComm控件。可是,在多线程里面,不支持控件使用的,怎么办呢?关键在于,在进行串口通信的同时,不能影响系统的正常使用,只有当接收到错误的数据时,才进行相应的处理?我对这方面了解不多,请多赐教!
哦,对了,使用oncomm事件,会不会占用很多系统的资源,让系统运行速度变慢呢?还是影响很小呢?
oncomm应该比较节省系统资源啊,总比循环查询要好的多,windows就是基于事件的,所以用起来比较方便和高效的!
监控的同时,DoEvents&一下。
楼主,我劝你VB6下你最好不要考虑多线程,多半会适得其反的,我曾经也想用多线程实现多个串口的多线程串口通信,但程序很容易就崩溃了,查阅了很多资料,加之我水平不够,放弃了。
如果你的程序是商用的,多线程请慎用,可以使用DoEvents来提高程序的响应。
让界面挂起,一般来说不会是&接收串口数据&时,而是&处理收到的数据&时.
比如你有一个数据包要从串口收过来,大小为1024K,如果处理不好,卡死你.
让界面挂起,一般来说不会是&接收串口数据&时,而是&处理收到的数据&时.
比如你有一个数据包要从串口收过来,大小为1024K,如果处理不好,卡死你.
一般不会这么恐怖了1024K,太大了
这个问题刚开始我也是头疼
我一个串口要实时接收六个仪表,一共二十几个参数值.而且仪表的通讯协议是被动方式的.即PC要发送指令仪表才返回数据.这样一来,要不断的发送指令,不断的接收及处理,还要不断的往数据库写入!!
我是采用轮询方式的,用TIMER作个扫描周期,TIMER事件初关掉TIMER,执行扫描完再开,这样可以有效的压缩TIMER内部时间
在读取函数中加入DoEvents,基本可以了.CPU占用率一直在57%左右.一般的操作不会卡死.测了一天也没问题
但是偶尔在数据库操作的时候,比如查询历史数据,会卡死:(
真也找不到好办法呀~~~
听朋友说,用VB.NET可以采用多线程解决~~~可惜没玩到这个东西过.
期待楼主的问题得到真正的解决!
我们的项目,用的是vb6.0环境开放的,如果要换成.net环境下,就要改动很大了,况且这个项目基本快结束了……时间也来不及……
各位,我们大家一起都再研究研究……看看有没有什么其它好的解决办法……
如果,确实不行的话,就用oncomm进行处理……
毕竟这也是一种办法……
让界面挂起,一般来说不会是&接收串口数据&时,而是&处理收到的数据&时.
比如你有一个数据包要从串口收过来,大小为1024K,如果处理不好,卡死你.
&&&听说,你在这方面,很有研究,你有什么好的处理方法,指点小弟一下……
这个问题刚开始我也是头疼
我一个串口要实时接收六个仪表,一共二十几个参数值.而且仪表的通讯协议是被动方式的.即PC要发送指令仪表才返回数据.这样一来,要不断的发送指令,不断的接收及处理,还要不断的往数据库写入!!
我是采用轮询方式的,用TIMER作个扫描周期,TIMER事件初关掉TIMER,执行扫描完再开,这样可以有效的压缩TIMER内部时间
在读取函数中加入DoEvents,基本可以了.CPU占用率一直在57%左右.一般的操作不会卡死.测了一天也没问题
但是偶尔在数据库操作的时候,比如查询历史数据,会卡死:(
真也找不到好办法呀~~~
听朋友说,用VB.NET可以采用多线程解决~~~可惜没玩到这个东西过.
期待楼主的问题得到真正的解决!
如果你的仪表的实时性要求不是很高(个人认为3秒以内要将这20多个参数读取一遍,这样实时性要求就比较高了),你可以设置一个轮读变量,在Timer中使用Select&Case&语句来依次读取每一个参数,每次读一个。比如,你的Timer的Interval是200ms,那么你读完我、所有的参数耗时大约是:200ms&X&20=4000ms&也就是4秒,其实这个实时性已经很高了。我11个仪表,都是这样处理的。
1.采用多进程,几十个串口程序一起运行
2。每个程序都采用查询式的
3.接受缓冲区开20000字节
剩下的什么时间片全部交给xp去处理。
一个查询就可以让cpu90%,50个查询还是这个样子。自己试一下!
几百元一个的仪表根本就受不了高速采集,里面是单片机。要做AD转换、量程上下限处理、进制转换、键盘处理、接口处理。
想当年在做水泵测试员的时候,
一台奔3的电脑,vb编的测试软件,实时反映几台仪器,十几个数据的采集。
照样能打开模拟器用小窗口玩街霸,一点都不卡。
再安装个老板键,灵得不得了。想关就关。
DOS&的中断在XP里面还有吗?
采集和查询分成两个独立程序就可以了。

我要回帖

更多关于 串口 fcntl select 的文章

 

随机推荐