c中串口传输时字符\r转为\n

Character \r transforms to \n when transmitting through serial port in c

我仅使用写入功能通过串口传输数据。出于某种原因,当我收到此数据时,\r (0x0d) 转换为 \n (0x0a)。这可能是由于我在打开端口时使用了 termios 选项,但我不知道我可以更改什么。

我编写了打开二进制图像的代码,将其数据保存到 uint8_t 数组,并使用写入系统调用发送数据,并使用读取系统调用读取数据。

发送端口和接收端口都打开了相同的选项。

每次收到的所有字节仅在完全相同的字节上有所不同,它们都是 \r 字节。没有数据丢失。

对于一些额外的上下文:我正在使用 2 个 arduino 通过串行端口传输数据,其中 RX0 连接到 TX0,TX0 连接到 RX0。我也在做空。基本上我使用 arduinos 来分离 TX 和 RX 信号,我并没有真正使用实际的 arduino 芯片或任何东西。

我正在为接收缓冲区和传输缓冲区分配正确数量的内存

#include <termios.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
int serialport_init(const char* serialport, int baud) {
    struct termios toptions;
    int fd;
    fd = open(serialport, O_RDWR | O_NONBLOCK);

    if (fd == -1) {
        return -1;
    }

    if (tcgetattr(fd, &toptions) < 0) {
        return -1;
    }
    speed_t brate = baud;
    brate = B115200;
    cfsetispeed(&toptions, brate);
    cfsetospeed(&toptions, brate);

    // 8N1 - * bits no parity
    toptions.c_cflag &= ~PARENB;
    toptions.c_cflag &= ~CSTOPB;
    toptions.c_cflag &= ~CSIZE;
    toptions.c_cflag |= CS8;

    toptions.c_cflag |= CREAD | CLOCAL;  // turn on READ & ignore ctrl lines
    toptions.c_iflag &= ~(IXON | IXOFF | IXANY);  // turn off s/w flow ctrl

    toptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);  // make raw
    toptions.c_oflag &= ~OPOST;                           // make raw

    toptions.c_cc[VMIN] = 0;
    toptions.c_cc[VTIME] = 0;

    tcsetattr(fd, TCSANOW, &toptions);
    if (tcsetattr(fd, TCSAFLUSH, &toptions) < 0) {
        return -1;
    }

    return fd;
}


int serialport_write_bytes(int fd, const uint8_t* bytes, size_t n_bytes) {
    ssize_t n;
    size_t bytes_written = 0;

    while (bytes_written < (size_t)n_bytes) {
        n = write(fd, &bytes[bytes_written], n_bytes - bytes_written);
        if (n == -1) continue;
        if (n == 0) {
            continue;
        }
        bytes_written += n;
        printf("wrote total of: %ld bytes n=%ld\n", bytes_written, n);
        tcflush(fd, TCIOFLUSH);  // Flush port - same result if not used
        usleep(10 * 1000);       // wait 1 msec try again. Maybe can remove
    }
    printf("Total bytes written: %ld\n", bytes_written);
    return 0;
}


int serialport_read_bytes(int fd, uint8_t* buf, int n_bytes, int millis) {
    ssize_t n;
    size_t bytes_read = 0;

    while (bytes_read < (size_t)n_bytes) {
        n = read(fd, &buf[bytes_read], n_bytes - bytes_read);
        if (n == -1) return -1;  // couldn't read
        if (n == 0) {
            usleep(millis * 1000);  // wait 1 msec try again
            continue;
        }
        printf("read total: %ld bytes\n", bytes_read);
        bytes_read += n;
    }
    printf("Total bytes read: %ld\n", bytes_read);
    return 0;
}

我认为您还需要取消设置 ICRNL 标志。

https://viewsourcecode.org/snaptoken/kilo/02.enteringRawMode.html#fix-ctrl-m

toptions.c_iflag &= ~ICRNL;