当前位置:首页 > 行业动态 > 正文

c串口通讯编程linux

***:本文主要介绍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] = '
0