linux C串口常规设置参考

据通信的基本方式可分为并行通信与串行通信两种。· 并行通信是指利用多条数据传输线将一个资料的各位同时传送。它的特点是传输速度快,适用于短距离通信,但要求传输速度较高的应用场合。· 串行通信是指利用一条传输线将资料一位位地顺序传送。特点是通信线路简单,利用简单的线缆就可实现通信,降低成本,适用于远距离通信,但传输速度慢的应用场合。串口设置详解本节主要讲解设置串口的主要方法。如前所述,设置串口中最基本的包括波特率设置,校验位和停止位设置。串口的设置主要是设置struct termios结构体的各成员值,如下所示:#includestruct termio{ unsigned short c_iflag; /* 输入模式标志 */ unsigned short c_oflag; /* 输出模式标志 */ unsigned short c_cflag; /* 控制模式标志*/ unsigned short c_lflag; /*本地模式标志 */ unsigned char c_line; /* line discipline */ unsigned char c_cc[NCC]; /* control characters */};在这个结构中最为重要的是c_cflag,通过对它的赋值,用户可以设置波特率、字符大小、数据位、停止位、奇偶校验位和硬件流控等。另外c_iflag 和c_cc 也是比较常用的标志。在此主要对这3 个成员进行详细说明。 c_cflag支持的常量名称CBAUD 波特率的位掩码B0 0波特率(放弃DTR)B1800 1800波特率B2400 2400波特率B4800 4800波特率B9600 9600波特率B19200 19200波特率B38400 38400波特率B57600 57600波特率B115200 115200波特率EXTA 外部时钟率EXTB 外部时钟率CSIZE 数据位的位掩码CS5 5个数据位CS6 6个数据位CS7 7个数据位CS8 8个数据位CSTOPB 2个停止位(不设则是1个停止位)CREAD 接收使能PARENB 校验位使能PARODD 使用奇校验而不使用偶校验HUPCL 最后关闭时挂线(放弃DTR)CLOCAL 本地连接(不改变端口所有者)LOBLK 块作业控制输出CNET_CTSRTS 硬件流控制使能

c_iflag支持的常量名称INPCK 奇偶校验使能IGNPAR 忽略奇偶校验错误PARMRK 奇偶校验错误掩码ISTRIP 除去奇偶校验位IXON 启动出口硬件流控IXOFF 启动入口软件流控IXANY 允许字符重新启动流控IGNBRK 忽略中断情况BRKINT 当发生中断时发送SIGINT信号INLCR 将NL映射到CRIGNCR 忽略CRICRNL 将CR映射到NLIUCLC 将高位情况映射到低位情况IMAXBEL 当输入太长时回复ECHO c_cc 支持的常量名称VINTR 中断控制,对应键为CTRL+CVQUIT 退出操作,对应键为CRTL+ZVERASE 删除操作,对应键为Backspace(BS)VKILL 删除行,对应键为CTRL+UVEOF 位于文件结尾,对应键为CTRL+DVEOL 位于行尾,对应键为Carriage return(CR)VEOL2 位于第二行尾,对应键为Line feed(LF)VMIN 指定了最少读取的字符数VTIME 指定了读取每个字符的等待时间

串口控制函数Tcgetattr 取属性(termios结构)Tcsetattr 设置属性(termios结构)cfgetispeed 得到输入速度Cfgetospeed 得到输出速度Cfsetispeed 设置输入速度Cfsetospeed 设置输出速度Tcdrain 等待所有输出都被传输tcflow 挂起传输或接收tcflush 刷清未决输入和/或输出Tcsendbreak 送BREAK字符tcgetpgrp 得到前台进程组IDtcsetpgrp 设置前台进程组ID

