2013-10-03 3 views
0

시리얼 포트를 통해 이진 데이터를 보내야합니다. 길을 따라 제어 문자로 다시 해석 할 필요가 없습니다.윈도우에서 직렬로 바이너리 데이터 쓰기

#include <windows.h> 

// open serial port 
HANDLE hSerial; 
hSerial = CreateFile ("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 

// get serial parameters 
DCB dcbSerialParams = {0}; 
dcbSerialParams.DCBlength = sizeof (dcbSerialParams); 
if (!GetCommState(hSerial, &dcbSerialParams)) { 
    cout << "error getting state\n"; 
    exit(0); 
} 

// set serial params 
dcbSerialParams.BaudRate = CBR_115200; 
dcbSerialParams.ByteSize = 8; 
dcbSerialParams.StopBits = ONESTOPBIT; 
dcbSerialParams.Parity = NOPARITY; 
if (!SetCommState (hSerial, &dcbSerialParams)) { 
    cout << "error setting parameters\n"; 
    exit(0); 
} 

// set time outs 
COMMTIMEOUTS timeouts = {0}; 
timeouts.ReadIntervalTimeout = 50; 
timeouts.ReadTotalTimeoutConstant = 10; 
timeouts.ReadTotalTimeoutMultiplier = 10; 
timeouts.WriteTotalTimeoutConstant = 10; 
timeouts.WriteTotalTimeoutMultiplier = 10; 
if (!SetCommTimeouts (hSerial, &timeouts)) { 
    cout << "problem setting timeout values\n"; 
    exit(0); 
} else cout << "timeouts set\n"; 

내가 ReadFile을 내가 얻을 0에서 문제없이 255 디스플레이 바이트 수, 명령을 실행하면 다음과 같이 나는 현재 내 시리얼 포트를 설정하고있다. 하지만 필자는 WriteFile에 그런 행운이 없다. 명시 적으로 이진 쓰기 모드를 설정하는 방법이 있습니까?

편집

이 좋아, 여기에 몇 가지 추가 정보를 원하시면입니다. 나는 윈도우 머신과 시리얼을 통해 꺾어 리눅스 싱글 보드 컴퓨터를 창문 쪽 위의 코드는 뒤에 :

unsigned char temp = 0; 

bool keepReading = true; 
while (keepReading) { 
    DWORD dwBytesRead = 0; 
    ReadFile (hSerial, &temp, 1, &dwBytesRead, NULL); 
    if (1 == dwBytesRead) cout << (unsigned int) temp << " "; 
    if (255 == temp) keepReading = false; 
} 
cout << endl; 

bool keepWriting = true; 
char send = 0; 
while (keepWriting) { 
    DWORD dwBytesWritten = 0; 
    WriteFile (hSerial, &send, 1, &dwBytesWritten, NULL); 
    send++; 
    if (256 == send) keepWriting = false; 
} 

리눅스 측에 내 코드는 다음과 같습니다

int fd = open("/dev/ttymxc0", O_RDWR | O_NOCTTY); 
struct termios options; 
bzero (options, sizeof(options)); 
options.c_cflag = B115200 | CS8 | CLOCAL | CREAD; 
options.c_iflat = IGNPAR; 
options.c_oflag = 0; 
options.c_lflag = ICANON; 
options.c_cc[VMIN] = 1; 
options.c_CC[VTIME] = 0; 
tcflush (fd, TCIFLUSH); 
tcsetattr (fd, ICSANOW, &options); 

bool keepWriting = true; 
char send = 0; 
while (keepWriting) { 
    write (fd, &send, 1); 
    send++; 
    if (256 == send) keepWriting = false; 
} 

bool keepReading = true; 
while (keepReading) { 
    char temp = 0; 
    int n = read (fd, &temp, 1); 
    if (-1 == n) { 
     perror ("Read error"); 
     keepReading = false; 
    } else if (1 == n) { 
     cout << temp << " "; 
    } 
    if (256 == temp) keepReading = false; 

} 
cout << endl; 

close(fd); 

두 컴퓨터에서 코드를 시작하고 while 루프의 첫 번째 집합이 정상적으로 실행됩니다. 창 측면의 터미널에는 0에서 255까지 표시됩니다. 그런 다음 바로 거기에 있습니다. while 루프의 두 번째 집합에 대해 Linux 측에서 읽은 바이트 수를 출력하면 계속해서 0 바이트가됩니다. 이것은 닫힌 포트를 나타냅니다 정상적으로,하지만 방금 보낸 정보를 통해 그래서 어떻게 될 수 있을까?

+0

'WriteFile'에 시도한 것을 게시 할 수 있습니까? 'WriteFile'과'ReadFile'을 호출하는 것과는 다른 어떤 것도 있어서는 안됩니다. – Derek

+0

"그런 행운이 없다"는 것은 적절한 문제 설명이 아닙니다. "이진 쓰기 모드"는 없으며 항상 이진 모드입니다. 아마 다른 쪽 끝에서 문제를 찾아야 할 것입니다. –

+1

'DCB :: fOutX'와'DCB :: fInX'가 모두 0으로 설정되어 있는지 확인해야합니다. –

답변

0

이 좋아, 그래서 그것을 파악, 오히려 동료는 않았다.

T0:23:respawn:/sbin/getty -L ttymxc0 115200 vt100 

이 바이트를 수신하지 못할 만든 방법으로 직렬 포트를 잡는했다 : 리눅스 측면에서,/etc/inittab 파일에 내가 줄을 주석했다. 이제 예상 결과를 봅니다.

2

나는 리눅스가 휴식을 감지하고 포트를 재설정하고 있거나 표준 모드가 설정되어 있다는 사실을 망각하고 있다고 생각합니다. 당신이 이미 가지고있는 것에 추가하여 이러한 설정을보십시오 : 조나단 포터 언급으로

options.c_iflag |= IGNBRK; 
    options.c_iflag &= ~BRKINT; 
    options.c_iflag &= ~ICRNL; 
    options.c_oflag = 0; 
    options.c_lflag = 0; 
+0

이것은 차이가없는 것처럼 보입니다. 나는 같은 줄을 따라 생각하고 있는데, 일부 바이트는 제어 문자로 해석되고있다. 하지만, 어떤 바이트를 보내는지는 중요하지 않습니다. – Mike

2

이 가장 가능성이 당신이 XON/XOFF 흐름 제어가 꺼져 필요가 없습니다. SetCommState 호출하기 전에이 줄을 추가합니다 : 당신이 설정해야 할 수도 있습니다

dcbSerialParams.fOutX = 0; 
dcbSerialParams.fInX = 0; 

다른 어떤 분야 :

dcbSerialParams.fNull = 0; 
dcbSerialParams.fDtrControl = DTR_CONTROL_DISABLE; 
dcbSerialParams.fRtsControl = RTS_CONTROL_DISABLE; 
+0

나는 이것을 시험해 보았고 결과는 변하지 않았다. 제가 생각해 보았던 한 가지는 : 직렬 포트를 통해 로그인하는 것이 가능하며, 실제로 보드를 처음에 어떻게 세우는 지입니다. Windows에서 보낸 바이트를 내 프로그램보다는 터미널에서 캡처 할 수 있습니까? – Mike

관련 문제