zoukankan      html  css  js  c++  java
  • poll函数和串口设置

    2015.1.24

    今天星期六,多云,早晨8:17起床的,今天是来南京起床最迟的一天,因为昨晚睡得有点迟,今天又不用上课,整个人有点放松。收拾好来到教室,教室门没有开,胡明
    也到了,其他人还在宿舍睡觉,等了10分钟还没有人来开门,就决定出去逛逛,看看南京市有什么好玩的或者特别的。9点没到从鸿运大厦出门,回来的时候10点10分左右,走了
    一个多小时,百度地图还是有点管用的,起码没有让我迷路。逛了一圈,以前觉得南京算是个大城市,应该比较繁华或者时尚之类的,但是现在完全没有这种感觉,想到以后
    的工作,我就想:此地不宜久留。如果可以,我会选择不在南京工作,这里找不到归属感,貌似工资也不好。
    因外买了过年回家的车票,对这边车站不熟,就决定今天下去去把车票取了,1:40左右走的,和张恒斌一起,来回公交车都是他刷的卡,到南京北站后发现车站挺小的,取完票就
    出来了,因为根本不需要去熟悉他,太小了。出站后就问张恒斌,要不要再这边逛逛,他说:好啊,这边要去不就去桥上(南京长江大桥:全桥长4589米,公路桥长1600多米)嘛!,我对
    到处逛还是比较有兴趣的,在杭州的时候就一个人在钱塘江复兴大桥上走了一个来回,那时候是晚上。走上桥后发现南京长江大桥挺长的,一咬牙继续走,就这样,我和张恒斌两个人
    边走边聊,桥上风挺大的,走热了的时候我把衣服脱了,但是没一会就冷了。南京这边天气污染很严重,桥上灰蒙蒙的,桥下面有很多货船,拍了一些照片,记录了一下这段旅程。回到
    宿舍4:10左右了,因为走了很长的路,所以感觉比较累,口也比较干燥,吃了个梨子后,在床上睡了会,起来的时候6点多了,清醒过后下楼吃晚饭,去排档叫了份红烧鲫鱼。有点奢侈
    了,每天吃盖浇饭有点受不了,就这样,一天过去了,晚上就该学习了!

    poll函数实现的IO多路复用!,结合昨天的select函数一起看,他们在这里实现的是相同的功能,但是poll函数效率更高!使用范围更广!

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <time.h>
    #include <errno.h>
    #include <fcnt1.h>

    #include <poll.h>

    #define MAX_BUFFER_SIZE 1024
    #define IN_FELES 3
    #define TIME_DELAY 60
    #define MAX(a, b) ((a > b) ? (a):(b))

    int main(void)
    {
    struct pollfd fds[IN_FILES];
    char buf[MAX_BUFFER_SIZE];
    int i, res, real_read, maxfd;
    /*首先按一定的权限打开另个源文件*/
    fds[0].fd = 0;
    if((fds[1].fd = open("in1",O_RDONLY | O_NONBLOCK)) < 0)
    {
    printf("open in1 error ");
    return 1;
    }

    if((fds[2].fd = open("in2",O_RDONLY | O_NONBLOCK)) < 0)
    {
    printf("open in2 error ");
    return 1;
    }

    for(i = 0; i < IN_FILES; i++)
    {
    fds[i].events = POLLIN;
    }
    /*循环测试该文件描述符是否准备就绪,并调用select函数对相关文件描述符做对应操作*/
    while(fds[0].events || fds[1].events || fds[2].events)
    {
    if(poll(fds,IN_FILES,0) < 0)
    {
    printf("poll error ");
    return 1;

    }

    for(i = 0; i < IN_FILES; i++)
    {
    if(fds[i].revents)
    {
    memset(buf ,0, MAX_BUFFER_SIZE);
    real_read = read(fds(fds[i].fd,buf,MAX_BUFFER_SIZE);

    if(real_read < 0)
    {
    if(errno != EAGAIN)
    {
    return 1;
    }
    }

    else if(!real_read)
    {
    close(fds[i].fd);
    fds[i].events = 0;
    }
    else
    {
    if(i == 0)
    {
    if((buf[0] == 'q') || (buf[0] == 'Q'))
    {
    return 1;
    }
    }
    else
    {
    buf[real_read] = '';
    printf("%s,buf");
    }
    }
    }
    }
    }
    exit(0);
    }

    串口设置详解:

    串口设置主要是设置struct termios结构体的各成员值:

    #include <termios.h>
    struct termios
    {
    unsigned short c_iflag; //输入模式标志
    unsigned short c_oflag; 输出模式标志
    unsigned short c_cflag; //控制模式标志
    unsigned short c_lglag; 本地模式标志
    unsigned char c_line; 线路规程
    unsigned char c_cc[NCC]; //控制特性
    speed_t c_ispeed; 输入速度
    speed_t c_ospeed; 输出速度
    }

    不能对c_cflag成员初始化,而要将其通过“与”“或”操作使用其中的某些选项
    输入模式标志c_iflag用于控制端口接收端的字符输入处理。

    下面详细讲解设置串口属性的基本流程:

    1.保存原先串口的配置:

    if(tcgetattr(fd,&old_cfg) != 0)
    {
    perror("tvgetattr");
    return -1;
    }

    2.激活选项:CLOCAL和CREAD分别用于本地连接和接受使能,用位掩码

    newtio.c_cflag |= CLOCAL | CREAD;

    调用dfmakeraw()函数将终端设置为原始模式

    cfmakeraw(&new_cfg);

    3.设置波特率;设置波特率有专门的函数,
    cfsetispeed(&new_cfg,B115200);
    cfsetospeed(&new_cfg,B115200);
    一般的,用户需要将终端的输入和输出的波特率设置成一样的,这几个函数在成功时返回0,失败时返回-1.

    4.设置字符大小,用位掩码:一般首先清除数据位中的位掩码再重新安要求设置

    new_cfg.c_cflag &= ~CSIZE; 用数据位掩码清空数据位设置
    new_cfg.c_cflag |= CS8;

    5.设置奇偶校验位:首先激活c_cflag中的校验位使能标志PARENB和是否要进行偶校验,同时还要
    激活c_iflag中的对于输入数据的奇偶校验使能INPCK;

    new_cfg.c_cflag |= (PARODD | PARENB);
    new_cfg.c_iflag |= INPCK;

    使能偶校验时,代码如下:
    new_cfg.c_cflag |= PARENB
    new_cfg.c_cflag &= ~PARODD 清除偶校验标志,则配置为奇校验
    new_cfg.c_iflag |= INPCK;

    6.设置停止位

    若停止位为一个,则清除CSTOPB,如停止位为两个,则激活CSTOPB.以下分别是停止位为一个和两个比特时的代码
    new_cfg.c_cflag &= ~CSTOPB; 将停止位设置为一个比特
    new_cfg.c_cflag |= CSTOPB; 将停止位设置为两个比特

    7.设置最少字符和等待时间:
    在对就收字符和字符时间没有特别要求的情况下,可以将其设置为0,则在任何情况下read()函数立即返回:
    new_cfg.c_cc[VTIME] = 0;
    new_cfg.c_cc[VMIN] = 0;

    8.清除串口缓冲:
    int tcdrain(int fd); 使程序阻塞,直到输出缓冲区的数据全部发送完毕
    int tcflow(int fd,int action); 用于暂停或重新开始输出
    int tcflush(int fd,int queue_selectot); 用于清空输入、输出缓冲区

    9.激活配置
    tcsetattr(int fd, int optional_actions, const struct termios *termios_p);

    函数调用如下:
    if((tcsetattr(fd,TCSANOW,&new_cfg)) != 0)
    {
    perror("tcsetattr");
    return -1;
    }

    **********************************************************************************************************************************************************
    **********************************************************************************************************************************************************
    **********************************************************************************************************************************************************

  • 相关阅读:
    ASP.NET Web API 控制器执行过程(一)
    ASP.NET Web API 控制器创建过程(二)
    ASP.NET Web API 控制器创建过程(一)
    ASP.NET Web API WebHost宿主环境中管道、路由
    ASP.NET Web API Selfhost宿主环境中管道、路由
    ASP.NET Web API 管道模型
    ASP.NET Web API 路由对象介绍
    ASP.NET Web API 开篇示例介绍
    ASP.NET MVC 视图(五)
    ASP.NET MVC 视图(四)
  • 原文地址:https://www.cnblogs.com/cnlg/p/4246867.html
Copyright © 2011-2022 走看看