linux和windows之间的串行通信

时间:2013-07-13 06:53:50

标签: c++ c linux windows

我将数据字节从linux发送到串口RS232的窗口然后一切正常,只有我必须处理来自linux的0xa发送,因为Windows将其读取为0xd + 0xa。 但是当我从windows发送数据字节到linux时,一些字节被替换为 -  windows发送 - 0xd linux接收0xa windows发送 - 0x11 linux接收整数8200的垃圾tyte值

请解释当我将数据从Windows发送到Linux时出了什么问题。 提前谢谢

Windows串口初始化

char *pcCommPort = "COM1";
    hCom = CreateFile( TEXT("COM1"),
                       GENERIC_READ | GENERIC_WRITE,
                       0,    // must be opened with exclusive-access
                       NULL, // no security attributes
                       OPEN_EXISTING, // must use OPEN_EXISTING
                       0,    // not overlapped I/O
                       NULL  // hTemplate must be NULL for comm devices
                       );
fSuccess = GetCommState(hCom, &dcb);
 FillMemory(&dcb, sizeof(dcb),0);


    dcb.DCBlength = sizeof(dcb);
    dcb.BaudRate = CBR_115200;     // set the baud rate
    dcb.ByteSize = 8;             // data size, xmit, and rcv
    dcb.Parity = NOPARITY;        // no parity bit
    dcb.StopBits = ONESTOPBIT;    // one stop bit
    dcb.fOutxCtsFlow = false;

    fSuccess = SetCommState(hCom, &dcb);
 buff_success = SetupComm(hCom, 1024, 1024);
COMMTIMEOUTS cmt;
    // ReadIntervalTimeout in ms
    cmt.ReadIntervalTimeout = 1000;
    cmt.ReadTotalTimeoutMultiplier = 1000;
    cmt.ReadTotalTimeoutConstant=1000;
    timeout_flag = SetCommTimeouts(hCom, &cmt);

windows write serial -

WriteFile(hCom, buffer, len, &write, NULL);

Linux串行初始化 -

_fd_port_no = open("//dev//ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
tcgetattr(_fd_port_no, &options);
        cfsetispeed(&options, B115200);
        cfsetospeed(&options, B115200);
        options.c_cflag |= (CS8);
        options.c_cflag|=(CLOCAL|CREAD);
        options.c_cflag &=~PARENB;
        options.c_cflag &= ~CSTOPB;
        options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
        options.c_iflag |= (IXON | IXOFF | IXANY);
        options.c_cflag &= ~ CRTSCTS;
        tcsetattr(_fd_port_no, TCSANOW, &options);

阅读串口linux -

while(read(_fd_port_no,buffer+_buffer_len,sizeof(buffer))>0)
    {
        _buffer_len = _buffer_len+sizeof(buffer);

    }

是的,正如我从Linux告诉Windows只检测到NL / CR问题,但我通过字节替换解决了它, 但是你对从Windows发送到Linux的serila数据(字节替换策略)有任何了解吗? 实际上我必须通过串口发送200字节块的200 KB文件,以便在从Windows发送到Linux时可以替换哪个字节

4 个答案:

答案 0 :(得分:3)

如果您在Windows上使用ReadFileWrietFile,在Linux中使用readwrite,那么行结尾应该无关紧要,其他比“你必须在收到它后在某个时候翻译它。”

这看起来不对:

while(read(_fd_port_no,buffer+_buffer_len,sizeof(buffer))>0)
{
    _buffer_len = _buffer_len+sizeof(buffer);

}

您应该考虑read返回的读取大小。

如果sizeof(buffer)是您正在阅读的实际缓冲区,则添加+_buffer_len,当_buffer_len >= sizeof(buffer)将在缓冲区外写入​​时。

还有点担心:

    options.c_iflag |= (IXON | IXOFF | IXANY);
    options.c_cflag &= ~ CRTSCTS;

你确定要XOFF / CTRL-S(0x13)停止流动吗?通常这意味着不允许使用带有CTRL-S的数据 - 这在发送文本数据时可能不是问题,但如果您需要发送二进制数据,它肯定会。 IXOFF还意味着另一端必须响应XOFF和XON(CTRL-Q,0x11)来停止/启动数据流。通常,我们不希望在现代系统中使用它....

如果两端之间的接线正确,则使用RTS / CTS应该是安全的。

答案 1 :(得分:1)

我认为你必须在从串口读取磁通之前进行冲洗

tcflush(_fd_port_no TCIFLUSH);

furthemore您是否尝试使用指挥官在控制台上看到助焊剂     猫< dev / ttyS0?

答案 2 :(得分:1)

为避免行结束转换,您可能需要添加:

options.c_iflag &= ~IGNCR;  // turn off ignore \r 
options.c_iflag &= ~INLCR;  // turn off translate \n to \r 
options.c_iflag &= ~ICRNL;  // turn off translate \r to \n

options.c_oflag &= ~ONLCR;  // turn off map \n  to \r\n
options.c_oflag &= ~OCRNL;  // turn off map \r to \n 
options.c_oflag &= ~OPOST;  // turn off implementation defined output processing

另外,以下一行:

options.c_iflag |= (IXON | IXOFF | IXANY);

将启用XON / XOFF处理,因此tty驱动程序将处理Ctrl-S(XOFF)和Ctrl-Q(XON)字符作为流控制(这可能是您在发送0x11时看到一些意外的原因,这是Ctrl- Q)。我希望你能把这些东西关掉:

options.c_iflag &= ~(IXON | IXOFF | IXANY);

事实上,我认为您可能希望在调用cfmakeraw()之后调用tcgetattr(),这将禁用对输入和输出字符的所有特殊处理。

答案 3 :(得分:1)

全部谢谢

此更改解决了我的问题

fd_port_no = open("//dev//ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
tcgetattr(_fd_port_no, &options);
        cfsetispeed(&options, B115200);
        cfsetospeed(&options, B115200);
        options.c_cflag |= (CS8);
        options.c_cflag|=(CLOCAL|CREAD);
        options.c_cflag &=~PARENB;
        options.c_cflag &= ~CSTOPB;
        options.c_cflag &= ~ CRTSCTS;
        options.c_iflag |= (IXON | IXOFF | IXANY);
        options.c_lflag &= ~(ICANON | ISIG | ECHO | ECHONL | ECHOE | ECHOK);
        options.c_cflag &= ~ OPOST;
        tcsetattr(_fd_port_no, TCSANOW, &options);