- 如何找到串口设备号
- 串口之打开操作
- 串口之初始化
- 串口之发送
- 串口之接收
如何找到串口设备号
如果你使用的是开发板搭载Linux系统进行的串口编程,你可以通过原理图进行查看
如果你电脑安装的linux系统,那么插上串口,通过dmesg命令进行查看
本文例子使用/dev/ttyS0
串口之打开操作
#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int main(){ int fd; char *com = "/dev/ttyS0"; if((fd = open(com,O_RDWR|O_CREAT,0777))<0){ }else{ } return 0;}
串口之初始化
- 了解termio结构体
- 常用初始化函数
- tcgetattr函数
- cfgetispeed函数
- cfgetospeed函数
- cfsetispeed函数
- cfsetospeed函数
- tcflush函数
- tcsetattr函数
- 初始化步骤
了解termio结构体
struct 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作为填充字符,如果未设置该参数,填充字符为NULNLDLY换行输出延时,可以取NL0(不延迟)或NL1(延迟0.1s)CRDLY回车延迟,取值范围为:CR0、CR1、CR2和 CR3TABDLY水平制表符输出延迟,取值范围为:TAB0、TAB1、TAB2和TAB3BSDLY空格输出延迟,可以取BS0或BS1VTDLY垂直制表符输出延迟,可以取VT0或VT1FFDLY换页延迟,可以取FF0或FF1c_cflag参数如下:
参数 | 说明 | CBAUD波特率(4+1位)(非POSIX)CBAUDEX附加波特率(1位)(非POSIX)CSIZE字符长度,取值范围为CS5、CS6、CS7或CS8CSTOPB设置两个停止位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]参数如下:
宏 | 说明 | 宏 | 说明 | VINTRInterrupt字符VEOL附加的End-of-file字符VQUITQuit字符VTIME非规范模式读取时的超时时间VERASEErase字符VSTOPStop字符VKILLKill字符VSTARTStart字符VEOFEnd-of-file字符VSUSPSuspend字符VMIN非规范模式读取时的最小字符数
常用初始化函数
- tcgetattr函数
- cfgetispeed函数
- cfgetospeed函数
- cfsetispeed函数
- cfsetospeed函数
- tcflush函数
- tcsetattr函数
读取当前参数函数: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
- 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
初始化设置代码如下:
/***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;}
- 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
串口之发送与接收
#include <stdio.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <termios.h>#include <errno.h>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;}