linux下写通信程序,Linux下写串口通信程序

串口属性通过结构体struct termios来设置。通过tcgetattr()函数可以获取串口当前属性,通过tcsetattr函数把新的属性设置到串口上。

struct termios包含以下成员:

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用于设置控制参数,除波特率外还包含以下内容:

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)

其中CLOCAL和CREAD通常总是应该被使能的。

下面是c_cflag的一些典型配置方式:

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;

c_lfalg用于设置本地模式,它决定串口驱动如何处理输入的字符。其设置包含以下内容:

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

c_iflag用于设置如何处理串口上接收到的数据,包含以下内容:

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_oflag用语设置如何处理输出数据,包含以下内容:

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

c_cc定义了控制字符,包含以下内容:

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

-

VSTART

Start flow

CTRL-Q (XON)

VSTOP

Stop flow

CTRL-S (XOFF)

VTIME

Time to wait for data (tenths of seconds)

-

其中,控制符 VTIME 和 VMIN 之间有着复杂的关系。 VTIME 定义要求等待的零到几百毫秒的值(通常是一个8位的unsigned char变量)。VMIN 定义了要求等待的最小字节数(不是要求读的字节数,read()的第三个参数才是指定要求读的最大字节数),这个字节数可能是0。

>   如果 VTIME 取 0 , VMIN 定义了要求等待读取的最小字节数。函数read() 只有在读取了 VMIN 个字节的数据或者收到一个信号的时候才返回。

>   如果 VMIN 取 0 , VTIME 定义了即使没有数据可以读取, read() 函数返回前也要等待几百毫秒的时间量。这时, read() 函数不需要像其通常情况那样要遇到一个文件结束标志才返回 0 。

>   如果 VTIME 和 VMIN 等不取 0 , VTIME 定义的时当接收到底一个自己的数据后开始计算等待的时间量。如果当调用 read 函数时可以得到数据,计时器马上开始计时。如果但调用 read 函数时还没有任何数据可读,则等接收到底一个字节的数据后,计时器开始计时。函数 read 可能会在读取到 VMIN 个字节的数据后返回,也可能在计时完毕后返回,这主要取决于哪个条件首先实现。不过函数至少会读取到一个字节的数据,因为计时器是在读取到第一个数据时开始计时的。

>   如果 VTIME 和 VMIN 都取 0 ,即使读取不到任何数据,函数read也会立即返回。同时,返回值 0 表示 read 函数不需要等待文件结束标志就返回了。

串口属性一般不应该直接赋值,而用按位或和按位与非来设置。设置好的属性使用tcsetattr函数来让它在串口上生效。此函数的第一个参数是串口设备描述符,第三个是指向设置属性的termios结构体的指针,第二个参数有以下选择:

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

串口通信源程序(此程序接收14个字节数据再把它发回去):

#include

#include

#include

#include

#include

#include

#include

#include

main()

{

int fd;

int i;

int len;

int n=0;

char read_buf[256];

char write_buf[256];

struct termios opt;

fd = open("/dev/tts/0", O_RDWR | O_NOCTTY);    //默认为阻塞读方式

if(fd == -1)

perror("open serial 0\n");

tcgetattr(fd, &opt);

cfsetispeed(&opt, B9600);

cfsetospeed(&opt, B9600);

if(tcsetattr(fd, TCSANOW, &opt) != 0 )

{     perror("tcsetattr error");

return -1;

}

opt.c_cflag &=~CSIZE;

opt.c_cflag |= CS8;

opt.c_cflag &=~CSTOPB;

opt.c_cflag &=~PARENB;

opt.c_cflag &=~INPCK;

opt.c_cflag |= (CLOCAL | CREAD);

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

opt.c_oflag &=~OPOST;

opt.c_iflag &=~ICRNL;

opt.c_iflag &=~INLCR;

opt.c_cc[VTIME] = 150;

opt.c_cc[VMIN] = 1;

tcflush(fd, TCIOFLUSH);

printf("configure complete\n");

if(tcsetattr(fd, TCSANOW, &opt) != 0)

{

perror("serial error");

return -1;

}

printf("start send and receive data\n");

while(1)

{

n = 0;

len = 0;

bzero(read_buf,sizeof read_buf);

bzero(write_buf,sizeof write_buf);

while( (n = read(fd, read_buf, 14)) > 0 )

{

for(i=len; i

{

write_buf[i] = read_buf[i-len];

}

len += n;

if(len == 14)    //读完全部14个数据就结束

break;

}

for(i=0; i

printf("%d ",write_buf[i]);

n = write(fd, write_buf, len);

printf("write %d chars\n",n);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值