linux下串口应用程序,Linux应用编程之串口

如何找到串口设备号

串口之打开操作

串口之初始化

串口之发送

串口之接收

如何找到串口设备号

如果你使用的是开发板搭载Linux系统进行的串口编程,你可以通过原理图进行查看  如果你电脑安装的linux系统,那么插上串口,通过dmesg命令进行查看  本文例子使用/dev/ttyS0

串口之打开操作

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15#include

#include

#include

int main(){

int fd;

char *com = "/dev/ttyS0";

if((fd = open(com,O_RDWR|O_CREAT,0777))<0){

//fd返回-1打开失败

}else{

//打开成功

}

return 0;

}

串口之初始化

了解termio结构体

常用初始化函数

tcgetattr函数

cfgetispeed函数

cfgetospeed函数

cfsetispeed函数

cfsetospeed函数

tcflush函数

tcsetattr函数

初始化步骤

读取当前参数

修改参数

配置参数

了解termio结构体

1

2

3

4

5

6

7

8

1

2

3

4

5

6

7

8struct termios

{

tcflag_t c_iflag;//输入模式

tcflag_t c_oflag;//输出模式

tcflag_t c_cflag;//控制模式

tcflag_t c_lflag;//本地模式

cc_t c_cc[NCCS];//控制字符

};

c_iflag参数如下:

键值

说明

IGNBRK

忽略BREAK键输入

BRKINT

如果设置了IGNBRK,BREAK键输入将被忽略

IGNPAR

忽略奇偶校验错误

PARMRK

标识奇偶校验错误

INPCK

允许输入奇偶校验

ISTRIP

去除字符的第8个比特

INLCR

将输入的NL(换行)转换成CR(回车)

IGNCR

忽略输入的回车

ICRNL

将输入的回车转化成换行(如果IGNCR未设置的情况下)

IUCLC

将输入的大写字符转换成小写字符(非POSIX)

IXON

允许输出时对XON/XOFF流进行控制

IXANY

输入任何字符将重启停止的输出

IXOFF

允许输入时对XON/XOFF流进行控制

IMAXBEL

当输入队列满的时候开始响铃

c_oflag参数如下:

键值

说明

OPOST

处理后输出

OLCUC

将输入的小写字符转换成大写字符(非POSIX)

ONLCR

将输入的NL(换行)转换成CR(回车)及NL(换行)

OCRNL

将输入的CR(回车)转换成NL(换行)

ONOCR

第一行不输出回车符

ONLRET

不输出回车符

OFILL

发送填充字符以延迟终端输出

OFDEL

以ASCII码的DEL作为填充字符,如果未设置该参数,填充字符为NUL

NLDLY

换行输出延时,可以取NL0(不延迟)或NL1(延迟0.1s)

CRDLY

回车延迟,取值范围为:CR0、CR1、CR2和 CR3

TABDLY

水平制表符输出延迟,取值范围为:TAB0、TAB1、TAB2和TAB3

BSDLY

空格输出延迟,可以取BS0或BS1

VTDLY

垂直制表符输出延迟,可以取VT0或VT1

FFDLY

换页延迟,可以取FF0或FF1

c_cflag参数如下:

参数

说明

CBAUD

波特率(4+1位)(非POSIX)

CBAUDEX

附加波特率(1位)(非POSIX)

CSIZE

字符长度,取值范围为CS5、CS6、CS7或CS8

CSTOPB

设置两个停止位

CREAD

使用接收器

PARENB

使用奇偶校验

PARODD

对输入使用奇偶校验,对输出使用偶校验

HUPCL

关闭设备时挂起

CLOCAL

忽略调制解调器线路状态

CRTSCTS

使用RTS/CTS流控制

c_lflag参数如下:

参数

说明

ISIG

当输入INTR、QUIT、SUSP或DSUSP时,产生相应的信号

ICANON

使用标准输入模式

XCASE

