[基础|理论|实验]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      

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/xiaoxia/archive/2011/07/01/2095448.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值