
Linux 串口编程:解锁设备通信的钥匙
在嵌入式系统、物联网(IoT)以及各类硬件设备之间,串口通信(Serial Communication)扮演着举足轻重的角色
它以其简单、可靠和广泛兼容性的特点,成为许多低速率、长距离数据传输的首选方案
而在Linux操作系统下,通过C语言进行串口编程,不仅能够充分发挥Linux系统的强大功能,还能实现高效、灵活的设备通信
本文将深入探讨Linux串口编程的精髓,从基础知识到实战应用,带你领略这一技术的无限魅力
一、串口通信基础
串口通信,全称为串行通信(Serial Communication),是一种数据按位顺序传输的通信方式
与传统的并行通信相比,虽然其传输速率较慢,但所需的线路资源少,易于实现长距离传输,且成本较低
串口通信的基本参数包括波特率(Baud Rate)、数据位(Data Bits)、停止位(Stop Bits)和奇偶校验(Parity),这些参数决定了通信双方如何理解彼此发送的数据
- 波特率:指每秒传输的比特数,常见的波特率有9600、19200、38400、115200等
- 数据位:每个数据包中的有效数据位数,通常为7位或8位
停止位:用于标识数据包结束,通常为1位或2位
- 奇偶校验:用于检测数据传输中的错误,分为无校验(None)、奇校验(Odd)、偶校验(Even)等
二、Linux下的串口编程环境
Linux系统提供了丰富的接口和工具来支持串口编程
其中,`termios`结构体是核心,它定义了串口通信的各种参数和配置
在C语言中,通过`termios.h`头文件中的函数,可以方便地对串口进行配置和控制
- 打开串口:使用标准的open()函数,通过指定设备文件(如`/dev/ttyS0`、`/dev/ttyUSB0`)来打开串口
- 配置串口:通过tcgetattr()获取当前串口配置,使用`cfsetispeed()`和`cfsetospeed()`设置波特率,调整`c_cflag`、`c_lflag`、`c_iflag`、`c_oflag`等字段来配置数据位、停止位、奇偶校验等参数,最后通过`tcsetattr()`应用配置
- 读写操作:使用read()和write()函数进行数据的读写
对于非阻塞或异步操作,可以结合`select()`、`poll()`或`epoll()`机制
- 关闭串口:使用close()函数关闭串口设备
三、实战:Linux串口编程示例
下面是一个简单的Linux串口编程示例,演示如何打开串口、配置参数、发送和接收数据,并最终关闭串口
include
include
include
include
include
include
include
int set_serial_attributes(int fd, int speed) {
struct termios tty;
if(tcgetattr(fd, &tty) != 0) {
perror(tcgetattr);
return -1;
}
cfsetospeed(&tty,speed);
cfsetispeed(&tty,speed);
tty.c_cflag= (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
tty.c_iflag &= ~IGNBRK; // disable break processing
tty.c_lflag = 0; // no signaling chars, no echo,
// no canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc【VMIN】 = 1; // read doesnt block
tty.c_cc【VTIME】 = 5; // 0.5 seconds read timeout
tty.c_iflag &=~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
tty.c_cflag|= (CLOCAL | CREAD); // ignore modem controls,
// enable reading
tty.c_cflag&= ~(PARENB | PARODD); // shut off parity
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
if(tcsetattr(fd, TCSANOW, &tty) != 0) {
perror(tcsetattr);
return -1;
}
return 0;
}
int main() {
charportname = /dev/ttyUSB0;
int fd =open(portname, O_RDWR | O_NOCTTY | O_SYNC);
if(fd < {
perror(open);
return 1;
}
if(set_serial_attributes(fd, B115200) < 0) {
close(fd);
return 1;
}
charwrite_buf【】 = Hello, Serial Port!
;
intn_written =write(fd,write_buf,sizeof(write_buf));
if(n_written < {
perror(write);
close(fd);
return 1;
}
charrea