[英]Serial communication between linux and windows
我將數據字節從linux發送到串口RS232的窗口然后一切正常,只有我必須處理來自linux的0xa發送,因為Windows將其讀取為0xd + 0xa。 但是當我從windows發送數據字節到linux時,一些字節被替換為 - windows發送 - 0xd linux接收0xa windows發送 - 0x11 linux接收垃圾tyte值整數8200
請解釋當我將數據從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寫序列 -
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時可以替換哪個字節
如果您正在使用ReadFile
和WrietFile
在Windows和read
和write
在Linux中,它不應該真正重要的行結束是什么,除了“你必須在某個時候接受它后,把它翻譯。
這看起來不正確:
while(read(_fd_port_no,buffer+_buffer_len,sizeof(buffer))>0)
{
_buffer_len = _buffer_len+sizeof(buffer);
}
您應該考慮read返回的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應該是安全的。
我認為你必須在從串口讀取磁通之前進行沖洗
tcflush(_fd_port_no TCIFLUSH);
更多你有沒有嘗試使用指揮官通過控制台看到助焊劑
貓<dev / ttyS0?
要避免行結束轉換,您可能需要添加:
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()
,它應該禁用輸入和輸出字符的所有特殊處理。
謝謝大家
這個改變解決了我的問題
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.