在ICANON和XCASE同时设置的情况下,终端只使用大写。

ECHO

显示输入字符

ECHOE

如果ICANON同时设置,ERASE将删除输入的字符

ECHOK

如果ICANON同时设置,KILL将删除当前行

ECHONL

如果ICANON同时设置,即使ECHO没有设置依然显示换行符

ECHOPRT

如果ECHO和ICANON同时设置,将删除打印出的字符(非POSIX)

TOSTOP

向后台输出发送SIGTTOU信号

c_cc[NCCS]参数如下:

说明

说明

VINTR

Interrupt字符

VEOL

附加的End-of-file字符

VQUIT

Quit字符

VTIME

非规范模式读取时的超时时间

VERASE

Erase字符

VSTOP

Stop字符

VKILL

Kill字符

VSTART

Start字符

VEOF

End-of-file字符

VSUSP

Suspend字符

VMIN

非规范模式读取时的最小字符数

常用初始化函数

tcgetattr函数

cfgetispeed函数

cfgetospeed函数

cfsetispeed函数

cfsetospeed函数

tcflush函数

tcsetattr函数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34读取当前参数函数:

int tcgetattr(int fd,struct termios *termios_p)

fd:open操作后返回的文件句柄

*termios_p:为前面介绍的结构体

初始化开始前调用这个函数.

获取当前波特率函数:

int speed_t cfgetispeed(const struct termios *termios_p)

int speed_t cfgetospeed(const struct termios *termios_p)

*termios_p:为前面介绍的结构体

成功返回0,失败返回-1

波特率设置函数:

int cfsetispeed(struct termios *termios_p,speed_t speed)

int cfsetospeed(struct termios *termios_p,speed_t speed)

*termios_p:为前面介绍的结构体

speed:波特率,常用B2400,B4800,B9600,B115200,B460800

成功返回0,失败返回-1

清空buffer数据函数:

int tcflush(int fd,int queue_selector)

queue_selector:有三个常用宏定义

TCIFLUSH:清空正读的数据,且不会读出

TCOFLUSH:清空正写入的数据,且不会发送到终端

TCIOFLUSH:清空所有正在发生的I/O数据.

成功返回0,失败返回-1

设置串口参数函数:

int tcsetattr(int fd,int optional_actions,cons struct termios *termios_p)

optional_actions:有三个常用宏定义

TCSANOW:不等数据传输完毕,立即改变属性

TCSADRAIN:等所有数据传输完毕,再改变属性

TCSAFLUSH:清空输入输出缓冲区才改变属性

成功返回0,失败返回-1

初始化设置代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82/**

*fd:文件句柄

*nSpeed:波特率

*nBits:数据位

*nEvent:奇偶校验

*nStop:停止位

/

int set_opt(int fd,int nSpeed,int nBits,int nEvent ,int nStop){

struct termios newtio,oldtio;

if(tcgetattr(fd,&oldtio)!=0){

//错误

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((tcsetttr(fd,TCSANOW,&newtio))!=0){

//com set error

return -1;

}

return 0;

}

串口之发送与接收

#include

#include

#include

#include

#include

#include

#include

#include

int set_opt(int,int,int,char,int);

void main()

{

int fd;

char *com= "/dev/ttyS0";

char *buffer = "hello world!\n";

if((fd = open(com, O_RDWR|O_NOCTTY|O_NDELAY))<0){

printf("open %s is failed",com);

}

else{

printf("open %s is success\n",com);

set_opt(fd, 115200, 8, 'N', 1);

wr_static = write(fd,buffer, strlen(buffer));

//读取差不多一样的这里就不介绍了

if(wr_static<0)

printf("write failed\n");

else

printf("wr_static is %d\n",wr_static);

close(fd);

}

}

int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)

{

struct termios newtio,oldtio;

if ( tcgetattr( fd,&oldtio) != 0) {

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;

}

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值