Linux下的串口通信
串口通信基础
串口通信是一种异步串行通信方式,通过数据线、地线等少数几根线路实现数据传输,在Linux系统中,串口设备通常被抽象为字符设备文件,位于/dev目录下,如/dev/ttyS0(COM1)、/dev/ttyUSB0(USB转串口)等,串口通信的核心参数包括波特率、数据位、停止位、校验位和流控,这些参数需在通信两端保持一致才能正常传输数据。

串口设备的管理与配置
在Linux中,串口设备文件由内核自动识别和管理,通过ls -l /dev/tty*命令可以查看系统中的串口设备,若设备未正确识别(如USB转串口),需加载ch341、ftdi_sio等内核模块,串口参数的配置可通过stty命令实现,例如设置波特率为115200、8位数据位、无校验位、1位停止位:
stty -F /dev/ttyS0 115200 cs8 -cstopb -parenb
setserial命令可用于查看或修改串口硬件属性,如UART类型、中断请求号(IRQ)等。
编程接口与库函数
Linux提供了多种串口编程接口,主要包括系统调用、C标准库及第三方库。
-
系统调用:
通过open()、read()、write()、close()等函数直接操作串口设备文件。int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); write(fd, "Hello", 5); read(fd, buffer, sizeof(buffer)); close(fd);需注意设置终端属性为原始模式(
c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG)),避免系统对输入数据进行缓冲或处理。
-
Termios库:
termios是Linux下配置串口的核心API,通过struct termios结构体设置串口参数。struct termios options; tcgetattr(fd, &options); cfsetispeed(&options, B115200); cfsetospeed(&options, B115200); options.c_cflag &= ~PARENB; tcsetattr(fd, TCSANOW, &options);
tcgetattr()和tcsetattr()分别用于获取和设置串口属性,TCSANOW表示立即生效。 -
第三方库:
如libserialport、Boost.Asio等库提供了更高级的封装,简化了跨平台串口编程。libserialport的sp_open()函数可自动处理设备权限和参数配置。
高级功能与调试技巧
-
非阻塞与超时设置:
通过O_NONDELAY标志或fcntl(fd, F_SETFL, FNDELAY)实现非阻塞读取,避免程序因等待数据而阻塞,超时可通过struct termios中的c_cc[VMIN]和c_cc[VTIME]设置,例如VMIN=0, VTIME=1表示读取1个字节后等待0.1秒。 -
流控机制:
硬件流控(RTS/CTS)和软件流控(XON/XOFF)可通过c_cflag的CRTSCTS和IXON/IXOFF位启用,防止数据溢出。
-
调试工具:
minicom、screen:交互式终端工具,可用于手动测试串口通信。cat /dev/ttyS0:直接读取串口数据,配合echo "data" > /dev/ttyS0发送数据。socat:灵活的端口转发工具,可实现串口与网络数据的双向转换。
应用场景与实例
串口通信在嵌入式系统、工业控制、物联网等领域广泛应用,在树莓派中通过/dev/ttyAMA0与传感器通信:
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
int main() {
int fd = open("/dev/ttyAMA0", O_RDWR);
struct termios options;
tcgetattr(fd, &options);
cfsetispeed(&options, B9600);
tcsetattr(fd, TCSANOW, &options);
write(fd, "AT\r\n", 4); // 发送AT指令
char buffer[100];
read(fd, buffer, sizeof(buffer)); // 读取响应
printf("%s\n", buffer);
close(fd);
return 0;
}
上述代码通过串口向模块发送AT指令并打印响应,适用于调试串口外设。
Linux下的串口通信通过设备文件和标准系统调用实现,灵活性和可扩展性强,掌握termios配置、编程接口及调试工具,可有效解决实际开发中的通信问题,随着物联网的发展,串口通信仍将在设备互联中发挥重要作用,开发者需深入理解其底层机制,以应对复杂的应用需求。