两个程序直接共用一个串口通信程序,怎么能不被占用的情况下能截取串口通信程序的通信数据,(通过串口通信程序去获取客显中数据)

CommMonitor串口监控工具 V3.13 下载 虚拟监视、不占串口、捕获串口数据 - 偶要下载站
偶要下载站 / 绿色软件下载联盟站!为大家提供一手绿色软件下载服务!
当前位置: &
> CommMonitor串口监控工具 V3.13 下载 虚拟监视、不占串口、捕获串口数据
CommMonitor串口监控工具 V3.13 下载 虚拟监视、不占串口、捕获串口数据
CommMonitor串口监控工具是用于RS232 / RS422 / RS485端口监控的专业强大的系统实用程序软件。CommMonitor监视显示,记录和分析系统中的所有串行端口活动。这是追踪应用程序或驱动程序研发,串行设备测试和优化等过程中可能出现的问题的理想方法。
CommMonitor可以侦测、拦截、逆向分析串口通信协议,方便串口工程师诊断硬件的故障,或者调试,优点是它应用虚拟监视、不占串口、捕获串口数据。
此外CommMonitor还提供过滤、搜索、数据导出和强大的数据拦截功能,可以将指定端口的数据流、控制流信息拦截并保存下来,供分析之用。如察看端口状态的变化(波特率、数据位、校验位、停止位),拦截上行、下行的数据,处理速度飞快,拦截效率高,并可以以十六进制、ASCII字符形式显示,全面支持Unicode 。
CommMonitor 串口监视精灵支持Windows系统:
WinXP、Win2003、WinVista、Win7、Win2008、Win8、Win2012、Win2016、Win10,32/64位系统,驱动程序已,完全支持64位Windows系统。
CommMonitor串口监控工具功能特点如下:
1、使用纯API全新编写了所有监视模块,安全稳定有效
2、不能占用串口(COM口),只会对相关的API进行拦截
3、可以在串口打开后监控,一改有些监控软件只能在打开前监控
4、可以直接拖动窗口捕获图标到目标进程窗口上选中进程
5、新增对虚拟串口的监视 ,改变了原来CommMonitor3.0不能对虚拟串口的监视
6、无DLL无驱动,不能对全局进程进行HOOK,只对指定的进程进行HOOK
7、能捕获串口(COM口)的打开、读写数据 、关闭操作,并能同时监视指定进程的最多255个串口
CommMonitor监视串口数据教程:
1、打开CommMonitor软件
2、选择要监视的软件进程ID
3、选择串口号
4、选择显示格式
5、启动监视
6、启动监视后就会有数据陆续显示出来了。
7、这个按钮用来清空显示,如果显示的内容太多,可以点这里清掉。
提示:CommMonitor串口监控工具已经更新到最新版本了!!!
界面预览图:
串口数据读取软件是一款程序员用的辅助软件哦,串口数据大家都知道是很不好读取的,有了这样一款读取软件程序员们就轻松多了...
这款串口软件也是很不错的,和本软件是同类也有很多人下载,您可以试一下它!
4.82MB | 汉化中文 | ★★☆☆☆
454KB | 简体中文 | ★★☆☆☆
6.72MB | 简体中文 | ★★★★☆
2.92MB | 简体中文 | ★★☆☆☆
2.15MB | 简体中文 | ★★★★☆
1.84MB | 简体中文 | ★★☆☆☆
6.27MB | 简体中文 | ★★☆☆☆
409KB | 简体中文 | ★★☆☆☆
564KB | 简体中文 | ★★☆☆☆
974KB | 简体中文 | ★★☆☆☆
CommMonitor串口监控工具 V3.13 下载 虚拟监视、不占串口、捕获串口数据
如果看不到下载地址,请更换其他浏览器!
想下载到手机上? 鼠标移动到左边二维码上扫一扫即可!
1、如果发现下载地址不能下载,请多试几个下载地址!安装及使用时出现问题,安装方法与使用教程请到官方网站获取或搜索。
2、为了保证您享受到最快的下载速度,推荐安装迅雷下载工具。如果下载后出现不能解压,请安装winrar等解压缩包软件!
3、如果下载的压缩包文件需要解压密码,网址就是解压密码:www.ouyaoxiazai.com
4、本站不提供该下载软件的破解版,注册机,注册码,序列号,注册密钥,激活码,等相关信息下载以及咨询!
免费版/简体中文/★★☆☆☆
绿色版/简体中文/★★☆☆☆
绿色版/简体中文/★★☆☆☆
免费版/简体中文/★★☆☆☆
汉化版/汉化中文/★★☆☆☆
免费版/简体中文/★★☆☆☆
下载排行榜
人气下载榜
偶要下载站集绿色软件下载、手机软件与游戏、各种素材、字体下载于一身的联盟网站,致力打造一个纯绿色软件下载乐园。
本站为非营利性网站,中国绿色联盟提供的资源均来自网络收集整理,下载个人纯属学习交流之用,如有侵犯您的版权请与我联系,我们会马上改正请在下载24小时内删除!
Copyright &
偶要下载(OuyaoXiazai.Com) All Rights Reserved. 鲁ICP备号 鲁公网安备74号(转)嵌入式Linux下的串口通信程序设计
原文:http://www.ca800.com/plc/detail.asp?id=10381
嵌入式Linux下的串口通信程序设计
作 者:电子科技大学自动化工程学院 李 梅
随着嵌入式系统应用的发展,linux操作系统的应用也越来越广泛。linux作为一款免费的并且开放源代码的操作系统,与windows操作系统相比有许多独特的优势。linux可以进行定制内核;linux的gui图形界面能够任意选择;linux可以更方便、更安全地进行远程操作。随着linux操作系统的不断发展和完善,基于linux操作系统的软件开发也得到了长足的发展和应用。如果在工控领域引入linux,不可避免的会遇到在嵌入式linux下如何实现串行通信的问题。
风场远程监控系统采用了嵌入式linux操作系统。本文通过基于风场远程监控系统串口的实现,详细地介绍了嵌入式linux下串口通信编程,并根据嵌入式linux操作系统串口通信的特点,制定了独特的串口通信协议,保证风场远程监控系统串口通信的实时性和可靠性。
系统结构分析
风场远程监控系统由风机主控制器、通讯控制器、服务器这三部分构成。风机主控制器存储着风机的所有数据,用户既可以通过服务器访问通讯控制器从而获取风机主控制器的数据,也可以直接访问通讯控制器。
风机主控制器采用英飞凌的xc164芯片实现。通讯控制器基于at91rm9200嵌入式处理器通过移植嵌入式linux操作系统实现,是风机主控制器与用户之间的数据纽带。服务器采用apache服务器。通讯控制器通过串口获取风机主控制器的运行数据,与此同时,服务器中的某些服务同样通过串口与通讯控制器通信。因此,实现嵌入式linux操作系统下的串口通信是整个系统中必不可少的。
3.1 linux下的串口概述
在linux操作系统下,对设备和文件的操作都等同于文件的操作,这样大大简化了系统对不同设备的操作,提高了效率。在程序中,设备和文件都是通过文件描述符来操作的。文件描述符是一个非负数的索引值,指向内核中每个进程打开的文件记录表。当打开一个现存的文件或者创建一个新文件时,内核就向进程返回一个文件描述符。当需要对设备进行读写操作时,也需要把文件描述符作为参数传递给相应的函数。
linux的设备文件都存放在“/dev”目录下,串口资源对应的设备名是“/dev/ttys+编号”,因此串口对应的设备文件的路径是“/dev/ttys*”。对串口的操作可以像读写普通文件一样读写设备文件即可。
linux下的串口通信程序设计&&&
串口参数包括波特率、起始位数量、停止位数量等数值。串口设置主要是设置termios机构体中的各成员值。termios是linux系统用于查询和操纵各个终端的一个标准接口,在头文件“termios.h”定义。termios的数据结构如下所示:
struct& termios
c_&&&&&&&&&&&&&&
c_&&&&&&&&&&&&&
c_&&&&&&&&&&&&&
c_&&&&&&&&&&&&&
c_&&&&&&&&&&&&&&&&
c_cc[nccs];&&&&&&&&&&&
串口通信程序可分为以下几个步骤:
第一步:打开串口
&&& 调用open( )
打开串口设备,如果出错返回-1,成功则返回一个整形文件句柄,以后这个串口的操作都针对这个句柄进行。
&&& #define
usart0 /dev/ttys0
&&& #define
usart1 /dev/ttys1
open_usart(usart)
= open (“usart”,o_rdwr | o_noctty | o_nonblock);
&&&&&if(-1
&&&&&&return
&&& return
open_usart(usart0);&&&&&
第二步:串口属性配置
打开串口后需要对串口进行属性配置,即对termios结构体中的成员进行设置。串口属性应与windows下串口属性和xc164单片机串口属性保持一致,即采用相同的数据流格式、波特率和校验方式。根据是否对数据进行预处理,传输方式可分为正则方式和原始方式。为实现实时通信,将串口所对应的终端设置为原始工作方式,即不对输入和输出字符进行任何处理,不等待字符汇聚成一行,而是立即读写串口。
系统根据termios结构中c_cc数组的两个变量vmin和vtime判断是否返回输入。vmin设定满足读取功能的最低字节个数,vtime设定字节输入时间计时器。因此在操作串口是要特别注意设定这两个变量的值,尽量保证串口的通信成功率。
在termios结构中,最重要的是c_cflag,用户通过对其赋值可以实现串口波特率、字符大小、数据位、停止位、奇偶校验位等参数的设置。需要注意的是,termios结构不能初始化,需要使用位运算符在程序中进行参数设置或者清除。
set_config (int fd)
result=tcgetattr(fd, &options);
if(result&0)
&&&&&printf(“error
in tcgetattr\n”);
return (-1);
options.c_cflag &=~
options.c_cflag &=~
options.c_cflag &=~
options.c_cflag |=cs8;
options.c_iflag &=~(icanon|echo|isig);
options.c_iflag &=~(ixon|ixoff|ixany);
options.c_iflag &=~
options.c_oflag &=~
options.c_cc[vmin]=1;
options.c_cc[vtime]=l;
cfsetospeed(&options,b115200);
cfsetispeed(&options,b115200);
tcsetattr(fd,tcsanow,&options);
&&& return
经过设置后,就可用标准的文件读写命令read()和write()操作串口了。最后在退出前,用close()函数关闭串口。
3.3 linux下采用select机制读写多个串口
本文的串口读写采用了非阻塞的模式。在这种模式下要采用轮询的方法读写串口。当进程调用read函数时,设置了o_nonblock标志,那么即使串口没有数据可读,read函数也会立即返回。此时其返同值为eagain,表明串口数据未就绪。如果串口有数据可读,则read函数会读取该数据,并返回所读数据的长度,此时进程必须通过反复调用来检测是否有数据可读。如果轮询频率过低,则容易丢失数据;轮询频率过高,则占用太多处理器的处理周期。
与频繁调用非阻塞读写函数来轮询监听串口的方法相比,select调用允许用户把进程本身挂起来,同时使系统内核监听所要求的一组文件描述符的任何活动。只要确认在任何被监控的文件描述符上出现活动,select调用将返回指示该设备文件已经准备好的信息。这样就使进程能相对实时地监测到串口设备上随机的变化,而不必由进程本身去探测输入数据是否准备好。
select定义于&uintsd.h&中,函数原型如下:
select(int n,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,struct
timeval*timeout);
第1个参数n表示文件描述符集合中最大值再加1。第2个参数readfds表示可读文件描述符集合,当文件描述符的状态变成可读的时候系统就会告诉select函数返回。第3个参数writefds表示可写文件描述符集合,当文件描述符状态变成可写时系统会要求select函数返回。第4个参数exceptfds用于异常控制。struct
timeval*timeout是select的超时时间,这个参数至关重要,它可以使select处于三种状态,第一,若将null以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;第二,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;第三,timeout的值大于0,这就是等待的超时时间,即select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,将控制权交还给调用select函数的进程。
以下是本文采用select机制实现多个串口读写的程序:
&&& struct
ret=0,maxfd=0;
&&& struct
timeover.tv_sec =
0;&&&&&&&&&&&&&&&&&&
timeover.tv_usec =
10000;&&&&&&&&&&&&&
open_usart(usart0);&&&&&&&&&&&
open_usart(usart1);&&&&&&&&&&&
fd_zero(&fds);&&&&&&&&&&&&&&&&&&&
fd_set(fd1,&fds);&&&&&&&&&&&&&&&&&
fd_set(fd2,&fds);&&&&&&&&&&&&&&&&&
&&& maxfd =
(fd1&fd2)?(fd1+1):(fd2+1);&&&&
select(maxfd,fds,null,null,&timeover);&&&&
switch(ret)
perror(“select”);&&&&&
&&& printf(“time
over!”)&&&
&&&&&&if(fd_isset(fd1,&fds))&&
串口0处理函数;&&
if(fd_isset(fd2,&fds))&&
串口1处理函数;
串口通信协议
由于本系统采用非规范式输入,导致一帧数据可能分成几次接收。为了能够判断一帧数据是否接收完整,本系统制定了一套特殊的串口通信协议,如附图所示。
通信协议定义
在本系统的串口通信协议中,一帧数据包括了帧头、数据长度、数据内容和数据校验这四部分。数据长度、数据内容和数据校验为有效数据区。帧头长度为两个字节,为0xaa、0xbb。当接收到相邻的两个字节为0xaa和0xbb数据时,认为一帧数据开始。数据长度为两个字节,是数据内容的字节数和数据校验的字节数之和。数据校验采用crc16的校验方式,对数据长度和数据内容进行校验,占两个字节。数据内容的最大字节数为65533,即一帧数据最多可以传送65533个字节的数据。
待发送的数据不可避免地会出现相邻的两个字节为0xaa和0xbb的情况,如不对此中情况进行处理即发送数据,则一帧数据会被误判为两帧。针对这一问题,本系统提出了一种行之有效的解决方法。数据长度、数据内容以及数据校验这三部分数据中一旦出现0xaa,则重复一次0xaa。重复的0xaa不计入数据长度也不进行数据校验。
接收数据时进行逆向操作。首先根据接收到的两个字节判断是否为帧头,如果是则代表一帧数据开始,继续接收余下的数据,否则循环检测。在接收数据时根据数据长度判断一帧数据是否接收完毕,接收完一帧数据后进行crc校验,校验正确则进行数据处理,否则丢弃这帧数据。在有效数据区内如果出现两个相邻字节为0xaa的数据,则只取其中的一个字节。
本文设计了在基于at91rm9200硬件平台上,针对风场远程监控系统中的嵌入式linux串口通信程序,并且制定了行之有效的串口通信协议。实践证明本文针对风场远程监控系统设计的串口通信程序运行良好,数据收发正常。本文对于从事嵌入式linux下的多串口通信程序设计人员具有一定的参考价值。
李& 梅(1984-)& 女&
硕士研究生,研究方向为控制理论与控制工程。
&&& [1] 孙纪坤,张小全.
嵌入式linux系统开发技术详解——基于arm[m]. 北京:人民邮电出版社,2006.
&&& [2] 李玉波.
linux c编程[m]. 北京:清华大学出版社,2005.
&&& [3] 陈先在.
linux c函数实力速查手册[m]. 北京:人民邮电出版社,.
&&& [4] 杨宗德.
linux高级程序设计[m]. 北京:人民邮电出版社,2008.
 | 本文来自:2009年第10期“现场总线与网络技术”上 ,已经被阅读过33次
嵌入式Linux下的串口通信程序设计
作 者:电子科技大学自动化工程学院 李 梅
随着嵌入式系统应用的发展,linux操作系统的应用也越来越广泛。linux作为一款免费的并且开放源代码的操作系统,与windows操作系统相比有许多独特的优势。linux可以进行定制内核;linux的gui图形界面能够任意选择;linux可以更方便、更安全地进行远程操作。随着linux操作系统的不断发展和完善,基于linux操作系统的软件开发也得到了长足的发展和应用。如果在工控领域引入linux,不可避免的会遇到在嵌入式linux下如何实现串行通信的问题。
风场远程监控系统采用了嵌入式linux操作系统。本文通过基于风场远程监控系统串口的实现,详细地介绍了嵌入式linux下串口通信编程,并根据嵌入式linux操作系统串口通信的特点,制定了独特的串口通信协议,保证风场远程监控系统串口通信的实时性和可靠性。
系统结构分析
风场远程监控系统由风机主控制器、通讯控制器、服务器这三部分构成。风机主控制器存储着风机的所有数据,用户既可以通过服务器访问通讯控制器从而获取风机主控制器的数据,也可以直接访问通讯控制器。
风机主控制器采用英飞凌的xc164芯片实现。通讯控制器基于at91rm9200嵌入式处理器通过移植嵌入式linux操作系统实现,是风机主控制器与用户之间的数据纽带。服务器采用apache服务器。通讯控制器通过串口获取风机主控制器的运行数据,与此同时,服务器中的某些服务同样通过串口与通讯控制器通信。因此,实现嵌入式linux操作系统下的串口通信是整个系统中必不可少的。
3.1 linux下的串口概述
在linux操作系统下,对设备和文件的操作都等同于文件的操作,这样大大简化了系统对不同设备的操作,提高了效率。在程序中,设备和文件都是通过文件描述符来操作的。文件描述符是一个非负数的索引值,指向内核中每个进程打开的文件记录表。当打开一个现存的文件或者创建一个新文件时,内核就向进程返回一个文件描述符。当需要对设备进行读写操作时,也需要把文件描述符作为参数传递给相应的函数。
linux的设备文件都存放在“/dev”目录下,串口资源对应的设备名是“/dev/ttys+编号”,因此串口对应的设备文件的路径是“/dev/ttys*”。对串口的操作可以像读写普通文件一样读写设备文件即可。
linux下的串口通信程序设计&&&
串口参数包括波特率、起始位数量、停止位数量等数值。串口设置主要是设置termios机构体中的各成员值。termios是linux系统用于查询和操纵各个终端的一个标准接口,在头文件“termios.h”定义。termios的数据结构如下所示:
struct& termios
c_&&&&&&&&&&&&&&
c_&&&&&&&&&&&&&
c_&&&&&&&&&&&&&
c_&&&&&&&&&&&&&
c_&&&&&&&&&&&&&&&&
c_cc[nccs];&&&&&&&&&&&
串口通信程序可分为以下几个步骤:
第一步:打开串口
&&& 调用open( )
打开串口设备,如果出错返回-1,成功则返回一个整形文件句柄,以后这个串口的操作都针对这个句柄进行。
&&& #define
usart0 /dev/ttys0
&&& #define
usart1 /dev/ttys1
open_usart(usart)
= open (“usart”,o_rdwr | o_noctty | o_nonblock);
&&&&&if(-1
&&&&&&return
&&& return
open_usart(usart0);&&&&&
第二步:串口属性配置
打开串口后需要对串口进行属性配置,即对termios结构体中的成员进行设置。串口属性应与windows下串口属性和xc164单片机串口属性保持一致,即采用相同的数据流格式、波特率和校验方式。根据是否对数据进行预处理,传输方式可分为正则方式和原始方式。为实现实时通信,将串口所对应的终端设置为原始工作方式,即不对输入和输出字符进行任何处理,不等待字符汇聚成一行,而是立即读写串口。
系统根据termios结构中c_cc数组的两个变量vmin和vtime判断是否返回输入。vmin设定满足读取功能的最低字节个数,vtime设定字节输入时间计时器。因此在操作串口是要特别注意设定这两个变量的值,尽量保证串口的通信成功率。
在termios结构中,最重要的是c_cflag,用户通过对其赋值可以实现串口波特率、字符大小、数据位、停止位、奇偶校验位等参数的设置。需要注意的是,termios结构不能初始化,需要使用位运算符在程序中进行参数设置或者清除。
set_config (int fd)
result=tcgetattr(fd, &options);
if(result&0)
&&&&&printf(“error
in tcgetattr\n”);
return (-1);
options.c_cflag &=~
options.c_cflag &=~
options.c_cflag &=~
options.c_cflag |=cs8;
options.c_iflag &=~(icanon|echo|isig);
options.c_iflag &=~(ixon|ixoff|ixany);
options.c_iflag &=~
options.c_oflag &=~
options.c_cc[vmin]=1;
options.c_cc[vtime]=l;
cfsetospeed(&options,b115200);
cfsetispeed(&options,b115200);
tcsetattr(fd,tcsanow,&options);
&&& return
经过设置后,就可用标准的文件读写命令read()和write()操作串口了。最后在退出前,用close()函数关闭串口。
3.3 linux下采用select机制读写多个串口
本文的串口读写采用了非阻塞的模式。在这种模式下要采用轮询的方法读写串口。当进程调用read函数时,设置了o_nonblock标志,那么即使串口没有数据可读,read函数也会立即返回。此时其返同值为eagain,表明串口数据未就绪。如果串口有数据可读,则read函数会读取该数据,并返回所读数据的长度,此时进程必须通过反复调用来检测是否有数据可读。如果轮询频率过低,则容易丢失数据;轮询频率过高,则占用太多处理器的处理周期。
与频繁调用非阻塞读写函数来轮询监听串口的方法相比,select调用允许用户把进程本身挂起来,同时使系统内核监听所要求的一组文件描述符的任何活动。只要确认在任何被监控的文件描述符上出现活动,select调用将返回指示该设备文件已经准备好的信息。这样就使进程能相对实时地监测到串口设备上随机的变化,而不必由进程本身去探测输入数据是否准备好。
select定义于&uintsd.h&中,函数原型如下:
select(int n,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,struct
timeval*timeout);
第1个参数n表示文件描述符集合中最大值再加1。第2个参数readfds表示可读文件描述符集合,当文件描述符的状态变成可读的时候系统就会告诉select函数返回。第3个参数writefds表示可写文件描述符集合,当文件描述符状态变成可写时系统会要求select函数返回。第4个参数exceptfds用于异常控制。struct
timeval*timeout是select的超时时间,这个参数至关重要,它可以使select处于三种状态,第一,若将null以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;第二,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;第三,timeout的值大于0,这就是等待的超时时间,即select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,将控制权交还给调用select函数的进程。
以下是本文采用select机制实现多个串口读写的程序:
&&& struct
ret=0,maxfd=0;
&&& struct
timeover.tv_sec =
0;&&&&&&&&&&&&&&&&&&
timeover.tv_usec =
10000;&&&&&&&&&&&&&
open_usart(usart0);&&&&&&&&&&&
open_usart(usart1);&&&&&&&&&&&
fd_zero(&fds);&&&&&&&&&&&&&&&&&&&
fd_set(fd1,&fds);&&&&&&&&&&&&&&&&&
fd_set(fd2,&fds);&&&&&&&&&&&&&&&&&
&&& maxfd =
(fd1&fd2)?(fd1+1):(fd2+1);&&&&
select(maxfd,fds,null,null,&timeover);&&&&
switch(ret)
perror(“select”);&&&&&
&&& printf(“time
over!”)&&&
&&&&&&if(fd_isset(fd1,&fds))&&
串口0处理函数;&&
if(fd_isset(fd2,&fds))&&
串口1处理函数;
串口通信协议
由于本系统采用非规范式输入,导致一帧数据可能分成几次接收。为了能够判断一帧数据是否接收完整,本系统制定了一套特殊的串口通信协议,如附图所示。
通信协议定义
在本系统的串口通信协议中,一帧数据包括了帧头、数据长度、数据内容和数据校验这四部分。数据长度、数据内容和数据校验为有效数据区。帧头长度为两个字节,为0xaa、0xbb。当接收到相邻的两个字节为0xaa和0xbb数据时,认为一帧数据开始。数据长度为两个字节,是数据内容的字节数和数据校验的字节数之和。数据校验采用crc16的校验方式,对数据长度和数据内容进行校验,占两个字节。数据内容的最大字节数为65533,即一帧数据最多可以传送65533个字节的数据。
待发送的数据不可避免地会出现相邻的两个字节为0xaa和0xbb的情况,如不对此中情况进行处理即发送数据,则一帧数据会被误判为两帧。针对这一问题,本系统提出了一种行之有效的解决方法。数据长度、数据内容以及数据校验这三部分数据中一旦出现0xaa,则重复一次0xaa。重复的0xaa不计入数据长度也不进行数据校验。
接收数据时进行逆向操作。首先根据接收到的两个字节判断是否为帧头,如果是则代表一帧数据开始,继续接收余下的数据,否则循环检测。在接收数据时根据数据长度判断一帧数据是否接收完毕,接收完一帧数据后进行crc校验,校验正确则进行数据处理,否则丢弃这帧数据。在有效数据区内如果出现两个相邻字节为0xaa的数据,则只取其中的一个字节。
本文设计了在基于at91rm9200硬件平台上,针对风场远程监控系统中的嵌入式linux串口通信程序,并且制定了行之有效的串口通信协议。实践证明本文针对风场远程监控系统设计的串口通信程序运行良好,数据收发正常。本文对于从事嵌入式linux下的多串口通信程序设计人员具有一定的参考价值。
李& 梅(1984-)& 女&
硕士研究生,研究方向为控制理论与控制工程。
&&& [1] 孙纪坤,张小全.
嵌入式linux系统开发技术详解——基于arm[m]. 北京:人民邮电出版社,2006.
&&& [2] 李玉波.
linux c编程[m]. 北京:清华大学出版社,2005.
&&& [3] 陈先在.
linux c函数实力速查手册[m]. 北京:人民邮电出版社,.
&&& [4] 杨宗德.
linux高级程序设计[m]. 北京:人民邮电出版社,2008.
 | 本文来自:2009年第10期“现场总线与网络技术”上
,已经被阅读过33次
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。查看: 12492|回复: 17
串口通信的数据丢失问题。
主题帖子精华
初级会员, 积分 138, 距离下一级还需 62 积分
在线时间0 小时
我用串口通信,在串口调试助手里面,以 16 进制的形式发送,接收数据,没有任何问题。但是如果以字符形式发送,只有 英文字符 和 数字字符,那么没 11 个字节就会丢失一个字节,把第11 个字节丢失了,但是,其它的字符,还能显示,包括,地11个字符以后的字符。我的程序是,电脑通过串口助手发给单片机,单片机接收到以后再原样发回电脑。
这个单步调试也没法调啊,串口助手 一下 就发完了。
工程在附件里面,请教给位高手了。
12:00 上传
点击文件名下载附件
3.55 MB, 下载次数: 330
Good?good?study,day?day?up.?立志成为牛人。
主题帖子精华
金钱121741
在线时间986 小时
自己检查一下吧。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
微信公众平台:正点原子& &
主题帖子精华
初级会员, 积分 138, 距离下一级还需 62 积分
在线时间0 小时
回复【2楼】正点原子:
---------------------------------
谢谢原子哥指点,果然要靠自己解决啊。网上查了查资料,终于解决了。ST&公司的例程,看来,也不是最好的。以后,还是向原子哥学习,多操作寄存器了。
问题在这里,
u8&USART_Putc(u8&ch)&
{&
&&USART_SendData(USART1,&(u8)&ch);&
&&while(USART_GetFlagStatus(USART1,&USART_FLAG_TC)&==&RESET)&
&&{&
&&}&
&&return&&
}&
这个问题的根本原因是复位后,TC和TXE标志位默认都是1,很多人喜欢这样写:&
&&USART_SendData(USART1,&(u8)&ch);&&
&&while(USART_GetFlagStatus(USART1,&USART_FLAG_TC)&==&RESET)&&
&&{&&
&&}&&
while在发送第一个字节时没有起到应有作用,直接跳出,接着写第二个字节,这时第一个字节还未发出,数据被破坏了。
这是,别人的回答,但是,我估计,可能发送&11&个字节后,是不是,也会出现类似复位的情况,TC和TXE标志位变成1了。
把上面修改成:
u8&USART_Putc(u8&ch)&
{&
while(USART_GetFlagStatus(USART1,&USART_FLAG_TC)&==&RESET)&
&&{&
&&}&
&&USART_SendData(USART1,&(u8)&ch);&&&
&&return&&
}&
发送之前,等待上一次发送完成,再发送下一个数据。
这样,就再没丢失过了。
Good?good?study,day?day?up.?立志成为牛人。
主题帖子精华
初级会员, 积分 138, 距离下一级还需 62 积分
在线时间0 小时
再补充一下,上面的问题,经过我研究&参考手册&后,又通过板子,实际验证,这样写也是可以的:
while&(USART_GetFlagStatus(usart,USART_FLAG_TXE)&==&RESET);
USART_SendData(usart,data); &
Good?good?study,day?day?up.?立志成为牛人。
主题帖子精华
初级会员, 积分 75, 距离下一级还需 125 积分
在线时间0 小时
回复【楼主位】fanyi:
---------------------------------
Bit&7&TXE:&Transmit&data&register&empty
This&bit&is&set&by&hardware&when&the&content&of&the&TDR&register&has&been&transferred&into&
the&shift&register.&An&interrupt&is&generated&if&&the&TXEIE&bit&=1&in&the&USART_CR1&register.&It&
is&cleared&by&a&write&to&the&USART_DR&register.
0:&Data&is&not&transferred&to&the&shift&register
1:&Data&is&transferred&to&the&shift&register)
Note:&This&bit&is&used&during&single&buffer&transmission.
Bit&6&TC:&Transmission&complete
This&bit&is&set&by&hardware&if&the&transmissi&on&of&a&frame&containing&data&is&complete&and&if&
TXE&is&set.&An&interrupt&is&generated&if&TCIE=1&in&the&USART_CR1&register.&It&is&cleared&by&a&
software&sequence&(a&read&from&the&USART_SR&register&followed&by&a&write&to&the&
USART_DR&register).&The&TC&bit&can&also&be&cleared&by&writing&a&'0'&to&it.&This&clearing&
sequence&is&recommended&only&for&multibuffer&communication.
0:&Transmission&is&not&complete
1:&Transmission&is&complete
看下这个。
复位的时候TC为1,那么写入数据寄存器之后,由于仅仅就读取SR寄存器(就是USART_GetFlagStatus这个函数),但是没有往数据寄存器中写入数据(这个写入时在读取SR寄存器之后写入的,与前一个写入不同。a&read&from&the&USART_SR&register&followed&by&a&write&to&the&
USART_DR&register:这个是手册上的。),所以就不会把TC清零。也就是说第一次写入数据的时候,由于TC是1,所以第一个while判断是没有用的。第二次写入数据的时候,就把TC清零了,之后的判断就有用了。而你改变顺序之后,就是先读SR寄存器,然后写入数据寄存器,这就把TC位清零了。
但是TXE就不同了。只要把数据写入数据寄存器,TXE就自动清零了,所以第一个while判断数据是否移入到移位寄存器就有效果了。
主题帖子精华
初级会员, 积分 138, 距离下一级还需 62 积分
在线时间0 小时
回复【5楼】Trigger:
---------------------------------
Trigger&兄果然是高手,都开始研究英文版的手册了。经过你这么一说,我再看了一下参考手册,对USART寄存器的TC,&TXE的操作过程,理解的更深了。
while&(USART_GetFlagStatus(usart,USART_FLAG_TXE)&==&RESET);&
USART_SendData(usart,data);
这两句任意交换顺序都是可以的。
我就不明白,为什么,没有人使用这个方式发生数据,而,非要去使用 TC 位,这个清零麻烦,容易出错的标志位。?????
难道仅仅是因为,官方例程是这么写的????????????
Good?good?study,day?day?up.?立志成为牛人。
主题帖子精华
初级会员, 积分 75, 距离下一级还需 125 积分
在线时间0 小时
回复【6楼】fanyi:
---------------------------------
我是菜鸟...真心是菜鸟...看英文手册是英文对中文手册不放心。
主题帖子精华
初级会员, 积分 140, 距离下一级还需 60 积分
在线时间0 小时
回复【6楼】fanyi:
---------------------------------
发十六进制数据的时候,我的也是总是丢失第一个数据,这和你的问题一样么?哪里解决啊
主题帖子精华
金钱121741
在线时间986 小时
回复【8楼】zhaojiangbao:
---------------------------------
你代码的问题.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
微信公众平台:正点原子& &
主题帖子精华
初级会员, 积分 140, 距离下一级还需 60 积分
在线时间0 小时
回复【9楼】正点原子:
---------------------------------
回复【9楼】正点原子:
---------------------------------
回复【9楼】正点原子:
---------------------------------
我改!改找!这是个进步的过程!
主题帖子精华
新手入门, 积分 28, 距离下一级还需 -8 积分
在线时间0 小时
感谢各位仁兄,小弟刚好遇到此问题,就在这里找到了答案,感谢这个这么好的平台。
主题帖子精华
新手上路, 积分 39, 距离下一级还需 11 积分
在线时间2 小时
回复【6楼】fanyi:
---------------------------------
没错,大家都根据ST例程写的
主题帖子精华
新手上路, 积分 39, 距离下一级还需 11 积分
在线时间2 小时
----本楼纯占位,待下楼讨论----
主题帖子精华
新手上路, 积分 39, 距离下一级还需 11 积分
在线时间2 小时
回复【6楼】fanyi:
&&TC&是发送完成标志,TXE是数据发送至移位寄存器的标志,用法略有区别,至于
while&(USART_GetFlagStatus(usart,USART_FLAG_TXE)&==&RESET);&
USART_SendData(usart,data);
&这个while语句在前还是在后,个人认为,ST原本目的是为了照顾引脚复用的情况,当判断while&在前判断TC或TXE的时候,这两条语句执行完毕之后,如果串口被复用被改变了输出状态,则可能导致串口内的数据无法正常送出。
如果判断TC在前,判断while&在后(st现有做法),那么就出现丢首字节的问题。
如果判断TXE在前判断while&在后,则因TXE并不代表当前传输完毕,所以串口复用的时候依然会存在可能导致尾字节无法送出的问题。
所以这个问题的解决方案要根据各人的实际使用情况来确定:
如果串口不会复用,则建议选用判断TXE标志。亦即:
USART_SendData(usart,data); &//A
while&(USART_GetFlagStatus(usart,USART_FLAG_TXE)&==&RESET); &//B
//这里选用TXE而不是TC,是因为TXE默认为1,当A执行后,TXE就立刻变成了0,所以接下来的while就起作用了。
//如果选用TC,同样TC默认是1,但是A执行后TC在某种情况下,【注意不是绝对的,同样一个printf语句,在程序的不同地方执行,有时候TC会立即变成0,有时候却不会,具体什么原因懒得查了】却不能立刻变成0,所以接下来的while语句不成立,所以就直接跳走了,所以再来第二个字节的话,就可能第一个字节就被覆盖了,从而导致丢字节
如果串口被复用则建议采用保险的做法,亦即楼主给出的解决方案,虽然该方案会浪费一点点时间和略有些麻烦。
回复【5楼】Trigger:
---------------------------------
Trigger&兄果然是高手,都开始研究英文版的手册了。经过你这么一说,我再看了一下参考手册,对USART寄存器的TC,&TXE的操作过程,理解的更深了。
while&(USART_GetFlagStatus(usart,USART_FLAG_TXE)&==&RESET);&
USART_SendData(usart,data);
这两句任意交换顺序都是可以的。
我就不明白,为什么,没有人使用这个方式发生数据,而,非要去使用&TC&位,这个清零麻烦,容易出错的标志位。?????
难道仅仅是因为,官方例程是这么写的????????????
---------------------------------
主题帖子精华
新手上路, 积分 39, 距离下一级还需 11 积分
在线时间2 小时
回复【3楼】fanyi:
回复【2楼】正点原子:
---------------------------------
谢谢原子哥指点,果然要靠自己解决啊。网上查了查资料,终于解决了。ST&公司的例程,看来,也不是最好的。(ST的例程是安全的,但有时候确实也会出点小问题)以后,还是向原子哥学习,多操作寄存器了。
问题在这里,
u8&USART_Putc(u8&ch)&
&&USART_SendData(USART1,&(u8)&ch);&
&&while(USART_GetFlagStatus(USART1,&USART_FLAG_TC)&==&RESET)&
&&return&&
这个问题的根本原因是复位后,TC和TXE标志位默认都是1,(为1的时候,表示传输完毕,这种设定没有错)很多人喜欢这样写:&
&&USART_SendData(USART1,&(u8)&ch);&&
&&while(USART_GetFlagStatus(USART1,&
---------------------------------
主题帖子精华
新手上路, 积分 39, 距离下一级还需 11 积分
在线时间2 小时
回复【6楼】fanyi:
回复【5楼】Trigger:
---------------------------------
Trigger&兄果然是高手,都开始研究英文版的手册了。经过你这么一说,我再看了一下参考手册,对USART寄存器的TC,&TXE的操作过程,理解的更深了。
while&(USART_GetFlagStatus(usart,USART_FLAG_TXE)&==&RESET);&
USART_SendData(usart,data);
这两句任意交换顺序都是可以的。(在串口没被复用的情况下,亦即串口发送数据后,引脚的设定状态没有被改变的情况下,这样写是没有问题的,而且while在前还是在后都无所谓)
我就不明白,为什么,没有人使用这个方式发生数据,而,非要去使用&TC&位,这个清零麻烦,容易出错的标志位。?????
难道仅仅是因为,官方例程是这么写的????????????
---------------------------------
主题帖子精华
初级会员, 积分 147, 距离下一级还需 53 积分
在线时间2 小时
刚碰到,标记下,以后详细看
主题帖子精华
初级会员, 积分 53, 距离下一级还需 147 积分
在线时间1 小时
mark!!!大牛分析得挺透彻的
Powered by

我要回帖

更多关于 vb串口通信程序实例 的文章

 

随机推荐