当我尝试写入 uart 时写入 0D 0A 而不是 0A
writting 0D 0A insted of 0A when I tried to write into uart
以下代码配置UART端口。
const char *UART2_path="/dev/ttymxc2";
int UART2;
void UART2_open(const char *UART2_path)
{
int flags = O_RDWR | O_NOCTTY ;
UART2 = open(UART2_path,flags);
tcgetattr(UART2, &ttyurt); //Get the current attributes of the serial port //
//Setting baud rate (input and output)
cfsetispeed(&ttyurt, B115200);
cfsetospeed(&ttyurt, B115200);
ttyurt.c_cflag &= ~PARENB; // Disables the Parity Enable bit(PARENB) //
ttyurt.c_cflag &= ~CSTOPB; // Clear CSTOPB, configuring 1 stop bit //
ttyurt.c_cflag &= ~CSIZE; // Using mask to clear data size setting //
ttyurt.c_cflag |= CS8; // Set 8 data bits //
ttyurt.c_cflag &= ~CRTSCTS; // Disable Hardware Flow Control //
tcsetattr(UART2, TCSANOW, &ttyurt); // Write the configuration to the termios structure//
tcflush(UART2, TCIFLUSH);
}
---------
--------
--------
buffer[8]={0x1f,0x0a,0x1a,0x89,0x85,0xbf,0x36,0x40};
write(UART2,&buffer,strlen(buffer));//sending on uart
expected output==>1f0a8985bf3640
actual output ==>1f0d0a8985bf3640
我可以发送数据,但由于某些原因 0x0A
发送的字符被接收为 0x0D 0x0A
。我相当确定此端口配置中的某些内容正在执行此操作。
0a
之前的额外字节 0d
?
您似乎是 UNIX/Linux 与 Windows“换行”/“换行”处理的另一个受害者:UNIX/Linux 使用单个字符,例如 0A
(行feed) 或 0D
(换行符)用于转到另一行,而 Windows 使用组合 0D0A
,因此很可能您有一些程序将您的“I-believe-the-data-to-be-UNIX-like”转换为“Windows-like”。
这可能会走得更远:我遇到过 UNIX 文件被发送到 Windows 计算机的情况,用户正在使用 Windows 文件查看器来查看文件的内容,并且进行该转换的是文件查看器本身。因此,我建议您检查所有中间程序。
writting 0D 0A insted of 0A when I tried to write into uart
这似乎是由不适合您的情况的 termios(错误)配置引起的。 termios 层能够 translating/expanding 每次出现 \n
到 \r\n
用于输出(即 ONLCR 属性,通常是 默认启用)。
The following code configures UART port.
您的程序访问串行终端(即 /dev/tty...)而不是“UART 端口”。在您的程序和 UART 硬件之间有多层处理。参见 Linux serial drivers
您的初始化代码已正确实现(即根据 Setting Terminal Modes Properly),但这只是将串行线路参数设置为 115200 8N1 并且没有硬件流控制的最低限度。绝对没有指定其他 termios 属性,这意味着您的程序将使用任何以前的(随机?)设置(例如 ONLCR 属性),并且可能偶尔会出现错误。
使用串行终端和 termios 配置时最重要的考虑因素是确定数据是否应以规范(作为文本行)或 non-canonical(也称为原始或二进制)模式处理。规范模式提供额外的处理,以促进 reading/writing 文本作为行,由 End-of-Line 个字符分隔。否则,系统调用将针对任意数量的字节执行。有关详细信息,请参阅 this answer。
您的输出数据似乎不是 (ASCII) 文本,因此您可能想使用 non-canonical(又名原始)模式。对于原始输出,您的程序应指定:
ttyurt.c_oflag &= ~OPOST;
这将禁止 termios 对输出进行任何数据转换。
但是您的 termios 初始化也不完整,无法阅读。
有关 non-canonical 模式的正确和简洁的 termios 初始化,请参阅 this answer.
如果您需要规范模式,请参考 .
以下代码配置UART端口。
const char *UART2_path="/dev/ttymxc2";
int UART2;
void UART2_open(const char *UART2_path)
{
int flags = O_RDWR | O_NOCTTY ;
UART2 = open(UART2_path,flags);
tcgetattr(UART2, &ttyurt); //Get the current attributes of the serial port //
//Setting baud rate (input and output)
cfsetispeed(&ttyurt, B115200);
cfsetospeed(&ttyurt, B115200);
ttyurt.c_cflag &= ~PARENB; // Disables the Parity Enable bit(PARENB) //
ttyurt.c_cflag &= ~CSTOPB; // Clear CSTOPB, configuring 1 stop bit //
ttyurt.c_cflag &= ~CSIZE; // Using mask to clear data size setting //
ttyurt.c_cflag |= CS8; // Set 8 data bits //
ttyurt.c_cflag &= ~CRTSCTS; // Disable Hardware Flow Control //
tcsetattr(UART2, TCSANOW, &ttyurt); // Write the configuration to the termios structure//
tcflush(UART2, TCIFLUSH);
}
---------
--------
--------
buffer[8]={0x1f,0x0a,0x1a,0x89,0x85,0xbf,0x36,0x40};
write(UART2,&buffer,strlen(buffer));//sending on uart
expected output==>1f0a8985bf3640
actual output ==>1f0d0a8985bf3640
我可以发送数据,但由于某些原因 0x0A
发送的字符被接收为 0x0D 0x0A
。我相当确定此端口配置中的某些内容正在执行此操作。
0a
之前的额外字节 0d
?
您似乎是 UNIX/Linux 与 Windows“换行”/“换行”处理的另一个受害者:UNIX/Linux 使用单个字符,例如 0A
(行feed) 或 0D
(换行符)用于转到另一行,而 Windows 使用组合 0D0A
,因此很可能您有一些程序将您的“I-believe-the-data-to-be-UNIX-like”转换为“Windows-like”。
这可能会走得更远:我遇到过 UNIX 文件被发送到 Windows 计算机的情况,用户正在使用 Windows 文件查看器来查看文件的内容,并且进行该转换的是文件查看器本身。因此,我建议您检查所有中间程序。
writting 0D 0A insted of 0A when I tried to write into uart
这似乎是由不适合您的情况的 termios(错误)配置引起的。 termios 层能够 translating/expanding 每次出现 \n
到 \r\n
用于输出(即 ONLCR 属性,通常是 默认启用)。
The following code configures UART port.
您的程序访问串行终端(即 /dev/tty...)而不是“UART 端口”。在您的程序和 UART 硬件之间有多层处理。参见 Linux serial drivers
您的初始化代码已正确实现(即根据 Setting Terminal Modes Properly),但这只是将串行线路参数设置为 115200 8N1 并且没有硬件流控制的最低限度。绝对没有指定其他 termios 属性,这意味着您的程序将使用任何以前的(随机?)设置(例如 ONLCR 属性),并且可能偶尔会出现错误。
使用串行终端和 termios 配置时最重要的考虑因素是确定数据是否应以规范(作为文本行)或 non-canonical(也称为原始或二进制)模式处理。规范模式提供额外的处理,以促进 reading/writing 文本作为行,由 End-of-Line 个字符分隔。否则,系统调用将针对任意数量的字节执行。有关详细信息,请参阅 this answer。
您的输出数据似乎不是 (ASCII) 文本,因此您可能想使用 non-canonical(又名原始)模式。对于原始输出,您的程序应指定:
ttyurt.c_oflag &= ~OPOST;
这将禁止 termios 对输出进行任何数据转换。
但是您的 termios 初始化也不完整,无法阅读。
有关 non-canonical 模式的正确和简洁的 termios 初始化,请参阅 this answer.
如果您需要规范模式,请参考