星期日, 12月 24, 2006

Program Win32 program, Read data from COM port buffer.

void OnOpencom()
{
DCB dcb;
DWORD dwReadStatId;

HANDLE hRead;

開啟COM port, Overlapped屬性准許檔案同時被讀/寫
// Step I.
ComDev = CreateFile( "COM7",

GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,

0 );
if(ComDev == INVALID_HANDLE_VALUE)
{

GetDlgItem(IDC_MYTEXT)->
SetWindowText("Error! When open COM-PORT.");
}
else

{

設定 COM port 讀/寫 Buffer. 如果沒有設定 Buffer 大小,COM port 會使用先前所設定的。
// Step II.

if( !SetupComm(ComDev, MAX_READ_BUFFER, MAX_WRITE_BUFFER) )
{

GetDlgItem(IDC_MYTEXT)->
SetWindowText("Setup COMM error!");

return;
}


設定讀/寫 Timing
// Step III.
COMMTIMEOUTS time_out = {0, 0, 0, 0, 0};

time_out.ReadIntervalTimeout = MAXDWORD;
//time_out.ReadTotalTimeoutMultiplier = MAXDWORD;

//time_out.ReadTotalTimeoutConstant = 50;
// 5s
time_out.WriteTotalTimeoutConstant = 5000;
// 50ms
//time_out.WriteTotalTimeoutMultiplier = 5;
if( !SetCommTimeouts(ComDev, &time_out) )
{
GetDlgItem(IDC_MYTEXT)->
SetWindowText("Set COMM timeout error!");
return;
}


設定 COM port 屬性

// Step IV.

GetCommState(ComDev, &dcb);

dcb.BaudRate = CBR_57600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;

if( !SetCommState(ComDev, &dcb) )

GetDlgItem(IDC_MYTEXT)->
SetWindowText("Set COMM State ERROR!");


產生一 Thread 執行讀取工作

hRead = CreateThread( NULL,
0, (LPTHREAD_START_ROUTINE)ReadProc, (LPVOID)this, 0, &dwReadStatId ); if(hRead == NULL)
GetDlgItem(IDC_MYTEXT)->
SetWindowText("Error! CreateThread(Read)");

GetDlgItem(IDC_MYTEXT)->
SetWindowText("Open COM-PORT Successfully!");

}

}


DWORD WINAPI
ReadProc(LPVOID lpV)
{

DWORD dwRes, dwErr, dwLen;

CRMSDlg *p = (CRMSDlg*)lpV;
CString str; COMSTAT comstat;
osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

if( osRead.hEvent == NULL) {

// Error.
}
while(1)

{

ClearCommError(ComDev, &dwErr, &comstat);
dwLen = comstat.cbInQue;
if(!dwLen) {
Sleep(200);

continue;
}
if( !ReadFile(ComDev, lpBuf, dwLen, &dwLen, &osRead) )
{
if( GetLastError() != ERROR_IO_PENDING) {
p->
GetDlgItem(IDC_MYTEXT)->
SetWindowText("Error");

}

else {

switch( WaitForSingleObject(osRead.hEvent, 1000) )

{

case WAIT_OBJECT_0:
if( GetOverlappedResult(ComDev, &osRead, &dwLen, FALSE) ) p->
GetDlgItem(IDC_MYTEXT)->
SetWindowText(lpBuf);

else

// Error.
p->
GetDlgItem(IDC_MYTEXT)->
SetWindowText("Error");
break;
case WAIT_TIMEOUT:

// Error.
p->
GetDlgItem(IDC_MYTEXT)->
SetWindowText("Error");

break;
default: // Error. p->
GetDlgItem(IDC_MYTEXT)->
SetWindowText("Error");

} // switch

}
}
else

p->GetDlgItem(IDC_MYTEXT)->
SetWindowText(lpBuf);

}

}

星期日, 12月 17, 2006