Linux下串口编程
Posted DS小龙哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux下串口编程相关的知识,希望对你有一定的参考价值。
1.1 串口的名称
1.1.2 PC机的串口节点名称
串口的节点在/dev下边。
计算机本身的串口:ttySx
USB串口:ttyUSBx
虚拟机右下角可以将USB串口设备挂载到dev下。
1.1.2 串口测试命令: microcom
命令使用方法:
[root@wbyq ]# microcom --help
BusyBox v1.23.2 (2020-09-04 15:21:06 CST) multi-call binary.
Usage: microcom [-d DELAY] [-t TIMEOUT] [-s SPEED] [-X] TTY
Copy bytes for stdin to TTY and from TTY to stdout
-d Wait up to DELAY ms for TTY output before sending every
next byte to it
-t Exit if both stdin and TTY are silent for TIMEOUT ms
-s Set serial line to SPEED
-X Disable special meaning of NUL and Ctrl-X from stdin
参数如下:
-d 表示延时时间。发送一个字节后等待一段时间发送下一个字节.
-t 表示超时时间,超多少时间就自动退出。单位为ms
-s 表示波特率。
-X 禁用stdin中NUL和Ctrl-X特殊含义。
TTY 指定串口设备节点。如SAC0。
测试命令如下:
[root@wbyq ]# microcom -t 5000 -s 115200 /dev/ttySAC2
1.2 串口基本操作
1.2.1 打开串口
打开串口连接的时候,程序在open函数中除了Read+Write模式以外还需要指定O_NOCTTY选项:
fd=open("/dev/ttyUSB0",O_RDWR|O_NOCTTY);
标志O_NOCTTY告诉系统这个程序不会成为这个端口上的“控制终端”。如果不这样做的话,所有的输入,比如键盘上过来的Ctrl+C中止信号等等,会影响到你的进程。但是通常情况下,用户程序不会使用这个选项。
1.2.2向串口写数据
Linux下一切皆文件,写数据直接使用write、fputs等函数即可直接向串口发送数据。
n = write(fd, "1234\\r\\n", 6);
1.2.3从串口读数据
读数据的时候需要找准时机,需要知道串口何时有数据,可以使用linux下的轮询机制进行监控串口的文件描述符。
比如: poll、select、epoll机制等。也可以使用异步通知机制:fasync。
cnt=read(fd,buff,1024);
1.2.4 关闭串口
可以使用close系统调用关闭串口: close(fd);
1.3 配置串口
1.3.1 刷新输入输出缓冲区
函数原型: int tcflush(int fd, int queue_selector);
函数功能: 丢弃写入或者收到但是没有读取的数据.
函数参数:
int文件描述符.
int queue_selector:
TCIFLUSH
刷新已接收但未读取的数据。
TCOFLUSH
刷新已写入但未传输的数据。
TCIOFLUSH 刷新已接收但未读取的数据,以及已写入但未传输的数据。
1.3.2 设置输入输出波特率
speed_t cfgetispeed(const struct termios *termios_p);
函数功能: 获取输入波特率.
speed_t cfgetospeed(const struct termios *termios_p);
函数功能: 获取输出波特率.
int cfsetispeed(struct termios *termios_p, speed_t speed);
函数功能: 设置输入波特率.
int cfsetospeed(struct termios *termios_p, speed_t speed);
函数功能: 设置输出波特率.
波特率可以设置以下的值:
B0
B50
B75
B110
B134
B150
B200
B300
B600
B1200
B1800
B2400
B4800
B9600
B19200
B38400
B57600
B115200
B230400
波特率设置示例:
struct termios uart_cfg;
memset(&uart_cfg,0,sizeof(struct termios));
cfsetispeed(&uart_cfg,B115200); //设置输入波特率
cfsetospeed(&uart_cfg,B115200); //设置输出波特率
1.3.3 设置串口属性参数
进行串口编程时,最重要的是tcgetattr和tcsetattr这两个函数,这两个函数可以设置串口的参数和获取串口已经配置的参数。
比如: 波特率、停止位、数据位、奇偶校验位等.
int tcgetattr(int fd, struct termios *termios_p);
函数功能: 获取终端属性参数.
int tcsetattr(int fd, int optional_actions,const struct termios *termios_p);
函数功能: 设置终端属性参数.
参数介绍:
int文件描述符.
int设置更改的时机.
TCSANOW
更改立即发生。
TCSADRAIN
在传输完所有写入fd的输出之后,将发生更改。
TCSAFLUSH
将所有输出写入fd引用的对象之后,将发生更改发送,并且所有已接收但未读取的输入将被丢弃在进行更改之前。
const struct termios *termios_p : 保存配置属性的结构体
配置示例:
struct termios uart_cfg;
memset(&uart_cfg,0,sizeof(struct termios));
cfsetispeed(&uart_cfg,B115200); //设置输入波特率
cfsetospeed(&uart_cfg,B115200); //设置输出波特率
uart_cfg.c_cflag &= ~CSIZE; //清除串口的数据位
uart_cfg.c_cflag |= CS8; //配置串口的数据位为 8 位
uart_cfg.c_cflag &= ~CSTOPB; //配置的停止位:1 个
uart_cfg.c_cflag |= CREAD; //使能接收
uart_cfg.c_cflag &= ~PARENB; //不使用奇偶校验
tcsetattr(fd,TCSANOW,&uart_cfg);
1.4 struct termios 结构体介绍
Struct termios结构体包含了以下成员:
tcflag_t c_iflag; /* 输入模式设置 */
tcflag_t c_oflag; /* 输出模式设置 */
tcflag_t c_cflag; /* 控制模式设置 */
tcflag_t c_lflag; /* 本地模式 */
cc_t c_cc[NCCS]; /* 控制字符 */
1.4.1 c_iflag
输入模式标志,控制终端输入方式
c_iflag参数表:
键 值 | 说 明 |
IGNBRK | 忽略BREAK键输入 |
BRKINT | 如果设置了IGNBRK,BREAK键输入将被忽略 |
IGNPAR | 忽略奇偶校验错误 |
PARMRK | 标识奇偶校验错误 |
INPCK | 允许输入奇偶校验 |
ISTRIP | 去除字符的第8个比特 |
INLCR | 将输入的NL(换行)转换成CR(回车) |
IGNCR | 忽略输入的回车 |
ICRNL | 将输入的回车转化成换行(如果IGNCR未设置的情况下) |
IUCLC | 将输入的大写字符转换成小写字符(非POSIX) |
IXON | Linux下串口编程 |