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

POSIX操作系统的串口编程指南(2) 分类: Linux串口编程

2012-08-22 10:12 507 查看


第二章:配置串口


这一章介绍怎样使用C语言的POSIX终端接口配置串口。



POSIX终端接口

多数系统支持使用POSIX终端接口改变波特率、字符数等参数。首先要包含头文件<termios.h>;这样就定义了终端控制结构和POSIX控制函数。

两个最重要的POSIX函数是tcgetattr(3)和tcsetattr(3),用了获取和设置终端属性。你可以设置一个指向termios结构的指针,这个结构包含了所有可用的串口选项:

Table 3 - Termios Structure Members
Member
Description
c_cflag
Control options
c_lflag
Line options
c_iflag
Input options
c_oflag
Output options
c_cc
Control characters
c_ispeed
Input baud (new interface)
c_ospeed
Output baud (new interface)



控制选项

c_cflag用来控制波特率、数据位、奇偶位、停止位和硬件流控制。下面是所有支持的配置的常量:

Table 4 - Constants for the c_cflag Member
Constant
Description
CBAUD
Bit mask for baud rate
B0
0 baud (drop DTR)
B50
50 baud
B75
75 baud
B110
110 baud
B134
134.5 baud
B150
150 baud
B200
200 baud
B300
300 baud
B600
600 baud
B1200
1200 baud
B1800
1800 baud
B2400
2400 baud
B4800
4800 baud
B9600
9600 baud
B19200
19200 baud
B38400
38400 baud
B57600
57,600 baud
B76800
76,800 baud
B115200
115,200 baud
EXTA
External rate clock
EXTB
External rate clock
CSIZE
Bit mask for data bits
CS5
5 data bits
CS6
6 data bits
CS7
7 data bits
CS8
8 data bits
CSTOPB
2 stop bits (1 otherwise)
CREAD
Enable receiver
PARENB
Enable parity bit
PARODD
Use odd parity instead of even
HUPCL
Hangup (drop DTR) on last close
CLOCAL
Local line - do not change "owner" of port
LOBLK
Block job control output
CNEW_RTSCTS

CRTSCTS
Enable hardware flow control (not supported on all platforms)
c_cflag有两个选项需要一直使能,CLOCAL:忽略所有调制解调器的状态信号;CREAD:启用字符接收器。

波特率常数(CBAUD,B9600,etc.)用于缺少c_ispeed和c_ospeed 成员的旧接口。下一节介绍用于设置波特率的POSIX函数。

注:决不能直接初始化c_cflag(或其他flag)。应该使用AND,OR或NOT等位操作符来置1或清0成员中的位。不同的操作系统版本的位操作可能不同,使用位操作符可以避免错误操作一个新串行设备所需要的标志位。

1)设置波特率

不同的操作系统中,波特率储存的位置也不同。旧的接口将波特率按照Table4中的常量保存c_cflag中。新的实现方法提供了c_ispeed 和c_ospeed 来保存实际的波特率值。

cfsetospeed(3)和cfsetispeed(3)函数用来设置termios结构中的波特率,从而屏蔽了底层的操作系统。你可以使用下面的代码设置波特率:

Listing 2 - Setting the baud rate.

struct termios options;

/*

* Get the current options for the port...

*/

tcgetattr(fd, &options);

/*

* Set the baud rates to 19200...

*/

cfsetispeed(&options, B19200);

cfsetospeed(&options, B19200);

/*

* Enable the receiver and set local mode...

*/

options.c_cflag |= (CLOCAL | CREAD);

/*

* Set the new options for the port...

*/

tcsetattr(fd, TCSANOW, &options);

tcgetattr(3)函数使用你提供的串口配置参数填充termios结构。设置了波特率、使能本地模式和串行数据接收后,使用tcsetattr(3)使新的配置生效。常量TCSANOW指定了新的设置立即生效,不需要等待数据接收或发生结束。还有其他常量,可以等待输入或输出数据结束,或清空缓冲区。

多数操作系统不支持不同的输入和输出速率,为了最好的可移植性,请确保相同的输入和输出速率。