[color=#ff0000]完整的串口配置模板,实用!把常用的选项在函数里面列出,可大大方便用户的调试使用[/color]

int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop){ struct termios newtio,oldtio; /*保存测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息*/ if ( tcgetattr( fd,&oldtio) != 0) { perror("SetupSerial 1"); return -1; } bzero( &newtio, sizeof( newtio ) ); /*步骤一,设置字符大小*/ newtio.c_cflag |= CLOCAL | CREAD; newtio.c_cflag &= ~CSIZE; /*设置停止位*/ switch( nBits ) { case 7: newtio.c_cflag |= CS7; break; case 8: newtio.c_cflag |= CS8; break; }/*设置奇偶校验位*/ switch( nEvent ) { case ‘O’: //奇数 newtio.c_cflag |= PARENB; newtio.c_cflag |= PARODD; newtio.c_iflag |= (INPCK | ISTRIP); break; case ‘E’: //偶数 newtio.c_iflag |= (INPCK | ISTRIP); newtio.c_cflag |= PARENB; newtio.c_cflag &= ~PARODD; break; case ‘N’: //无奇偶校验位 newtio.c_cflag &= ~PARENB; break; } /*设置波特率*/ switch( nSpeed ) { case 2400: cfsetispeed(&newtio, B2400); cfsetospeed(&newtio, B2400); break; case 4800: cfsetispeed(&newtio, B4800); cfsetospeed(&newtio, B4800); break; case 9600: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; case 115200: cfsetispeed(&newtio, B115200); cfsetospeed(&newtio, B115200); break; case 460800: cfsetispeed(&newtio, B460800); cfsetospeed(&newtio, B460800); break; default: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; } /*设置停止位*/ if( nStop == 1 ) newtio.c_cflag &= ~CSTOPB; else if ( nStop == 2 ) newtio.c_cflag |= CSTOPB; /*设置等待时间和最小接收字符*/ newtio.c_cc[VTIME] = 0; newtio.c_cc[VMIN] = 0; /*处理未接收字符*/ tcflush(fd,TCIFLUSH); /*激活新配置*/ if((tcsetattr(fd,TCSANOW,&newtio))!=0) { perror("com set error"); return -1; } printf("set done!\n"); return 0;}

[b]串口使用详解[/b]在配置完串口的相关属性后,就可对串口进行打开,读写操作了。其使用方式与文件操作一样,区别在于串口是一个终端设备。

[b]打开串口[/b]fd = open( "/dev/ttyS0", O_RDWR|O_NOCTTY|O_NDELAY);

Open函数中除普通参数外,另有两个参数O_NOCTTY和O_NDELAY。 O_NOCTTY: 通知linix系统,这个程序不会成为这个端口的控制终端。 O_NDELAY: 通知linux系统不关心DCD信号线所处的状态(端口的另一端是否激活或者停止)。然后,恢复串口的状态为阻塞状态,用于等待串口数据的读入。用fcntl函数: fcntl(fd, F_SETFL, 0);

接着,测试打开的文件描述府是否引用一个终端设备,以进一步确认串口是否正确打开。 isatty(STDIN_FILENO);串口的读写与普通文件一样,使用read,write函数。 read(fd,buff,8); write(fd,buff,8);实例

#i nclude stdio.h>#i nclude string.h>#i nclude sys/types.h>#i nclude errno.h>#i nclude sys/stat.h>#i nclude fcntl.h>#i nclude unistd.h>#i nclude termios.h>#i nclude stdlib.h>int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop){ struct termios newtio,oldtio; if ( tcgetattr( fd,&oldtio) != 0) { perror("SetupSerial 1"); return -1; } bzero( &newtio, sizeof( newtio ) ); newtio.c_cflag |= CLOCAL | CREAD; newtio.c_cflag &= ~CSIZE; switch( nBits ) { case 7: newtio.c_cflag |= CS7; break; case 8: newtio.c_cflag |= CS8; break; } switch( nEvent ) { case ‘O’: newtio.c_cflag |= PARENB; newtio.c_cflag |= PARODD; newtio.c_iflag |= (INPCK | ISTRIP); break; case ‘E’: newtio.c_iflag |= (INPCK | ISTRIP); newtio.c_cflag |= PARENB; newtio.c_cflag &= ~PARODD; break; case ‘N’: newtio.c_cflag &= ~PARENB; break; }switch( nSpeed ) { case 2400: cfsetispeed(&newtio, B2400); cfsetospeed(&newtio, B2400); break; case 4800: cfsetispeed(&newtio, B4800); cfsetospeed(&newtio, B4800); break; case 9600: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; case 115200: cfsetispeed(&newtio, B115200); cfsetospeed(&newtio, B115200); break; default: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; } if( nStop == 1 ) newtio.c_cflag &= ~CSTOPB; else if ( nStop == 2 ) newtio.c_cflag |= CSTOPB; newtio.c_cc[VTIME] = 0; newtio.c_cc[VMIN] = 0; tcflush(fd,TCIFLUSH); if((tcsetattr(fd,TCSANOW,&newtio))!=0) { perror("com set error"); return -1; } printf("set done!\n"); return 0;}int open_port(int fd,int comport){ char *dev[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"}; long vdisable; if (comport==1) { fd = open( "/dev/ttyS0", O_RDWR|O_NOCTTY|O_NDELAY); if (-1 == fd){ perror("Can’t Open Serial Port"); return(-1); } else printf("open ttyS0 …..\n"); } else if(comport==2) { fd = open( "/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY); if (-1 == fd){ perror("Can’t Open Serial Port"); return(-1); } else printf("open ttyS1 …..\n"); } else if (comport==3) { fd = open( "/dev/ttyS2", O_RDWR|O_NOCTTY|O_NDELAY); if (-1 == fd){ perror("Can’t Open Serial Port"); return(-1); } else printf("open ttyS2 …..\n"); } if(fcntl(fd, F_SETFL, 0)0) printf("fcntl failed!\n"); else printf("fcntl=%d\n",fcntl(fd, F_SETFL,0)); if(isatty(STDIN_FILENO)==0) printf("standard input is not a terminal device\n"); else printf("isatty success!\n"); printf("fd-open=%d\n",fd); return fd;}int main(void){ int fd; int nread,i; char buff[]="Hello\n"; if((fd=open_port(fd,1))0){ perror("open_port error"); return; } if((i=set_opt(fd,115200,8,’N’,1))0){ perror("set_opt error"); return; } printf("fd=%d\n",fd);// fd=3; nread=read(fd,buff,8); printf("nread=%d,%s\n",nread,buff); close(fd); return;}

人只要不失去方向,就不会失去自己

linux C串口常规设置参考

相关文章:

你感兴趣的文章:

标签云: