tcgetattr
该函数用于获取与终端相关的参数。fd为终端的文件描述符,保存了返回的结果termios结构体中
http://baike.baidu.com/view/5644808.htm?fr=aladdin
tcsetattr 设置终端相关参数的函数
tcflush
Unix终端I/O函数。功能:清空终端未完成的输入/输出请求和数据
常用函数
使用open()函数打开串口,open()函数有两个参数,第一个是要打开的设备名(如:/dev/ttyS0)。第二个是打开的方式。
打开方式有以下三种:
-
O_RDWR,表示以读写方式打开串口。
-
O_NOCTTY,表示不成为端口的控制终端,如果没有这个选项,则任何输入(键盘按键)都会中断程序的执行。
-
O_NDELAY,表示程序不会关注DCD信号线所处的状态,即不管对端设备是运行或挂起。如果没有该选项,
-
则程序会被设置成睡眠状态,直到DCD信号为低为止。
成功打开串口则会返回文件描述符,打开失败则返回-1。下面是一个打开串口的示例:
fd = open("/dev/ttyS0",O_RDWR|O_NDELAY|O_NDELAY);
使用close()关闭打开的串口,唯一的参数是打开串口的文件描述符。下面是一个关闭串口的示例:
close(fd); //fd是打开串口返回的文件描述符
用write()函数向串口写数据。下面是一个向串口写数据的示例:
n = write(fd,buff,len); /* n表示成功写到串口的字节数,如果写入失败则返回-1 fd是打开串口返回的文件描述符 buff表示写入的内容 len表示写入信息的长度。 */
用read()函数从串口读取数据。下面是一个从串口读数据的示例:
n = read(fd,buff,len); /* n表示从串口读到字节数 fd是文件描述符 buff是读入字节存放的缓冲区 len表示读入的字节数 */
通过fcntl()函数可以操作文件描述符,用以控制读取数据的状态。fcntl(fd,F_SETFL,0)表示没有数据则阻塞,处于等待状态,
直到有数据到来;fcntl(fd,F_SETFL,FNDELAY)表示当端口没有数据时马上返回0。
-
BRKINT和IGNBRK
如果设置了IGNBRK,中断条件被忽略。如果没有设置IGNBRK而设置了BRKINT,中断条件清空输入输出队列中所有的数据并
-
且向tty的前台进程组中所有进程发送一个SIGINT信号。如果这两个都没有设置,中断条件会被看作一个0字符。这时,如
-
果设置了PARMRK,当检测到一个帧误差时将会向应用程序发送三个字节'\377''\0''\0',而不是只发送一个'\0'。
-
PARMRK和IGNPAR
如果设定了IGNPAR,则忽略接收到的数据的奇偶检验错误或帧错误(除了前面提到的中断条件)。如果没有设置IGNPAR而
-
设置了PARMRK,当接收到的字节存在奇偶检验错误或帧错误的时候。将向应用程序发送一个三字节的'\377''\0''\n'错误
-
报告。其中n表示所接收到的字节。如果两者都没有设置,除了接收到的字节存在奇偶检验错误或帧误差之外的中止条件
-
都会向应用程序发送一个单字节('\0')的报告。
-
INPCK
如果设置,则进行奇偶校验。如果不进行奇偶检验,PARMRK和IGNPAR将对存在的奇偶校验错误不产生任何的影响。
-
ISTRIP
如果设置,所接收到的所有字节的高位将会被去除,保证它们是一个7位的字符。
-
INLCR
如果设置,所接收到的换行字符('\n')将会被转换成回车符('\r')。
-
IGNCR
如果设置,则会忽略所有接收的回车符('\r')。
-
ICRNL
如果设置,但IGNCR没有设置,接收到的回车符向应用程序发送时会变换成换行符。
-
IUCLC
如果IUCLC和IEXTEN都设置,接收到的所有大写字母发送给应程序时都被转换成小写字母。POSIX中没有定义该标记。
-
IXOFF
如果设置,为避免tty设备的输入缓冲区溢出,tty设备可以向终端发送停止符^S和开始符^Q,要求终端停止或重新开始
-
向计算机发送数据。通过停止符和开始符来控制数据流的方式叫软件流控制,软件流控制方式较少用,我们主要还是用
-
硬件流控制方式。硬件流控制在c_cflag标志中设置。
-
IXON
如果设置,接收到^S后会停止向这个tty设备输出,接收到^Q后会恢复输出。
-
IXANY
如果设置,则接到任何字符都会重新开始输出,而不仅仅是^Q字符。
-
IMAXBEL
如果设置,当输入缓冲区空间满时,再接收到的任何字符就会发出警报符'\a'。POSIX中没有定义该标记。
OPOST是POSIX定义的唯一一个标志,只有设置了该标志后,其它非POSIX的输出标记才会生效。
-
OPOST
开启该标记,后面的输出标记才会生效。否则,不会对输出数据进行处理。
-
OLCUC
如果设置,大写字母被转换成小写字母输出。
-
ONLCR
如果设置,在发送换行符('\n')前先发送回车符('\r')。
-
ONOCR
如果设置,当current column为0时,回车符不会被发送也不会被处理。
-
OCRNL
如果设置,回车符会被转换成换行符。另外,如果设置了ONLRET,则current column会被设为0.
-
ONLRET
如果设置,当一个换行符或回车符被发送的时候,current column会被设置为0。
-
OXTABS
如果设置,制表符会被转换成空格符。
-
CLOCAL
如果设置,modem的控制线将会被忽略。如果没有设置,则open()函数会阻塞直到载波检测线宣告modem处于摘机状态为止。
-
CREAD
只有设置了才能接收字符,该标记是一定要设置的。
-
CSIZE
设置传输字符的位数。CS5表示每个字符5位,CS6表示每个字符6位,CS7表示每个字符7位,CS8表示每个字符8位。
-
CSTOPB
设置停止位的位数,如果设置,则会在每帧后产生两个停止位,如果没有设置,则产生一个停止位。一般都是使用一位停
-
止位。需要两位停止位的设备已过时了。
-
HUPCL
如果设置,当设备最后打开的文件描述符关闭时,串口上的DTR和RTS线会减弱信号,通知Modem挂断。也就是说,当一个
-
用户通过Modem拔号登录系统,然后注销,这时Modem会自动挂断。
-
PARENB和PARODD
如果设置PARENB,会产生一个奇偶检验位。如果没有设置PARODD,则产生偶校验位,如果设置了PARODD,则产生奇校验位。
-
如果没有设置PARENB,则PARODD的设置会被忽略。
-
CRTSCTS
使用硬件流控制。在高速(19200bps或更高)传输时,使用软件流控制会使效率降低,这个时候必须使用硬件流控制。
只有在本地模式标志c_lflag中设置了IEXITEN时,POSIX没有定义的控制字符才能在Linux中使用。每个控制字符都对应一个
按键组合(^C、^H等),但VMIN和VTIME这两个控制字符除外,它们不对应控制符。这两个控制字符只在原始模式下才有效。
-
c_cc[VINTR]
默认对应的控制符是^C,作用是清空输入和输出队列的数据并且向tty设备的前台进程组中的每一个程序发送一个SIGINT信号
-
,对SIGINT信号没有定义处理程序的进程会马上退出。
-
c_cc[VQUIT]
默认对应的控制符是^\,作用是清空输入和输出队列的数据并向tty设备的前台进程组中的每一个程序发送一个SIGQUIT
-
信号,对SIGQUIT信号没有定义处理程序的进程会马上退出。
-
c_cc[verase]
默认对应的控制符是^H或^?,作用是在标准模式下,删除本行前一个字符,该字符在原始模式下没有作用。
-
c_cc[VKILL]
默认对应的控制符是^U,在标准模式下,删除整行字符,该字符在原始模式下没有作用。
-
c_cc[VEOF]
默认对应的控制符是^D,在标准模式下,使用read()返回0,标志一个文件结束。
-
c_cc[VSTOP]
默认对应的控制字符是^S,作用是使用tty设备暂停输出直到接收到VSTART控制字符。或者,如果设备了IXANY,
-
则等收到任何字符就开始输出。
-
c_cc[VSTART]
默认对应的控制字符是^Q,作用是重新开始被暂停的tty设备的输出。
-
c_cc[VSUSP]
默认对应的控制字符是^Z,使当前的前台进程接收到一个SIGTSTP信号。
-
c_cc[VEOL]和c_cc[VEOL2]
在标准模式下,这两个下标在行的末尾加上一个换行符('\n'),标志一个行的结束,从而使用缓冲区中的数据被发送,
-
并开始新的一行。POSIX中没有定义VEOL2。
-
c_cc[VREPRINT]
默认对应的控制符是^R,在标准模式下,如果设置了本地模式标志ECHO,使用VERPRINT对应的控制符和换行符在本地显示,
-
并且重新打印当前缓冲区中的字符。POSIX中没有定义VERPRINT。
-
c_cc[VWERASE]
默认对应的控制字符是^W,在标准模式下,删除缓冲区末端的所有空格符,然后删除与之相邻的非空格符,从而起到在一
-
行中删除前一个单词的效果。POSIX中没有定义VWERASE。
-
c_cc[VLNEXT]
默认对应的控制符是^V,作用是让下一个字符原封不动地进入缓冲区。如果要让^V字符进入缓冲区,需要按两下^V。POSIX中
-
没有定义VLNEXT。
要禁用某个控制字符,只需把它设置为_POSIX_VDISABLE即可。但该常量只在Linux中有效,所以如果程序要考虑移植性的问题,
请不要使用该常量。
-
ICANON
如果设置,则启动标准模式,如果没有设置,则启动原始模式。
-
ECHO
如果设置,则启动本地回显。如果没有设置,则除了ECHONL之外,其他以ECHO开头的标记都会失效。
-
ECHOCTL
如果设置,则以^C的形式打印控制字符,如:按Ctrl+C显示^C,按Ctrl+?显示^?。
-
ECHOE
如果在标准模式下设定了ECHOE标志,则当收到一个ERASE控制符时将删除前一个显示字符。
-
ECHOK和ECHOKE
在标准模式下,当接收到一个KILL控制符,则在缓冲区中删除当前行。如果ECHOK、ECHOKE和ECHOE都没有设置,则用ECHOCTL
如果已经设置了ECHOE和ECHOK,但没有设置ECHOKE,将会在输出终端显示ECHOCTL表示的KILL字符,紧接着是换行,如果设
如果ECHOK、ECHOKE和ECHOE都有设置,则会删除当前行。
在POSIX中没有定义ECHOKE标记,在没有定义ECHOKE标记的系统中,设置ECHOK则表示同时设置了ECHOKE标志。
-
置了OPOST,将会通过OPOST处理程序进行适当的处理。
-
表示的KILL字符(^U)将会在输出终端上显示,表示当前行已经被删除。
-
ECHONL
如果在标准模式下设置了该标志,即使没有设置ECHO标志,换行符还是会被显示出来。
-
ECHOPRT
如果设置,则字符会被简单地打印出来,包括各种控制字符。在POSIX中没有定义该标志。
-
ISIG
如果设置,与INTR、QUIT和SUSP相对应的信号SIGINT、SIGQUIT和SIGTSTP会发送到tty设备的前台进程组中的所有进程。
-
NOFLSH
一般情况下,当接收到INTR或QUIT控制符的时候会清空输入输出队列,当接收到SUSP控制符时会清空输入队列。但是如果
-
设置了NOFLUSH标志,则所有队列都不会被清空。
-
TOSTOP
如果设置,则当一个非前台进程组的进程试图向它的控制终端写入数据时,信号SIGTTOU会被被发送到这个进程所在的进
-
程组。默认情况下,这个信号会使进程停止,就像收到SUSP控制符一样。
-
IEXIEN
默认已设置,我们不应修改它。在Linux中IUCLC和几个与删除字符相关的标记都要求在设置了IEXIEN才能正常工作。
-
设置流控制
termios_new.c_cflag &= ~CRTSCTS; //不使用流控制 termios_new.c_cflag |= CRTSCTS; //使用硬件流控制 termios_new.c_iflag |= IXON|IXOFF|IXANY; //使用软件流控制
-
屏蔽字符大小位
termios_new.c_cflag &= ~CSIZE;
-
设置数据位大小
termios_new.c_cflag |= CS8; //使用8位数据位 termios_new.c_cflag |= CS7; //使用7位数据位 termios_new.c_cflag |= CS6; //使用6位数据位 termios_new.c_cflag |= CS5; //使用5位数据位
-
设置奇偶校验方式
termios_new.c_cflag &= ~PARENB; //无奇偶校验 termios_new.c_cflag |= PARENB; //奇校验 termios_new.c_cflag &= ~PARODD; termios_new.c_cflag |= PARENB; //偶校验 termios_new.c_cflag &= ~PARODD;
-
停止位
termios_new.c_cflag |= CSTOPB; //2位停止位 termios_new.c_cflag &= ~CSTOPB; //1位停止位
-
输出模式
termios_new.c_cflag &= ~OPOST; //原始数据(RAW)输出
-
控制字符
termios_new.c_cc[VMIN] = 1; //读取字符的最小数量 termios_new.c_cc[VTIME] = 1; //读取第一个字符的等待时间
-
关闭终端回显,键盘输入的字符不会在终端窗口显示。
#include <stdio.h> #include <stdlib.h> #include <termios.h> #include <unistd.h> int main(void) { struct termios ts,ots; char passbuf[1024]; tcgetattr(STDIN_FILENO,&ts); /* STDIN_FILENO的值是1,表示标准输入的文件描述符 */ ots = ts; ts.c_lflag &= ~ECHO; /* 关闭回终端回显功能*/ ts.c_lflag |= ECHONL; tcsetattr(STDIN_FILENO,TCSAFLUSH,&ts); /* 应用新终端设置 */ fgets(passbuf,1024,stdin); /* 输入字符不会在终端显示 */ printf("you input character = %s\n",passbuf); tcsetattr(STDIN_FILENO,TCSANOW,&ots); /* 恢复旧的终端设备 */ }
串口本身,标准和硬件 †
串口是计算机上的串行通讯的物理接口。计算机历史上,串口曾经被广泛用于连接计算机和终端设备和各种外部设备。虽然以太网接口和USB接口也
是以一个串行流进行数据传送的,但是串口连接通常特指那些与RS-232标准兼容的硬件或者调制解调器的接口。虽然现在在很多个人计算机上,
原来用以连接外部设备的串口已经广泛的被USB和Firewire替代;而原来用以连接网络的串口则被以太网替代,还有用以连接终端的串口设备则已经
被MDA或者VGA取而代之。但是,一方面因为串口本身造价便宜技术成熟,另一方面因为串口的控制台功能RS-232标准高度标准化并且非常普及,
所以直到现在它仍然被广泛应用到各种设备上。 某些计算机使用一个叫做UART的集成电路来作为串口设备。这个集成电路可以进行字符和异步串行