当我尝试写入 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.
如果您需要规范模式,请参考 .