您的位置:首页 > 运维架构 > Linux

[基础|理论|实验]linux下的RS232串口通讯

2011-07-01 13:43 465 查看
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 终端控制定*/

#include <errno.h> /*错误号定义/

    打开串口:

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

fd = open("/dev/ttyS0",O_RDWR| O_NOCTTY | O_NDELAY);

if(-1 == fd)

{

perror("can not open serial port");

}

    设置串口:

最基本的设置串口包括波特率设置,效验位和停止位设置。主要是设置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 */

speed_t c_ospeed; /* output speed */

#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1

#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1

};

波特率设置

struct termios Opt;

tcgetattr(fd, &Opt); /*获得文件句柄的termios结构*/

cfsetispeed(&Opt,B2400); /*设置为2400Bps,通常串口IO是一致的波特率*/

cfsetospeed(&Opt,B2400);

tcsetattr(fd,TCANOW,&Opt); /*设置文件句柄的termios结构,TCANOW为设置立即生效*/

设置数据位

options.c_cflag &= ~CSIZE;
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*/
//option.c_cflag |= PARODD; 设置停止位

option.c_cflag &= ~CSTOPB; //一位停止位
//option.c_cflag |= CSTOPB; //两位停止位 关闭文件

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
int main(void)
{

int fd;
struct termios option;
int status = 0;
char buff[512];//这样定义buff的内容是随机数
int num = 0;

fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY );
if (-1 == fd)
{
perror("can not open serial port");

}
tcgetattr(fd, &option);
option.c_cflag |= CLOCAL; //保证程序不会成为端的占有者
option.c_cflag |= CREAD; //使端口能读取输入的数据
cfsetispeed(&option, B2400);
cfsetospeed(&option, B2400);

option.c_cflag &= ~CSIZE;
option.c_cflag |= CS8;
option.c_cflag |= PARENB;
//option.c_cflag &= ~PARODD;

option.c_cflag |= PARODD; //奇校验
option.c_cflag |= CMSPAR; //标记校验位
option.c_cflag &= ~CSTOPB; //一位停止位
option.c_iflag |= INPCK; /* Disnable parity checking */

// 一下是添加测试
///////////////////////////////////////////////////////////////////////////////////

option.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

option.c_oflag &= ~OPOST;
option.c_oflag &= ~(ONLCR | OCRNL); //添加的

option.c_iflag &= ~(ICRNL | INLCR);
option.c_iflag &= ~(IXON | IXOFF | IXANY); //添加的
///////////////////////////////////////////////////////////////////////////////////////

option.c_cc[VTIME] = 0; //设置超时
option.c_cc[VMIN] = 1; //设置最小字节数
tcflush(fd, TCIFLUSH);

status = tcsetattr(fd, TCSANOW, &option);
if (-1 == status)
{
perror("tcsetattr false");
}

write(fd, "\x02", sizeof("\x02"));
num = read(fd, buff, 512);
printf("%d\n", num);
printf("%d\n", errno);
printf("%x", buff[0]);//注意这里,如果读取不成功,将是随机值。
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: