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;
    }

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

  • 相关阅读:
    第二次作业——评分!
    第一次点评!
    神经网络测试:利用分块patch输入的弊端
    利用分块进行网络输入测试
    python 用filter求解素数
    英语语法
    git clone 下载出现Time out
    路由转发
    获取用户密码
    后门维持
  • 原文地址:https://www.cnblogs.com/cnlg/p/4246867.html
Copyright © 2011-2022 走看看