Вопрос по COM-порту
От: Rom  
Дата: 19.06.02 20:48
Оценка:
Всем привет!
Кто может подсказать, как вывести COM-порт из комы на функции WaitCommEvent(...), чтобы корректно завершить поток, в котором порт работает на приёме? Открываю порт для синхронного чтения. Вот ниже код.
BOOL C_USPDTR::Connect(LPCSTR port)
{
    COMMCONFIG cfg;
    DWORD dwRes;

    Disconnect();

    memset(&cfg,0,sizeof(cfg));
    cfg.dwSize = sizeof(cfg);
    if(::CommConfigDialog(port,NULL,&cfg) != IDOK) return FALSE;

    cfg.dcb.fBinary = TRUE;
    cfg.dcb.XoffLim = 512;
    cfg.dcb.XonLim = 2048;
    cfg.dcb.fParity = TRUE;
    cfg.dcb.fNull = TRUE;
    hComm = ::CreateFile(port,
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        0,
        NULL);
    if(hComm == INVALID_HANDLE_VALUE)
    {
        ::MessageBox(NULL,"Âûáðàííûé ïîðò çàíÿò!","Îøèáêà îòêðûòèÿ ïîðòà",MB_OK);
        Disconnect();
        return FALSE;
    }
    ::FlushFileBuffers(hComm);
    if(!::SetCommState(hComm,&cfg.dcb)) 
    {
        dwRes = ::GetLastError();
        ::MessageBox(NULL,"Îøèáêà èíèöèàëèçàöèè ïîðòà!",NULL,MB_OK);
    }
    

    COMMTIMEOUTS to;
    DWORD rttc = 100 * 11 * 1000 / cfg.dcb.BaudRate;
    DWORD rit = 11 * 1000 / cfg.dcb.BaudRate;
    to.ReadIntervalTimeout = rit ? rit : 1;
    to.ReadTotalTimeoutConstant = rttc ? rttc : 1;
    to.ReadTotalTimeoutMultiplier = to.ReadIntervalTimeout;
    to.WriteTotalTimeoutConstant = 0;
    to.WriteTotalTimeoutMultiplier = 0;

    if(!::SetCommTimeouts(hComm,&to))
    {
        dwRes = ::GetLastError();
        ::MessageBox(NULL,"Îøèáêà èíèöèàëèçàöèè ïîðòà!",NULL,MB_OK);
    }
    ::GetCommTimeouts(hComm,&to);
    ::PurgeComm(hComm,PURGE_RXABORT|PURGE_TXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
    connect = TRUE;
    ::AfxBeginThread(RecvThread,(LPVOID)NULL);
    return TRUE;    
}
//////////////////////////////////////////////////////////////////////////
void C_USPDTR::Disconnect()
{
    if(hComm!=INVALID_HANDLE_VALUE)
    {
        connect = FALSE;
        ::EscapeCommFunction(hComm,SETBREAK);
        ::SetCommBreak(hComm);
        ::PurgeComm(hComm,PURGE_RXABORT|PURGE_TXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
        ::SetCommBreak(hComm);
        ::WaitForSingleObject(eStopRecvEvent.m_hObject,INFINITE);
        ::CloseHandle(hComm);        
        hComm = INVALID_HANDLE_VALUE;
    }
}
////////////////////////////////////////////////////////////////////////////////////////
UINT C_USPDTR::RecvThread(LPVOID param)
{
    DWORD dwEvent, dwBytesRead;
    OVERLAPPED ol;
    UART_PACKET    packet;

    memset( (LPVOID)&ol, 0, sizeof(ol) );
    ol.hEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );
    ::SetCommMask( hComm, EV_RXCHAR | EV_BREAK);
    while(connect)
    {
        if( ::WaitCommEvent(hComm, &dwEvent, NULL) )
        {
            if( dwEvent & EV_RXCHAR )
            {
                ::ReadFile( hComm, &packet.head, sizeof(UART_PACKET_HEAD),
                    &dwBytesRead, NULL);
                packet.pBuf = new BYTE[ packet.head.data_size ];
                ::ReadFile( hComm, packet.pBuf, packet.head.data_size, 
                    &dwBytesRead, NULL);
            }
            if(dwEvent & EV_BREAK )
            {
                connect = FALSE;
                break;
            }
            else break;
        }
    }
    ::SetEvent(eStopRecvEvent.m_hObject);
    return 0;
}


В функции Disconnect() (там сейчас полная каша ) ни SetCommBreak(..), ни PurgeComm(..) не приводят к выходу из WaitCommEvent(..) .........

С уважением, Роман.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.