当我尝试写入 uart 时,写入 0D 0A 而不是 0A

发布于 2025-01-15 14:37:14 字数 1461 浏览 2 评论 0原文

以下代码配置 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

The following code configures UART port.

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  

I'm able to send data, but for some reason 0x0A sent characters are received as 0x0D 0x0A. I'm fairly sure something in this port configuration is doing this.

extra byte 0d before 0a?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧人 2025-01-22 14:37:14

当我尝试写入uart时,写入0D 0A而不是0A

这似乎是由不适合您的情况的 termios(错误)配置引起的。 termios 层能够将每次出现的 \n 转换/扩展为 \r\n 以进行输出(即 ONLCR 属性,即通常默认启用)。

以下代码配置 UART 端口。

您的程序访问串行终端(即/dev/tty...)而不是“UART 端口”。您的程序和 UART 硬件之间存在多个处理层。请参阅 Linux 串行驱动程序

您的初始化代码已正确实现(即每个正确设置终端模式),但这只是最低限度,仅将串行线路参数设置为 115200 8N1,并且没有硬件流量控制。绝对没有指定其他 termios 属性,这意味着您的程序将使用任何先前的(随机?)设置(例如 ONLCR 属性),并且可能偶尔会出现错误行为。

使用串行终端和 termios 配置时最重要的考虑因素是确定是否应以规范(作为文本行)或非规范(也称为原始或二进制)模式处理数据。规范模式提供了额外的处理,以方便以行的方式读取/写入文本,并由行尾字符分隔。否则,将对任意数量的字节执行系统调用。有关更多详细信息,请参阅此答案

您的输出数据似乎不是(ASCII)文本,因此您可能想使用非规范(又名原始)模式。对于原始输出,您的程序应指定:

ttyurt.c_oflag &= ~OPOST;

这将禁止 termios 对输出进行任何数据转换。

但是您的 termios 初始化也不完整,无法阅读。
有关非规范模式的正确且简洁的 termios 初始化,请参阅 这个答案
如果您需要规范模式,请参阅此答案

writting 0D 0A insted of 0A when I tried to write into uart

That appears to caused by a termios (mis)configuration that is inappropriate for your situation. The termios layer is capable of translating/expanding each occurrence of \n to \r\n for output (i.e. the ONLCR attribute, which is typically enabled by default).

The following code configures UART port.

Your program accesses a serial terminal (i.e. /dev/tty...) rather than a "UART port". There are several layers of processing in between your program and the UART hardware. See Linux serial drivers

Your initialization code is properly implemented (i.e. per Setting Terminal Modes Properly), but it is just the bare minimum that sets only the serial line parameters to 115200 8N1 and no HW flow control. Absolutely no other termios attributes are specified, which means that your program will use whatever previous (random?) settings (such as the ONLCR attribute), and may occasionally misbehave.

The most important consideration when using a serial terminal and termios configuration is determining whether the data should be handled in canonical (as lines of text) or non-canonical (aka raw or binary) mode. Canonical mode provides additional processing to facilitate the reading/writing of text as lines, delimited by End-of-Line characters. Otherwise syscalls are performed for an arbitrary number of bytes. See this answer for more details.

Your output data appears to be not (ASCII) text, so presumably you want to use non-canonical (aka raw) mode. For raw output, your program should specify:

ttyurt.c_oflag &= ~OPOST;

This will inhibit any data conversion on output by termios.

But your termios initialization is also incomplete for reading.
For a proper and concise termios initialization for non-canonical mode, see this answer.
If instead you need canonical mode, then refer to this answer.

两人的回忆 2025-01-22 14:37:14

您似乎是 UNIX/Linux 与 Windows“换行”/“换行”处理的另一个受害者:UNIX/Linux 使用单个字符,例如 0A (换行)或 0D(换行符)用于转到另一行,而 Windows 使用组合 0D0A,因此很可能您有一些程序可以将您的“我相信数据转换为类似 UNIX 的数据” ” 变为“类似 Windows”。

这可能会走得很远:我遇到过这样的情况:UNIX 文件被发送到 Windows 计算机,用户使用 Windows 文件查看器来查看文件的内容,而文件查看器本身正在执行转换。因此我建议您检查所有中间程序。

You seem to be another victim of UNIX/Linux versus Windows "newline"/"line feed" handling: UNIX/Linux uses single character, like 0A (line feed) or 0D (newline) for going to another line, while Windows uses a combination 0D0A, so most probably you have some program that converts your "I-believe-the-data-to-be-UNIX-like" into "Windows-like".

That might go far: I had the situation where UNIX files were sent to a Windows computer, and the user was using a Windows file viewer to see the content of the files, and it was the file viewer itself which was doing that conversion. Therefore I advise you to check all intermediate programs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文