2013-07-13 71 views
3

我从linux发送数据字节到串口RS232的窗口然后一切正常,只有我必须处理0xa从linux发送,因为windows将其读为0xd + 0xa。 但是当我从Windows到Linux的一些字节发送数据字节被替换为 - 窗口发送 - 0xd中Linux的接受是0xA 窗口发送 - 为0x11 Linux的整数东西收到垃圾tyte价值8200linux和windows之间的串行通信

普莱舍解释什么不顺心的时候我从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); 

窗口写serial-

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

Linux的串行initialize-

_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(字节替换策略)的串行数据的想法。 其实我有送200 KB的文件在200字节的块通过串行所以它如果从Windows发送到Linux

字节的可更换
+0

所以你要发送原始字节,而不是发短信?显示发送和接收的代码;尽可能少的代码当然。 –

+0

请注意,“0x0a”是换行符,“0x0d”是回车符。听起来像典型的NL/CR问题。 –

+0

如果您从Windows发送文件,是否以文本模式或二进制模式打开了该文件?确保两端的所有串行设置都相同,例如你似乎在Linux端有XON/XOFF,但不在Windows端(不使用XON/XOFF) – nos

回答

3

如果您使用的是Linux的Windows上ReadFileWrietFilereadwrite,它不该“吨真的不管什么行结束是,除了“你必须把它在某些时候翻译收到后

这看起来不正确:

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

} 

你应该考虑到读取的大小由返回。

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

也略有担心这个:

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

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

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

1

我认为你必须刷新从一个串口

tcflush(_fd_port_no TCIFLUSH); 

furthemore您曾经试图看到使用COMMANDE
猫<开发/ ttyS0来控制台通量读取流量过吗?

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); 

其实,我觉得你可能要调用tcgetattr()应该禁用的输入和输出字符的所有特殊处理之后调用cfmakeraw()

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); 
+0

但技术上不知道它是如何工作,但我的问题解决和测试好 – pritesh

+0

actualy断路器和客户端机器转移到Linux,所以这段代码工作LINIX到Linux串行通信。 – pritesh