2013-07-13 70 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