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;
我仅使用写入功能通过串口传输数据。出于某种原因,当我收到此数据时,\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;