Linux C串口编程基础与实践
在嵌入式开发、工业控制以及通信领域,串口编程是Linux系统下与外部设备进行数据交互的重要技术,通过C语言操作串口,开发者可以实现高效、稳定的设备通信,本文将详细介绍Linux C串口编程的核心概念、关键步骤及代码实现,帮助读者快速掌握这一技术。

串口通信基础
串口(Serial Port)是一种按位(bit)传输数据的通信方式,常用于连接调制解调器、GPS模块、单片机等设备,Linux系统将串口设备抽象为文件,如/dev/ttyS0(COM1)、/dev/ttyUSB0(USB转串口),通过标准文件操作函数(open()、read()、write()、close())即可完成通信。
串口通信的关键参数包括:
- 波特率(Baud Rate):数据传输速率,如9600、115200等。
- 数据位(Data Bits):通常为8位。
- 校验位(Parity):无校验(None)、奇校验(Odd)、偶校验(Even)。
- 停止位(Stop Bits):通常为1位或2位。
串口配置与初始化
在Linux C中,串口配置主要通过修改termios结构体实现,以下是配置步骤及关键代码:

1 打开串口设备
int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0) {
perror("Failed to open serial port");
exit(EXIT_FAILURE);
}
fcntl(fd, F_SETFL, 0); // 设置为阻塞模式
2 配置串口参数
struct termios options; tcgetattr(fd, &options); // 获取当前配置 // 设置波特率 cfsetispeed(&options, B115200); cfsetospeed(&options, B115200); // 设置数据位、校验位、停止位 options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; // 8位数据位 options.c_cflag &= ~PARENB; // 无校验 options.c_cflag &= ~CSTOPB; // 1位停止位 // 启用接收、忽略控制线 options.c_cflag |= (CLOCAL | CREAD); // 设置原始输入模式 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 设置超时(100ms) options.c_cc[VMIN] = 0; options.c_cc[VTIME] = 1; tcsetattr(fd, TCSANOW, &options); // 应用配置
串口数据读写
配置完成后,可通过read()和write()函数进行数据传输:
1 写数据
char *send_data = "Hello, Serial Port!";
int write_len = write(fd, send_data, strlen(send_data));
if (write_len < 0) {
perror("Failed to write data");
}
2 读数据
char buffer[256];
int read_len = read(fd, buffer, sizeof(buffer) - 1);
if (read_len > 0) {
buffer[read_len] = '\0';
printf("Received: %s\n", buffer);
}
高级功能与错误处理
1 串口状态查询
通过ioctl()函数可以获取串口状态,如线路信号(CTS/RTS):
int status;
ioctl(fd, TIOCMGET, &status);
if (status & TIOCM_CTS) {
printf("CTS is active\n");
}
2 错误处理与超时控制
使用tcflush()清空缓冲区,避免数据残留:

tcflush(fd, TCIOFLUSH); // 清空输入输出缓冲区
3 常见问题及解决方案
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 数据传输乱码 | 波特率或参数不匹配 | 检查termios配置 |
read()阻塞 |
未设置非阻塞模式 | 使用O_NDELAY或fcntl() |
| 数据丢失 | 缓冲区溢出 | 增加缓冲区大小或及时读取 |
完整示例代码
以下是一个完整的串口通信示例,实现双向数据收发:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
int init_serial(const char *port) {
int fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0) return -1;
struct termios options;
tcgetattr(fd, &options);
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 1;
tcsetattr(fd, TCSANOW, &options);
return fd;
}
int main() {
int fd = init_serial("/dev/ttyS0");
if (fd < 0) {
perror("Serial init failed");
return 1;
}
char *msg = "Test Message";
write(fd, msg, strlen(msg));
char buf[256];
int n = read(fd, buf, sizeof(buf));
if (n > 0) {
buf[n] = '\0';
printf("Received: %s\n", buf);
}
close(fd);
return 0;
}
Linux C串口编程是嵌入式开发的核心技能之一,通过合理配置termios结构体和灵活运用文件操作函数,可实现稳定可靠的设备通信,开发者需注意参数匹配、错误处理及超时控制,同时结合实际需求优化数据收发逻辑,掌握这些技术,将为物联网、工业自动化等领域的开发奠定坚实基础。




















