串口通信是嵌入式系统中一种常见的通信方式,用于实现设备之间的数据传输。在嵌入式Linux系统中,串口通信通常通过UART(Universal Asynchronous Receiver/Transmitter)接口实现。UART是一种异步通信协议,适用于点对点的短距离通信。
串口通信基础知识
-
UART协议:
- UART是一种异步通信协议,不需要单独的时钟线来同步数据传输。
- 数据以帧的形式传输,每一帧包含起始位、数据位、奇偶校验位和停止位。
- 常见的数据位长度为7位或8位,奇偶校验位可选,停止位通常为1位或2位。
-
波特率:
- 波特率是指每秒传输的位数,常见的波特率有9600、115200等。
- 发送方和接收方必须设置相同的波特率,以确保正确传输数据。
-
串口设备文件:
- 在Linux系统中,串口设备通常被映射为设备文件,如
/dev/ttyS0
、/dev/ttyUSB0
等。 - 不同的硬件平台可能有不同的设备文件名。
- 在Linux系统中,串口设备通常被映射为设备文件,如
嵌入式Linux中的串口编程
在嵌入式Linux系统中,可以通过文件操作接口来实现串口通信。以下是一个基本的示例,展示如何打开、配置和使用串口设备。
打开串口设备
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>int open_serial_port(const char *device) {int fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY);if (fd == -1) {perror("Unable to open serial port");return -1;}return fd;
}
配置串口参数
int configure_serial_port(int fd, speed_t baud_rate) {struct termios tty;// 获取当前的串口设置if (tcgetattr(fd, &tty) != 0) {perror("Error from tcgetattr");return -1;}// 设置波特率cfsetospeed(&tty, baud_rate);cfsetispeed(&tty, baud_rate);// 设置数据格式tty.c_cflag &= ~PARENB; // 清除校验位tty.c_cflag &= ~CSTOPB; // 1个停止位tty.c_cflag &= ~CSIZE; // 清除数据位掩码tty.c_cflag |= CS8; // 设置数据位为8位tty.c_cflag &= ~CRTSCTS; // 关闭硬件流控tty.c_cflag |= CREAD | CLOCAL; // 启用接收器,忽略控制行// 设置输入输出模式tty.c_lflag &= ~ICANON;tty.c_lflag &= ~ECHO;tty.c_lflag &= ~ECHOE;tty.c_lflag &= ~ISIG;tty.c_iflag &= ~(IXON | IXOFF | IXANY); // 关闭软件流控tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXOFF);tty.c_oflag &= ~OPOST;tty.c_oflag &= ~ONLCR;// 设置最小字符数和等待时间tty.c_cc[VMIN] = 1;tty.c_cc[VTIME] = 10; // 10 deciseconds// 应用新的设置if (tcsetattr(fd, TCSANOW, &tty) != 0) {perror("Error from tcsetattr");return -1;}return 0;
}
读取和写入数据
void write_to_serial_port(int fd, const char *data, size_t length) {ssize_t written = write(fd, data, length);if (written == -1) {perror("Error writing to serial port");} else if (written != length) {fprintf(stderr, "Incomplete write to serial port: %ld of %zu\n", written, length);}
}void read_from_serial_port(int fd) {char buffer[256];ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);if (bytes_read == -1) {perror("Error reading from serial port");} else if (bytes_read > 0) {buffer[bytes_read] = '\0';printf("Received: %s\n", buffer);}
}
示例程序
int main() {const char *device = "/dev/ttyS0";speed_t baud_rate = B9600;const char *message = "Hello, Serial Port!\n";int fd = open_serial_port(device);if (fd == -1) {return EXIT_FAILURE;}if (configure_serial_port(fd, baud_rate) == -1) {close(fd);return EXIT_FAILURE;}write_to_serial_port(fd, message, strlen(message));read_from_serial_port(fd);close(fd);return EXIT_SUCCESS;
}
注意事项
- 波特率匹配:确保发送方和接收方的波特率设置一致。
- 错误处理:在实际应用中,需要添加更多的错误处理逻辑,以提高系统的健壮性。
- 权限问题:访问串口设备文件可能需要适当的权限,可以通过
sudo
或更改文件权限来解决。
通过以上步骤,你可以在嵌入式Linux系统中实现串口通信,实现设备之间的数据传输。