[kaze's test] プログラミングメモ →目次

シリアル通信(OVERLAPPED版)(VC++)

RS232C Communication

簡単なシリアル通信方法は、シリアル通信(簡易版)(VC++)にメモしましたが、別のスレッドの中でOVERLAPPED的に受信処理を行うほうが一般的です。



1.シリアルのデバイスを開き、プロトコルを設定します。受信処理のスレッドも作成します。

例:ポート:"COM3"、ボーレート:19200で、8ビット、パリティ無し、1ストップ。

HANDLE hCom = INVALID_HANDLE_VALUE;
HANDLE hThread = NULL;
DWORD ThreadId;
void CSimple232CDlg::OnButtonOpen() 
{
    hCom = CreateFile("COM3", GENERIC_READ | GENERIC_WRITE, 0, NULL, 
                      OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
    if (hCom == INVALID_HANDLE_VALUE) 
        return;
    DCB dcb;
    memset(&dcb, 0, sizeof(DCB));
    dcb.DCBlength = sizeof(DCB) ;
    dcb.BaudRate = CBR_19200;
    dcb.ByteSize = 8;
    dcb.Parity = NOPARITY;
    dcb.StopBits = ONESTOPBIT;
    SetCommState(hCom, &dcb);
    hThread = CreateThread(NULL, 0, ReadDataWithOverLapped, NULL, 0, &ThreadId);
}
void CSimple232CDlg::OnButtonClose() 
{
    if (hCom != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hCom);
        hCom = INVALID_HANDLE_VALUE;
    }
    if (hThread != NULL) {
        TerminateThread(hThread, 0);
	    CloseHandle(hThread);
        hThread = NULL;
    }    
}

2.送信します。ファイルのOVERLAPPEDライトです。 

例:

void CSimple232CDlg::OnButtonSend() 
{
    if (hCom != INVALID_HANDLE_VALUE)
    {
        OVERLAPPED ovlp;
        memset(&ovlp, 0, sizeof(OVERLAPPED));
        ovlp.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

        CString strText = "Hello, RS232C. OVERLAPPED.";
        DWORD dwBytes = 0;
        if (!WriteFile(hCom, (LPCTSTR)strText, strText.GetLength(), &dwBytes, &ovlp))
        {
            if (GetLastError() == ERROR_IO_PENDING) 
            {
                GetOverlappedResult(hCom, &ovlp, &dwBytes, TRUE);
            }
        }
        ResetEvent(ovlp.hEvent);
        CloseHandle(ovlp.hEvent);
    }
}

3.受信します。OVERLAPPED受信処理は、スレッドの中で行います。

例:

DWORD WINAPI ReadDataWithOverLapped(LPVOID lpParam)
{
    OVERLAPPED ovlp;
    memset(&ovlp, 0, sizeof(OVERLAPPED));
    ovlp.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    while(1)
    {
        char buff[1024];
        DWORD nRead = 0;
        if (!ReadFile(hCom, buff, 10, &nRead, &ovlp)) 
        {
            if (GetLastError() == ERROR_IO_PENDING) 
            {
                GetOverlappedResult(hCom, &ovlp, &nRead, TRUE);
            }
        }
        if (nRead)
        {
            //受信したデータを処理するなど
            CString strText(buff, nRead);
            TRACE("Received: %s\r\n", strText);
        }
        ResetEvent(ovlp.hEvent);
    }
    CloseHandle(ovlp.hEvent);
    return 0;
}