c串口通讯编程linux
- 行业动态
- 2025-01-31
- 4319
***:本文主要介绍Linux操作系统平台下的串口通信编程,涵盖串口基本原理、通信编程涉及的结构体及相关设置方法等,并以实例说明文件方法的实现步骤。
在Linux环境下使用C语言进行串口通讯编程,主要涉及到串口的配置、打开、读写以及关闭等操作,以下是详细的步骤和代码示例:
1、包含头文件
在进行串口编程时,需要包含以下头文件:
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <termios.h> #include <unistd.h> #include <string.h> #include <errno.h>
2、串口配置函数
定义一个函数来配置串口属性,包括波特率、数据位、停止位、校验位等。
int set_port_attr(int fd, int baudrate, int databit, const char *stopbit, char parity, int vtime, int vmin) { struct termios opt; if (tcgetattr(fd, &opt) != 0) { perror("tcgetattr"); return -1; } cfsetispeed(&opt, baudrate); cfsetospeed(&opt, baudrate); opt.c_cflag &= ~CSIZE; switch (databit) { case 5: opt.c_cflag |= CS5; break; case 6: opt.c_cflag |= CS6; break; case 7: opt.c_cflag |= CS7; break; case 8: opt.c_cflag |= CS8; break; default: fprintf(stderr, "Unsupported data size "); return -1; } opt.c_cflag &= ~PARENB; // Clear parity bit, disabling parity (most common) if (parity != 'N') { opt.c_cflag |= PARENB; // Enable parity if (parity == 'O') { opt.c_cflag |= PARODD; // Odd parity } else { opt.c_cflag |= PARODD; // Even parity } } if (strcmp(stopbit, "1") == 0) { opt.c_cflag &= ~CSTOPB; } else if (strcmp(stopbit, "2") == 0) { opt.c_cflag |= CSTOPB; } else { fprintf(stderr, "Unsupported stop size "); return -1; } opt.c_cflag &= ~CRTSCTS; // Turn off hardware flow control opt.c_cflag |= CREAD | CLOCAL; // Ignore modem controls, local connection only opt.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off software flow control opt.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars) opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // Disablecanonical mode and echo opt.c_cc[VMIN] = vmin; // Minimum number of characters to read opt.c_cc[VTIME] = vtime; // Timeout in deciseconds for non-canonical read tcflush(fd, TCIFLUSH); // Flush interface, discarding any data written to the object but not transmitted if (tcsetattr(fd, TCSANOW, &opt) != 0) { perror("tcsetattr"); return -1; } return 0; }
3、打开串口
使用open()
函数打开串口设备文件,串口设备文件位于/dev
目录下,如/dev/ttyS0
(对于标准串口)或/dev/ttyUSB0
(对于USB转串口设备)。
int open_serial(const char *device) { int fd = open(device, O_RDWR | O_NOCTTY | O_SYNC); if (fd < 0) { perror("open serial port"); return -1; } return fd; }
4、读写串口
使用write()
函数向串口写入数据,使用read()
函数从串口读取数据。
int write_to_serial(int fd, const unsigned char *data, size_t len) { ssize_t written = write(fd, data, len); if (written < 0) { perror("write to serial port"); return -1; } return written; } int read_from_serial(int fd, unsigned char *buffer, size_t len) { ssize_t read_bytes = read(fd, buffer, len); if (read_bytes < 0) { perror("read from serial port"); return -1; } return read_bytes; }
5、关闭串口
使用close()
函数关闭串口设备文件。
void close_serial(int fd) { close(fd); }
6、主函数示例
在主函数中,调用上述函数进行串口的打开、配置、读写和关闭操作。
int main() { const char *device = "/dev/ttyUSB0"; // 根据实际情况修改串口设备文件路径 int fd = open_serial(device); if (fd < 0) { return EXIT_FAILURE; } // 配置串口属性,例如波特率9600,无奇偶校验,8位数据位,1位停止位,无硬件流控 if (set_port_attr(fd, B9600, 8, "1", 'N', 15, 1) < 0) { close_serial(fd); return EXIT_FAILURE; } // 向串口写入数据 const char *data = "Hello, Serial Port!"; if (write_to_serial(fd, (const unsigned char *)data, strlen(data)) < 0) { close_serial(fd); return EXIT_FAILURE; } // 从串口读取数据 unsigned char buffer[100]; ssize_t read_bytes = read_from_serial(fd, buffer, sizeof(buffer) 1); if (read_bytes < 0) { close_serial(fd); return EXIT_FAILURE; } buffer[read_bytes] = '