当前位置:文档之家› linux串口编程参数配置详解

linux串口编程参数配置详解

linux串口编程参数配置详解1.linux串口编程需要的头文件#include <stdio.h> //标准输入输出定义#include <stdlib.h> //标准函数库定义#include <unistd.h> //Unix标准函数定义#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h> //文件控制定义#include <termios.h> //POSIX中断控制定义#include <errno.h> //错误号定义2.打开串口串口位于/dev中,可作为标准文件的形式打开,其中:串口1 /dev/ttyS0串口2 /dev/ttyS1代码如下:int fd;fd = open(“/dev/ttyS0”, O_RDWR);if(fd == -1){Perror(“串口1打开失败!”);}//else//fcntl(fd, F_SETFL, FNDELAY);除了使用O_RDWR标志之外,通常还会使用O_NOCTTY和O_NDELAY这两个标志。

O_NOCTTY:告诉Unix这个程序不想成为“控制终端”控制的程序,不说明这个标志的话,任何输入都会影响你的程序。

O_NDELAY:告诉Unix这个程序不关心DCD信号线状态,即其他端口是否运行,不说明这个标志的话,该程序就会在DCD信号线为低电平时停止。

3.设置波特率最基本的串口设置包括波特率、校验位和停止位设置,且串口设置主要使用termios.h头文件中定义的termios结构,如下:struct termios{tcflag_t c_iflag; //输入模式标志tcflag_t c_oflag; //输出模式标志tcflag_t c_cflag; //控制模式标志tcflag_t c_lflag; //本地模式标志cc_t c_line; //line disciplinecc_t c_cc[NCC]; //control characters}代码如下:int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300, B384 00, B19200, B9600, B4800, B2400, B1200, B300, };int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9 600, 4800, 2400, 1200, 300, };void SetSpeed(int fd, int speed){int i;struct termios Opt; //定义termios结构if(tcgetattr(fd, &Opt) != 0){perror(“tcgetattr fd”);return;}for(i = 0; i < sizeof(speed_arr) / sizeof(int); i++){if(speed == name_arr[i]){tcflush(fd, TCIOFLUSH);cfsetispeed(&Opt, speed_arr[i]);cfsetospeed(&Opt, speed_arr[i]);if(tcsetattr(fd, TCSANOW, &Opt) != 0){perror(“tcsetattr fd”);return;}tcflush(fd, TCIOFLUSH);}}}注意tcsetattr函数中使用的标志:TCSANOW:立即执行而不等待数据发送或者接受完成。

TCSADRAIN:等待所有数据传递完成后执行。

TCSAFLUSH:Flush input and output buffers and make the change 4.设置数据位、停止位和校验位以下是几个数据位、停止位和校验位的设置方法:(以下均为1位停止位)8位数据位、无校验位:Opt.c_cflag &= ~PARENB;Opt.c_cflag &= ~CSTOPB;Opt.c_cflag &= ~CSIZE;Opt.c_cflag |= CS8;7位数据位、奇校验:Opt.c_cflag |= PARENB;Opt.c_cflag |= PARODD;Opt.c_cflag &= ~CSTOPB;Opt.c_cflag &= ~CSIZE;Opt.c_cflag |= CS7;7位数据位、偶校验:Opt.c_cflag |= PARENB;Opt.c_cflag &= ~PARODD;Opt.c_cflag &= ~CSTOPB;Opt.c_cflag &= ~CSIZE;Opt.c_cflag |= CS7;7位数据位、Space校验:Opt.c_cflag &= ~PARENB;Opt.c_cflag &= ~CSTOPB;Opt.c_cflag &= ~CSIZE;Opt.c_cflag |= CS7;代码如下:int SetParity(int fd, int databits, int stopbits, int parity) {struct termios Opt;if(tcgetattr(fd, &Opt) != 0){perror("tcgetattr fd");return FALSE;}Opt.c_cflag |= (CLOCAL | CREAD); //一般必设置的标志switch(databits) //设置数据位数{case 7:Opt.c_cflag &= ~CSIZE;Opt.c_cflag |= CS7;break;case 8:Opt.c_cflag &= ~CSIZE;Opt.c_cflag |= CS8;berak;default:fprintf(stderr, "Unsupported data size.\n");return FALSE;}switch(parity) //设置校验位{case 'n':case 'N':Opt.c_cflag &= ~PARENB; //清除校验位Opt.c_iflag &= ~INPCK; //enable parity checkingbreak;case 'o':case 'O':Opt.c_cflag |= PARENB; //enable parityOpt.c_cflag |= PARODD; //奇校验Opt.c_iflag |= INPCK //disable parity checkingbreak;case 'e': case 'E': Opt.c_cflag |= PARENB; //enable parity Opt.c_cflag &= ~PARODD; //偶校验 Opt.c_iflag |= INPC K; //disable pairty checking break; case 's': case 'S': Op t.c_cflag &= ~PARENB; //清除校验位 Opt.c_cflag &= ~CSTOPB; / /?????????????? Opt.c_iflag |= INPCK; //disable pairty checking break; default: fprintf(stderr, "Unsupported parity.\n"); retu rn FALSE; } switch(stopbits) //设置停止位 { case 1: Opt. c_cflag &= ~CSTOPB; break; case 2: Opt.c_cflag |= CSTOPB; break; default: fprintf(stderr, "Unsupported stopbits.\n"); re turn FALSE; } opt.c_cflag |= (CLOCAL | CREAD); opt.c_lflag &= ~(ICAN ON | ECHO | ECHOE | ISIG); opt.c_oflag &= ~OPOST; opt.c_oflag &= ~ (ONLCR | OCRNL); //添加的 opt.c_iflag &= ~(ICRNL | INLCR); opt.c_ifla g &= ~(IXON | IXOFF | IXANY); //添加的 tcflush(fd, TCIFLUSH); Opt.c_cc [VTIME] = 0; //设置超时为15sec Opt.c_cc[VMIN] = 0; //Update the O pt and do it now if(tcsetattr(fd, TCSANOW, &Opt) != 0) { perror("tcse tattr fd"); return FALSE; } return TRUE; }5.某些设置项在第四步中我们看到一些比较特殊的设置,下面简述一下他们的作用。

c_cc数组的VSTART和VSTOP元素被设定成DC1和DC3,代表ASCII标准的XON和XOFF字符,如果在传输这两个字符的时候就传不过去,需要把软件流控制屏蔽,即:Opt.c_iflag &= ~ (IXON | IXOFF | IXANY);有时候,在用write发送数据时没有键入回车,信息就发送不出去,这主要是因为我们在输入输出时是按照规范模式接收到回车或换行才发送,而更多情况下我们是不必键入回车或换行的。

此时应转换到行方式输入,不经处理直接发送,设置如下:Opt.c_lflag &= ~ (ICANON | ECHO | ECHOE | ISIG);还存在这样的情况:发送字符0X0d的时候,往往接收端得到的字符是0X0a,原因是因为在串口设置中c_iflag和c_oflag中存在从NL-CR和CR-NL的映射,即串口能把回车和换行当成同一个字符,可以进行如下设置屏蔽之:Opt.c_iflag &= ~ (INLCR | ICRNL | IGNCR);Opt.c_oflag &= ~(ONLCR | OCRNL);注意:控制符VTIME和VMIN之间有复杂的关系。

相关主题