串口VMIN VTIME 详解
原文地址:
以前跟着做过VxWorks的开发,主要通信方式是串口,因为底层BSP包已经做好了,串口通信非常简单。后来接触Linux,在一块OK6410上跑Linux串口通信,才发现原来天真的以为甚是简单的串口变得如此的不简单。
#include <termios.h>
1、串口的操作
1.1打开:fd = open("/dev/ttySAC1", O_RDWR | O_NOCTTY | O_NDELAY);
O_RDWR 读写方式打开;
O_NOCTTY 不允许进程管理串口(不太理解,一般都选上);
O_NDELAY 非阻塞(默认为阻塞,打开后也可以使用fcntl()重新设置)
1.2写入:n = write(fd, "linux", 5);
n实际写入字节数;
1.3读取:res = read(fd,buf,len);
res 读取的字节数;
1.4设置:fcntl(fd, F_SETFL, FNDELAY); //非阻塞
fcntl(fd, F_SETFL, 0); // 阻塞
1.5关闭:close(fd);
2、串口配置
struct termios options; // 串口配置结构体
tcgetattr(fd,&options); //获取当前设置
bzero(&options,sizeof(options));
options.c_cflag |= B115200 | CLOCAL | CREAD; // 设置波特率,本地连接,接收使能
options.c_cflag &= ~CSIZE; //屏蔽数据位
options.c_cflag |= CS8; // 数据位为 8 ,CS7 for 7
options.c_cflag &= ~CSTOPB; // 一位停止位, 两位停止为 |= CSTOPB
options.c_cflag &= ~PARENB; // 无校验
//options.c_cflag |= PARENB; //有校验
//options.c_cflag &= ~PARODD // 偶校验
//options.c_cflag |= PARODD // 奇校验
options.c_cc[VTIME] = 0; // 等待时间,单位百毫秒 (读)。后有详细说明
options.c_cc[VMIN] = 0; // 最小字节数 (读)。后有详细说明
tcflush(fd, TCIOFLUSH); // TCIFLUSH刷清输入队列。
TCOFLUSH刷清输出队列。
TCIOFLUSH刷清输入、输出队列。
tcsetattr(fd, TCSANOW, &options); // TCSANOW立即生效;
TCSADRAIN:Wait until everything has been transmitted;
TCSAFLUSH:Flush input and output buffers and make the change
3、VTIME 和 VMIN
VTIME 定义要求等待的零到几百毫秒的值(通常是一个8位的unsigned char变量)。
VMIN 定义了要求等待的最小字节数, 这个字节数可能是0。
只有设置为阻塞时这两个参数才有效,仅针对于读操作。
说起来比较复杂,举个例子吧,设置为阻塞状态,写操作未进行实验,这里仅讨论读操作,
read(fd,&buf,8); // 读串口
3.1
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 0;
VMIN = 0,当缓冲区字节数 >= 0 时进行读操作,实际上这时读串口操作并未被阻塞,因为条件始终被满足。
3.2
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 1;
VMIN = 1,当缓冲区字节数 >= 1 时进行读操作,当没有数据时读串口操作被阻塞。
3.3
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 4;
VMIN = 4,当缓冲区字节数 >= 4
时进行读操作,否则读串口操作被阻塞。每次读出的最大字节数由read函数中第三个参数决定。直到缓冲区剩下的数据< read 第三个参数
并且< 4 (如果这时read第三参数为 1
则进行4次读操作直至读完缓冲区,如read第三参数为2,连续进行读操作,直至缓冲区空或还剩一个字符)。没有设置VTIME,剩下的字符没有确定的期限,直到下次满足读条件的时候才被读出。
----------------------------------考虑VTIME-----------------------------
3.4
options.c_cc[VTIME] = 10; //单位百毫秒
options.c_cc[VMIN] = 4;
同3.3的区别就是,没满足条件或读缓冲区中剩下的数据会在1秒(10百毫秒)后读出。另外特别注意的是当设置VTIME后,如果read第三个参数小于VMIN ,将会将VMIN 修改为read的第三个参数,即使用read(fd,&buf,2);,以上设置变为:
options.c_cc[VTIME] = 10;
options.c_cc[VMIN] = 2;
ptty->ntm.c_cc[VTIME] = 0; // inter-character timer unused
ptty->ntm.c_cc[VMIN] = 1; // blocking read until 1 chars received
控制符VTIME和VMIN之间有着复杂的关系。VTIME定义要求等待的零到几百毫秒的时间量(通常是一个8位的unsigned char变量,取值不能大于cc_t)。VMIN定义了要求等待的最小字节数(不是要求读的字节数——read()的第三个参数才是指定要求读的最大字节数),这个字节数可能是0。
l 如果VTIME取0,VMIN定义了要求等待读取的最小字节数。函数read()只有在读取了VMIN个字节的数据或者收到一个信号的时候才返回。
l 如果VMIN取0,VTIME定义了即使没有数据可以读取,read()函数返回前也要等待几百毫秒的时间量。这时,read()函数不需要像其通常情况那样要遇到一个文件结束标志才返回0。
l 如果VTIME和VMIN都不取0,VTIME定义的是当接收到第一个字节的数据后开始计算等待的时间量。如果当调用read函数时可以得到数据,计时器马上开始计时。如果当调用read函数时还没有任何数据可读,则等接收到第一个字节的数据后,计时器开始计时。函数read可能会在读取到VMIN个字节的数据后返回,也可能在计时完毕后返回,这主要取决于哪个条件首先实现。不过函数至少会读取到一个字节的数据,因为计时器是在读取到第一个数据时开始计时的。
l 如果VTIME和VMIN都取0,即使读取不到任何数据,函数read也会立即返回。同时,返回值0表示read函数不需要等待文件结束标志就返回了。
陀螺仪实例结果:
options.c_cc[VTIME] = 1;
options.c_cc[VMIN] = 1;
和
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 1;
卡死,等待
options.c_cc[VTIME] = 1;
options.c_cc[VMIN] = 0; 等待VTIME后,read返回0
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 0; 相当于非阻塞,read立即返回0。
options.c_oflag &= ~(ONLCR | OCRNL);
options.c_iflag &= ~(ICRNL | INLCR);
options.c_iflag &= ~(IXON | IXOFF | IXANY);
c++ c++ python后c++ c++
cout<<"options.c_cflag1:"<<options.c_cflag<<endl; 3261 --> 7346 7346 --> 7346
cout<<"options.c_oflag1:"<<options.c_oflag<<endl; 5 --> 0 4 --> 0
cout<<"options.c_iflag1:"<<options.c_iflag<<endl; 1280 --> 0 0 --> 0
cout<<"options.c_lflag1:"<<options.c_lflag<<endl; 35387 --> 35360 0 --> 0
串口VMIN VTIME 详解的更多相关文章
- C#串口通信程序详解
C#串口通信程序详解 摘要:创建C#串口通信程序需要注意什么呢?创建C#串口通信程序的步骤是什么?那么本文就向你详细介绍创建C#串口通信程序集体的内容. 在.NET平台下创建C#串口通信程序,.NET ...
- 创建C#串口通信程序详解
在.NET平台下创建C#串口通信程序,.NET 2.0提供了串口通信的功能,其命名空间是System.IO.Ports.这个新的框架不但可以访问计算机上的串口,还可以和串口设备进行通信.我们将使用标准 ...
- STM32 串口功能 库函数 详解和DMA 串口高级运用(转载)
数据传输时要从支持那些相关的标准?传输的速度?什么时候开始?什么时候结束?传输的内容?怎样防止通信出错?数据量大的时候怎么弄?硬件怎么连接出发,当然对于stm32还要熟悉库函数的功能 具起来rs232 ...
- ESP8266串口WiFi扩展板详解
产品简介 ESP8266串口WiFi扩展板是深圳四博智联科技有限公司开发的一款基于乐鑫ESP8266的超低功耗的UART-WiFi模块,兼容Arduino UNO.Mega等标准主板,可以方便地进行二 ...
- linux 串口通信 编程详解
计算机串口的引脚说明 序号 信号名称 符号 流向 功能 3 发送数据 TXD DTE→DCE DTE发送串行数据 2 接收数据 RXD DTE←DCE DTE 接收串行数据 7 请求发送 RTS DT ...
- STM32 Bootloader基于ymodem传输协议串口IAP升级详解
硬件:stm32f103cbt6 软件:STM32F10x_StdPeriph_Lib_V3.5.0 文章目录 1 预备知识 2 Bootloader 2.1 启动流程 2.2 校验跳转地址是否有效 ...
- Linux串口编程详解(转)
串口本身,标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口曾经被广泛用于连接计算机和终端设备和各种外部设备.虽然以太网接口和USB接口也是以一个串行流进行数据传送的,但是串口连接 ...
- Linux串口c_cc[VTIME]和c_cc[VMIN]属性设置的作用
Linux串口c_cc[VTIME]和c_cc[VMIN]属性设置的作用 在串口编程模式下,open未设置O_NONBLOCK或O_NDELAY的情况下. c_cc[VTIME]和c_cc[VMIN] ...
- 串口通信中ReadFile和WriteFile的超时详解!
源:串口通信中ReadFile和WriteFile的超时详解! 在用ReadFile和WriteFile读写串行口时,需要考虑超时问题.如果在指定的时间内没有读出或写入指定数量的字符,那么ReadFi ...
随机推荐
- 【nginx】 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream
2013/10/22 20:05:49 [error] 12691#0: *6 FastCGI sent in stderr: "Primary script unknown" w ...
- 有关git clone 下载速度变慢的解决方法
使用提示:请注意一下,以下方法是在搭有梯子的情况下进行的,也就是说在有梯子的情况下,下载速度始终很慢,使用了以下方法用梯子下载达到正常速度,并没有尝试修复过后不用梯子下载. 所以,如果使用了以下方法, ...
- static关键字所导致的内存泄漏问题
大家都知道内存泄漏和内存溢出是不一样的,内存泄漏所导致的越来越多的内存得不到回收的失手,最终就有可能导致内存溢出,下面说一下使用staitc属性所导致的内存泄漏的问题. 在dalvik虚拟机中,sta ...
- Tomcat Bug记录
1.问题:org.apache.tiles.request.render.CannotRenderException: ServletException including path '/WEB-IN ...
- sqlmanagementstudio2008下载地址
http://big.wy119.com/sqlmanagementstudio2008_x86_chs.zip
- 带权并查集:HDU3172-Virtual Friends
Virtual Friends Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
- cf 1020 C
C. Elections time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- 【原创】关于高版本poi autoSizeColumn方法异常的情况
之前使用的3.9版本,autoSizeColumn方法一切正常,现在切换到了3.15版本这个方法就出先了问题,问题如下,无法自动追踪所有的列. Exception in thread "ma ...
- TCP缓冲区大小及限制
这个问题在前面有的部分已经涉及,这里在重新总结下.主要参考UNIX网络编程. (1)数据报大小IPv4的数据报最大大小是65535字节,包括IPv4首部.因为首部中说明大小的字段为16位.IPv6的数 ...
- Oracle 表空间的日常维护与管理
目录 Oracle 表空间的日常维护与管理 1.创建数据表空间 2.创建临时表空间 3.创建 UNDO 表空间 4.表空间的扩展与修改大小 5.表空间重命名 6.表空间的删除 7.更改表空间的读写模式 ...