Linux串口应用编程
创始人
2025-05-29 02:38:50
0

一、 串口API

在这里插入图片描述
在Linux系统中,操作设备的统一接口就是:open/ioctl/read/write。
对于UART,又在ioctl之上封装了很多函数,主要是用来设置行规程。
所以对于UART,编程的套路就是:

  • open
  • 设置行规程,比如波特率、数据位、停止位、检验位、RAW模式、一有数据就返回
  • read/write
    怎么设置行规程?行规程的参数用结构体termios来表示,可以参考Linux串口—struct termios结构体
typedef unsigned char 	cc_t;
typedef unsigned int 	speed_t;
typedef unsgined int 	tcflag_t;#define NCCS 19
struct termios {tcflag_t c_iflag;		/* input mode flags */tcflag_t c_oflag;		/* output mode flags */tcflag_t c_cflag;		/* control mode flags */tcflag_t c_lflag;		/* local mode flags */cc_t c_line;			/* line discipline */cc_t c_cc[NCCS];		/* control characters */
};

这些函数在名称上有一些惯例:

  • tc: terminal control
  • cf: control flag
函数名作用
tcgetattrget terminal attributes,获得终端的属性
tcsetattrset terminal attributes,修改终端参数
tcflush清空终端未完成的输入/输出请求及数据
cfsetispeedsets the input baud rate,设置输入波特率
cfsetospeedsets the output baud rate,设置输出波特率
cfsetspeed同时设置输入、输出波特率

函数不多,主要是需要设置好termios中的参数,这些参数很复杂,可以参考Linux串口—struct termios结构体。

二、编程

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop)
{struct termios newtio, oldtio;if(tcgetattr(fd, &oldtio) != 0) {perror("SetupSerial 1");return -1;}bzero(&newtio, sizeof(newtio));newtio.c_cflag |= CLOCAL|CREAD;newtio.c_cflag &= ~CSIZE;newtio.c_lflag &= ~(ICANON|ECHO|ECHOE|ISIG);newtio.c_oflag &= ~OPOST;switch(nBits) {case 7:newtio.c_cflag |= CS7;break;case 8:newtio.c_cflag |= CS8;break;}switch(nEvent) {case 0: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;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[VMIN] = 1;newtio.c_cc[VTIME] = 0;tcflush(fd, TCIFLUSH);if((tcsetattr(fd, TCSANOW, &newtio)) != 0) {perror("com set error");return -1;}return 0;
}int open_port(char *com)
{int fd;fd = open(com, O_RDWR|O_NOCTTY);if(-1 == fd) {return -1;}if(fcntl(fd, F_SETFL, 0) < 0) {printf("fcntl failed\n");return -1;}return fd;
}int main(int argc, char *argv[])
{int fd;int iRet;char c;if(argc != 2) {printf("Usage: \n");printf("%s \n", argv[0]);return -1;}fd = open_port(argv[1]);if(fd < 0) {printf("open %s err!\n", argv[1]);return -1;}iRet = set_opt(fd, 115200, 8, 'N', 1);if(iRet) {printf("set port err!\n");return -1;}printf("Enter a char: ");while(1) {scanf("%c", &c);iRet = write(fd, &c, 1);iRet = read(fd, &c, 1);if(iRet == 1) {printf("get: %02x %c\n", c, c);} else {printf("can not get data\n");}}return 0;
}

三、上机实验

短接串口的RX和TX

root@npi:~/test# ./a.out /dev/ttymxc2 
Enter a cahr: a
get: 61 a
get: 0a get: 0a get: 0a a 
get: 61 a
get: 0a 

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...