串口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;

  • 5
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值