在Linux系统中开展串口通信编程工作,首先需要完成系统层面的各项配置,确保串口设备可被正常识别、访问和参数调整,这是后续编写串口通信代码的基础前提。

识别系统中的串口设备
Linux系统会将串口设备映射为/dev目录下的设备文件,常见的串口设备文件名包括ttyS0、ttyS1等对应物理串口,ttyUSB0、ttyUSB1等对应USB转串口设备。我们可以通过以下命令查看当前系统中存在的串口设备:
# 查看所有串口设备 ls -l /dev/ttyS* /dev/ttyUSB* 2>/dev/null # 查看串口设备详细信息 dmesg | grep tty
如果插入USB转串口设备后没有对应的ttyUSB文件生成,需要检查系统是否加载了对应的驱动模块,常见的USB转串口驱动如pl2303、ch341等,可通过modprobe 驱动名命令手动加载。
配置串口设备访问权限
默认情况下,普通用户没有权限直接访问串口设备,直接打开设备文件会返回权限拒绝的错误。我们可以通过两种方式解决权限问题:
临时修改设备权限
使用chmod命令临时修改指定串口设备的权限,这种方式重启后会失效:
# 给ttyUSB0设备添加读写权限 sudo chmod 666 /dev/ttyUSB0
永久配置权限规则
通过udev规则实现永久权限配置,避免每次重启后重新设置权限。首先创建udev规则文件:
sudo vim /etc/udev/rules.d/99-serial.rules
在文件中添加以下内容,允许所有用户访问串口设备:
KERNEL=="ttyS[0-9]*", MODE="0666" KERNEL=="ttyUSB[0-9]*", MODE="0666"
保存后重新加载udev规则即可生效:
sudo udevadm control --reload-rules sudo udevadm trigger
安装串口编程依赖工具
进行串口通信编程需要用到termios相关的头文件,同时可以安装一些调试工具方便测试。以Debian/Ubuntu系统为例,安装命令如下:
# 安装C语言开发依赖 sudo apt-get install build-essential # 安装串口调试工具 sudo apt-get install minicom cutecom
minicom是常用的命令行串口调试工具,可以通过minicom -s命令进入配置界面,设置串口波特率、数据位、停止位、校验位等参数,测试串口是否能正常收发数据。
串口通信编程基础配置示例
Linux下串口编程主要通过termios结构体配置串口参数,以下是一个完整的串口初始化代码示例,使用C语言实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
/**
* 初始化串口设备
* @param port 串口设备路径,如/dev/ttyUSB0
* @param baud_rate 波特率,如9600、115200
* @return 成功返回文件描述符,失败返回-1
*/
int serial_init(const char *port, int baud_rate) {
int fd;
struct termios options;
// 打开串口设备,可读可写,非阻塞模式
fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
perror("打开串口失败");
return -1;
}
// 获取当前串口参数
if (tcgetattr(fd, &options) != 0) {
perror("获取串口参数失败");
close(fd);
return -1;
}
// 设置波特率
int speed;
switch (baud_rate) {
case 9600: speed = B9600; break;
case 19200: speed = B19200; break;
case 38400: speed = B38400; break;
case 57600: speed = B57600; break;
case 115200: speed = B115200; break;
default: speed = B9600; break;
}
cfsetispeed(&options, speed);
cfsetospeed(&options, speed);
// 设置数据位为8位
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// 设置无校验位
options.c_cflag &= ~PARENB;
options.c_cflag &= ~PARODD;
// 设置1位停止位
options.c_cflag &= ~CSTOPB;
// 禁用硬件流控
options.c_cflag &= ~CRTSCTS;
// 启用接收,忽略调制解调器控制线
options.c_cflag |= CREAD | CLOCAL;
// 禁用软件流控
options.c_iflag &= ~(IXON | IXOFF | IXANY);
// 设置原始输入模式,不处理特殊字符
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
// 设置原始输出模式
options.c_oflag &= ~OPOST;
// 设置最小读取字符数和超时时间
options.c_cc[VMIN] = 1; // 至少读取1个字符
options.c_cc[VTIME] = 0; // 无超时
// 清空串口缓冲区
tcflush(fd, TCIFLUSH);
// 应用串口参数
if (tcsetattr(fd, TCSANOW, &options) != 0) {
perror("设置串口参数失败");
close(fd);
return -1;
}
return fd;
}
int main() {
int fd = serial_init("/dev/ttyUSB0", 115200);
if (fd == -1) {
return 1;
}
// 发送测试数据
char send_buf[] = "Hello Serial Portn";
int len = write(fd, send_buf, strlen(send_buf));
if (len > 0) {
printf("发送数据成功,长度:%dn", len);
}
// 接收数据
char recv_buf[1024];
len = read(fd, recv_buf, sizeof(recv_buf) - 1);
if (len > 0) {
recv_buf[len] = ' ';
printf("接收数据:%sn", recv_buf);
}
close(fd);
return 0;
}
常见问题排查
- 打开设备返回权限拒绝:检查udev规则是否配置正确,或者当前用户是否在dialout用户组中,可通过
sudo usermod -aG dialout $USER将当前用户加入dialout组,重新登录后生效。 - 数据收发乱码:检查收发双方的波特率、数据位、停止位、校验位是否完全一致,可通过minicom工具先测试参数配置是否正确。
- 无法识别USB转串口设备:检查设备是否插好,运行
lsusb命令查看系统是否识别到USB设备,若未识别可能是驱动未安装或硬件故障。