Table 5 - Constants for tcsetattr
Constant
Description
TCSANOW
Make changes now without waiting for data to complete
TCSADRAIN
Wait until everything has been transmitted
TCSAFLUSH
Flush input and output buffers and make the change
2)设置字符大小

与波特率设置不同,没有方便的函数用来设置字符大小,所有必须用位掩码。字符大小用位数指定。

options.c_cflag &= ~CSIZE; /* Mask the character size bits */

options.c_cflag |= CS8; /* Select 8 data bits */

3)设置奇偶校验

类似设置字符大小,你必须手动设置使能奇偶校验和奇偶校验位数。UNIX的串口设备支持奇、偶和无校验。

No parity (8N1):

options.c_cflag &= ~PARENB

options.c_cflag &= ~CSTOPB

options.c_cflag &= ~CSIZE;

options.c_cflag |= CS8;

Even parity (7E1):

options.c_cflag |= PARENB

options.c_cflag &= ~PARODD

options.c_cflag &= ~CSTOPB

options.c_cflag &= ~CSIZE;

options.c_cflag |= CS7;

Odd parity (7O1):

options.c_cflag |= PARENB

options.c_cflag |= PARODD

options.c_cflag &= ~CSTOPB

options.c_cflag &= ~CSIZE;

options.c_cflag |= CS7;

Space parity is setup the same as no parity (7S1):

options.c_cflag &= ~PARENB

options.c_cflag &= ~CSTOPB

options.c_cflag &= ~CSIZE;

options.c_cflag |= CS8;

4)硬件流控制

有些UNIX版本支持使用CTS (Clear To Send)和RTS (Request To Send)信号来控制硬件流。如果你的系统定义了CNEW_RTSCTS或CRTSCTS常量 ,那就很可能支持硬件流控制。使用下面的代码可以使能硬件流控制:

options.c_cflag |= CNEW_RTSCTS; /* Also called CRTSCTS */

关闭硬件流控制:

options.c_cflag &= ~CNEW_RTSCTS;

本地选项

本地模式成员c_lflag用于控制串行设备如何管理输入字符。通常可以将c_lflag配置为canonical或raw 。

Table 6 - Constants for the c_lflag Member
ISIG
Enable SIGINTR, SIGSUSP, SIGDSUSP, and SIGQUIT signals
ICANON
Enable canonical input (else raw)
XCASE
Map uppercase /lowercase (obsolete)
ECHO
Enable echoing of input characters
ECHOE
Echo erase character as BS-SP-BS
ECHOK
Echo NL after kill character
ECHONL
Echo NL
NOFLSH
Disable flushing of input buffers after interrupt or quit characters
IEXTEN
Enable extended functions
ECHOCTL
Echo control characters as ^char and delete as ~?
ECHOPRT
Echo erased character as character erased
ECHOKE
BS-SP-BS entire line on line kill
FLUSHO
Output being flushed
PENDIN
Retype pending input at next read or input char
TOSTOP
Send SIGTTOU for background output



选择Canonical Input

Canonical Input是以行进行操作的。输入的字符被放在一个可以由用户进行交互编辑的缓冲区,知道收到回车(CR)或换行(LF)字符。选择这个模式的话,你需要选择ICANON,ECHO和ECHOE选项:

options.c_lflag |= (ICANON | ECHO | ECHOE);



选择Raw Input

Raw input 是不做任何处理的。输入字符被收到后就直接传送。你需要取消ICANON、ECHO、ECHOE和ISIG选项来选择Raw Input模式:

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



关于输入回显的说明

决不能在发生命令给一个MODOM或电脑时使能输入回显,那样的话会在两个串口之间形成一个回环。



输入选项

输入模式成员变量c_iflag用于控制串口接收端的字符的处理过程。与c_cflag一样,c_iflag的值也是将需要的选项通过OR运算得到的。

