Re: Вопрос по COM-порту
От: ua1zcl Россия www.alexklm.ru
Дата: 20.06.02 00:58
Оценка:
Здравствуйте Rom , Вы писали:

R>Всем привет!

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

R>    Disconnect();

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

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

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

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

R>    memset( (LPVOID)&ol, 0, sizeof(ol) );
R>    ol.hEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );
    ::SetCommMask( hComm, EV_RXCHAR | EV_BREAK | EV_ERR);
R>    while(connect)
R>    {
R>        if( ::WaitCommEvent(hComm, &dwEvent, NULL) )
R>        {
R>            if( dwEvent & EV_RXCHAR )
R>            {
R>                ::ReadFile( hComm, &packet.head, sizeof(UART_PACKET_HEAD),
R>                    &dwBytesRead, NULL);
R>                packet.pBuf = new BYTE[ packet.head.data_size ];
R>                ::ReadFile( hComm, packet.pBuf, packet.head.data_size, 
R>                    &dwBytesRead, NULL);
R>            }
R>            if(dwEvent & EV_BREAK )
R>            {
R>                connect = FALSE;
R>                break;
R>            }
                              if ((dwEvtMask & EV_ERR)!=0)
                              { DWORD dwError; 
                                //sprintf(str,"EVENT: EV_ERR"); Le(str);
                                ClearCommError(hComm,&dwError,&cs);
                              }
            else break;// А else и не будет, больше не заказано было
R>        }
R>    }
R>    ::SetEvent(eStopRecvEvent.m_hObject);
R>    return 0;
R>}
R>


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


Посмотрите старый пример — программу Tty.exe, где-то она была у MS в примерах. Я дописал
случай с EV_ERR. Попробуйте.
Александр
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.