POSIX操作系统的串口编程指南(2)

第二章:配置串口

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

 

POSIX终端接口

多数系统支持使用POSIX终端接口改变波特率、字符数等参数。首先要包含头文件;这样就定义了终端控制结构和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:启用字符接收器。

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

注:决不能直接初始化c_cflag(或其他flag)。应该使用ANDORNOT等位操作符来置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);

 

tcgetattr3)函数使用你提供的串口配置参数填充termios结构。设置了波特率、使能本地模式和串行数据接收后,使用tcsetattr3)使新的配置生效。常量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_RTSCTSCRTSCTS常量 ,那就很可能支持硬件流控制。使用下面的代码可以使能硬件流控制:

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

关闭硬件流控制:

options.c_cflag &= ~CNEW_RTSCTS;

 

本地选项

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

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)字符。选择这个模式的话,你需要选择ICANONECHOECHOE选项:

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

选择Raw Input

Raw input 是不做任何处理的。输入字符被收到后就直接传送。你需要取消ICANONECHOECHOEISIG选项来选择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, PARMRKISTRIP。通常你需要选择INPCKISTRIP来使能输入奇偶校验并去掉数据中的校验位:

options.c_iflag |= INPCK | ISTRIP);

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

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

设置软件流控制

使用IXONIXOFfIXANY常量来使能软件流控制:

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

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

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

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

输出选项

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

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)

 

你可能感兴趣的:(Linux串口编程)