Table 7 - Constants for the c_iflag Member
Constant
Description
INPCK
Enable parity check
IGNPAR
Ignore parity errors
PARMRK
Mark parity errors
ISTRIP
Strip parity bits
IXON
Enable software flow control (outgoing)
IXOFF
Enable software flow control (incoming)
IXANY
Allow any character to start flow again
IGNBRK
Ignore break condition
BRKINT
Send a SIGINT when a break condition is detected
INLCR
Map NL to CR
IGNCR
Ignore CR
ICRNL
Map CR to NL
IUCLC
Map uppercase to lowercase
IMAXBEL
Echo BEL on input line too long



设置输入奇偶校验选项

如果已经在c_cflag中使能了奇偶校验,那你可以使能输入奇偶校验。与输入奇偶校验相关的常量是INPCK, IGNPAR, PARMRK和ISTRIP。通常你需要选择INPCK和ISTRIP来使能输入奇偶校验并去掉数据中的校验位:

options.c_iflag |= (INPCK | ISTRIP);

IGNPAR是一个危险的选项,它告诉串口忽略校验错误并让数据通过,就想没用发生错误一样。这在测试通信连接的质量时有用,通常没有实用价值。

PARMRK会使校验错误被标记为“marked",并使用特殊的字符放入输入流中。如果使能IGNPAR,一个空字符(000 octal)会被加入到校验错误的前面。否则,DEL(177 octal)和NUL字符会和错误字符一起发生。



设置软件流控制

使用IXON、IXOFf和IXANY常量来使能软件流控制:

options.c_iflag |= (IXON | IXOFF | IXANY);

取消软件流控制只需掩掉这些位:

options.c_iflag &= (IXON | IXOFF | IXANY);

XON(开始数据)和XOFF(停止数据)字符定义在下面描述的c_cc数组中。



输出选项

C_oflag成员包含了输出过滤选项。像输入模式一样,你可以选择processed或raw数据输出。

Table 8 - Constants for the c_oflag Member
Constant
Description
OPOST
Postprocess output (not set = raw output)
OLCUC
Map lowercase to uppercase
ONLCR
Map NL to CR-NL
OCRNL
Map CR to NL
NOCR
No CR output at column 0
ONLRET
NL performs CR function
OFILL
Use fill characters for delay
OFDEL
Fill character is DEL
NLDLY
Mask for delay time needed between lines
NL0
No delay for NLs
NL1
Delay further output after newline for 100 milliseconds
CRDLY
Mask for delay time needed to return carriage to left column
CR0
No delay for CRs
CR1
Delay after CRs depending on current column position
CR2
Delay 100 milliseconds after sending CRs
CR3
Delay 150 milliseconds after sending CRs
TABDLY
Mask for delay time needed after TABs
TAB0
No delay for TABs
TAB1
Delay after TABs depending on current column position
TAB2
Delay 100 milliseconds after sending TABs
TAB3
Expand TAB characters to spaces
BSDLY
Mask for delay time needed after BSs
BS0
No delay for BSs
BS1
Delay 50 milliseconds after sending BSs
VTDLY
Mask for delay time needed after VTs
VT0
No delay for VTs
VT1
Delay 2 seconds after sending VTs
FFDLY
Mask for delay time needed after FFs
FF0
No delay for FFs
FF1
Delay 2 seconds after sending FFs



选择Processed输出

通过设置c_oflag中的OPOST选项来选择Processed输出:

options.c_oflag |= OPOST;

在所有的选项中,你大概只需要用ONLCR选项将换行符映射到CR-LF上。



选择Raw输出

在c_oflag中重新设置OPOST选项就选择了Raw输出:

Options.c_oflag &= ~OPOST;

取消OPOST选项时,c_oflag中的其他选项都将被忽略。



控制字符

c_cc字符数组包含控制字符的定义和超时参数。数组的元素都定义了常量。

Table 9 - Control Characters in the c_cc Member
Constant
Description
Key
VINTR
Interrupt
CTRL-C
VQUIT
Quit
CTRL-Z
VERASE
Erase
Backspace (BS)
VKILL
Kill-line
CTRL-U
VEOF
End-of-file
CTRL-D
VEOL
End-of-line
Carriage return (CR)
VEOL2
Second end-of-line
Line feed (LF)
VMIN
Minimum number of characters to read
VTIME
Time to wait for data (tenths of seconds)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: