zoukankan      html  css  js  c++  java
  • [基础|理论|实验]linux下的RS232串口通讯

    1.Linux把所有的外部终端设备都当做文件进行操作,通常分为块设备、字符设备、网络设备。串口是属于字符设备,是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用。常用的串口是 RS-232-C 接口,传输距离在码元畸变小于 4% 的情况下传输电缆长度应为 50 英尺。通常的操作步骤为"打开串口文件"->"设置串口参数"->"读写串口操作"->"关闭串口文件"。

    2.详解:

        需要头文件信息:

     1  
     2 #include     <stdio_ext.h>
     3 #include     <stdio.h>      /*标准输入输出定义*/
     4 #include     <stdlib.h>     /*标准函数库定义*/
     5 #include     <unistd.h>     /*Unix 标准函数定义*/
     6 #include     <sys/types.h>  /*系统类型定义*/
     7 #include     <sys/stat.h>   /*系统状态定义*/
     8 #include     <fcntl.h>      /*文件控制定义*/
     9 #include     <termios.h>    /*PPSIX 终端控制定*/
    10 #include     <errno.h>      /*错误号定义/

        打开串口:

    linux下的串口文件通常是位于/dev目录下,串口1为/dev/ttyS0,串口2为/dev/ttyS1,以此类推。其它终端还有usb0,py0等。

    1     fd = open("/dev/ttyS0",O_RDWR| O_NOCTTY | O_NDELAY);
    2     if(-1 == fd)
    3     {
    4         perror("can not open serial port");
    5 
    6     }

         设置串口:

    最基本的设置串口包括波特率设置,效验位和停止位设置。主要是设置termios结构体的成员函数。
     1 struct termios
     2   {
     3     tcflag_t c_iflag;        /* input mode flags */
     4     tcflag_t c_oflag;        /* output mode flags */
     5     tcflag_t c_cflag;        /* control mode flags */
     6     tcflag_t c_lflag;        /* local mode flags */
     7     cc_t c_line;            /* line discipline */
     8     cc_t c_cc[NCCS];        /* control characters */
     9     speed_t c_ispeed;        /* input speed */
    10     speed_t c_ospeed;        /* output speed */
    11 #define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
    12 #define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
    13   };
    波特率设置
    1 struct  termios Opt;
    2 tcgetattr(fd, &Opt);         /*获得文件句柄的termios结构*/
    3 cfsetispeed(&Opt,B2400);     /*设置为2400Bps,通常串口IO是一致的波特率*/
    4 cfsetospeed(&Opt,B2400);
    5 tcsetattr(fd,TCANOW,&Opt);    /*设置文件句柄的termios结构,TCANOW为设置立即生效*/ 

     设置数据位

    1 options.c_cflag &= ~CSIZE; 
    2 option.c_cflag |= CS8; /*设置为8位数据位,其它如CS5->CS7*/

     设置校验位

     1 option.c_cflag |= PARENB; /*设置校验位使能*/
     2 option.c_cflag |= PARODD; /*设置为奇校验*/
     3 //option.c_cflag &= ~PARODD; /*设置为偶校验*/
     4 
     5 //以下设置仅限于linux系统
     6 option.c_cflag |= CMSPAR;  
     7 /*设置space校验,奇偶校验位恒为0*/
     8 //option.c_cflag &= ~PARODD;或者是直接没有设置 
     9 /*设置mark校验,奇偶校验位恒为1*/
    10 //option.c_cflag |= PARODD;

     设置停止位

    1 option.c_cflag &= ~CSTOPB; //一位停止位
    2 //option.c_cflag |= CSTOPB; //两位停止位

     关闭文件

    1 close(fd);

    //增加关于RAW原始通信(非规范模式)详解

    在使用非规范模式的时候,需要关闭c_lflag字段的ICANON标志就会使得终端出于非规范模式,在这个模式下,接受到的数据不是成行的。故这里区别与上面说明,需要使用c_cc数组的两个变量:MIN和TIME,数组元素名下标为VMIN和VTIME。

    VTIME定义要求等待的时间(百毫米,通常是unsigned char变量),而VMIN定义了要求等待的最小字节数(相比之下,read函数的第三个参数指定了要求读的最大字节数)。
    如果VTIME=0,VMIN=要求等待读取的最小字节数,read必须在读取了VMIN个字节的数据或者收到一个信号才会返回。
    如果VTIME=时间量,VMIN=0,不管能否读取到数据,read也要等待VTIME的时间量。
    如果VTIME=时间量,VMIN=要求等待读取的最小字节数,那么将从read读取第一个字节的数据时开始计时,并会在读取到VMIN个字节或者VTIME时间后返回。
    如果VTIME=0,VMIN=0,不管能否读取到数据,read都会立即返回。

    另外要想以上设置生效,还需要在打开文件的时候,不要指定O_NDELAY或者是O_NONBLOCK参数。

     1 #include     <stdio.h>      /*标准输入输出定义*/
     2 #include     <stdlib.h>     /*标准函数库定义*/
     3 #include     <unistd.h>     /*Unix 标准函数定义*/
     4 #include     <sys/types.h>     /*系统类型定义*/
     5 #include     <sys/stat.h>         /*系统状态定义*/
     6 #include     <fcntl.h>      /*文件控制定义*/
     7 #include     <termios.h>    /*PPSIX 终端控制定义*/
     8 #include     <errno.h>      /*错误号定义*/
     9 
    10 int main(void)
    11 {
    12 
    13     
    14     int fd;
    15     struct termios option;
    16     int status = 0;
    17     char buff[512];//这样定义buff的内容是随机数
    18     int num = 0;
    19 
    20     fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY );
    21     if (-1 == fd)
    22     {
    23         perror("can not open serial port");
    24 
    25     }
    26     tcgetattr(fd, &option);
    27     option.c_cflag |= CLOCAL; //保证程序不会成为端的占有者
    28     option.c_cflag |= CREAD; //使端口能读取输入的数据
    29     cfsetispeed(&option, B2400);
    30     cfsetospeed(&option, B2400);
    31 
    32     option.c_cflag &= ~CSIZE;
    33     option.c_cflag |= CS8;
    34     option.c_cflag |= PARENB;
    35     //option.c_cflag &= ~PARODD;
    36 
    37     option.c_cflag |= PARODD; //奇校验
    38     option.c_cflag |= CMSPAR; //标记校验位
    39     option.c_cflag &= ~CSTOPB; //一位停止位
    40     option.c_iflag |= INPCK; /* Disnable parity checking */
    41 
    42     //    一下是添加测试
    43     ///////////////////////////////////////////////////////////////////////////////////
    44 
    45     option.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    46 
    47     option.c_oflag &= ~OPOST;
    48     option.c_oflag &= ~(ONLCR | OCRNL); //添加的
    49 
    50     option.c_iflag &= ~(ICRNL | INLCR);
    51     option.c_iflag &= ~(IXON | IXOFF | IXANY); //添加的
    52     ///////////////////////////////////////////////////////////////////////////////////////
    53 
    54     option.c_cc[VTIME] = 0//设置超时
    55     option.c_cc[VMIN] = 1//设置最小字节数
    56     tcflush(fd, TCIFLUSH);
    57 
    58     
    59     status = tcsetattr(fd, TCSANOW, &option);
    60     if (-1 == status)
    61     {
    62         perror("tcsetattr false");
    63     }
    64  
    65     write(fd, "\x02"sizeof("\x02"));
    66     num = read(fd, buff, 512);
    67     printf("%d\n", num);
    68     printf("%d\n", errno);
    69     printf("%x", buff[0]);//注意这里,如果读取不成功,将是随机值。
    70 }
    71     
     

    作者:xiaoxia

    出处:http://cnblogs.com/xiaoxia

    本文遵从GNU 的自由文档许可证(Free Document License)的条款,欢迎转载、修改、散布。 

  • 相关阅读:
    自己常用的数据库操作语句
    我被SQL注入撞了一下腰
    分页
    reset.css
    创建对象的多种方式
    js 数组去重
    学习JS防抖【节流】
    localStorage.js
    vue 项目移动端使用淘宝自适应插件 环境配置
    Vue项目搭建
  • 原文地址:https://www.cnblogs.com/xiaoxia/p/2095448.html
Copyright © 2011-2022 走看看