?? wserialcomm.cpp
字號:
// WSerialComm.cpp: implementation of the CWSerialComm class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "WSerialComm.h"
#include <stdio.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#define RXQUEUE 128 // < READ_BUFF_SIZE
#define TXQUEUE 128
static UINT CommWatchProc( LPVOID lpData )
{
CWSerialComm *pCommPort = ( CWSerialComm*) lpData ;
DWORD dwEvtMask ;
OVERLAPPED os ;
BOOL bWaitResult;
memset( &os, 0, sizeof( OVERLAPPED ) ) ;
os.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ;
if (os.hEvent == NULL) return ( FALSE ) ;
if (!SetCommMask( pCommPort ->m_hComDev, EV_RXCHAR ))
return ( FALSE ) ;
while ( pCommPort->IsOpen() )
{
dwEvtMask = 0 ;
bWaitResult = WaitCommEvent( pCommPort ->m_hComDev, &dwEvtMask, &os );
if(!bWaitResult && GetLastError() == ERROR_IO_PENDING)
{
DWORD dwLength;
bWaitResult = GetOverlappedResult(pCommPort ->m_hComDev, &os, &dwLength, TRUE);
}
if (!bWaitResult)
{
COMSTAT comStatus;
DWORD dwErrorFlags;
ClearCommError( pCommPort ->m_hComDev, &dwErrorFlags, &comStatus ) ;
pCommPort->OnCommPortError(dwErrorFlags,TRUE);
}
else if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
while ( pCommPort->ReadCommBlock() > 0 ) ;
}
CloseHandle( os.hEvent ) ;
pCommPort->m_dwThreadID = 0 ;
pCommPort->m_hCommWatchThread = NULL ;
return( TRUE ) ;
}
CWSerialComm::CWSerialComm()
{
if( !InitMembers() ) throw GetLastError();
}
CWSerialComm::~CWSerialComm()
{
if( IsOpen() ) CloseCom();
CloseHandle( m_osRead.hEvent ) ;
CloseHandle( m_osWrite.hEvent ) ;
}
BOOL CWSerialComm::IsOpen()
{
return m_bOpened;
}
void CWSerialComm::SetCommConfig()
{
COMMCONFIG cfg;
DWORD dwSize;
::GetCommConfig(m_hComDev, &cfg, &dwSize);
cfg.dcb.BaudRate = CBR_9600;
cfg.dcb.ByteSize = 8;
cfg.dcb.StopBits = ONESTOPBIT;
cfg.dcb.fParity = FALSE;
cfg.dcb.Parity = NOPARITY;
::SetCommConfig(m_hComDev, &cfg, sizeof(COMMCONFIG));
}
BOOL CWSerialComm::InitMembers()
{
// common data members
m_hComDev = 0 ;
m_bOpened = FALSE ;
//thread
m_dwThreadID = 0;
m_hCommWatchThread = NULL ;
memset( (void*)&m_osWrite, 0, sizeof(m_osWrite) );
memset( (void*)&m_osRead , 0, sizeof(m_osRead ) );
m_osRead.hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) ; // no name
if( NULL == m_osRead.hEvent ) return FALSE;
m_osWrite.hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) ; // no name
if ( NULL == m_osWrite.hEvent ) return FALSE;
return TRUE; //no error
} //end InitMembers
void CWSerialComm::GetCommName( LPSTR lpszComName, int portNo)
{
sprintf(lpszComName, "COM%d", portNo);
}
BOOL CWSerialComm::OpenCom( int portNo )
{
if( IsOpen() ) return TRUE;
char szCommName[32];
GetCommName(szCommName, portNo);
// open COMM device
if ((m_hComDev =
CreateFile( szCommName, GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security attrs
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_OVERLAPPED, // overlapped I/O
NULL )) == (HANDLE) -1 )
return ( FALSE ) ;
else
{
SetCommConfig();
SetCommMask( m_hComDev, EV_RXCHAR ) ;
SetupComm( m_hComDev, RXQUEUE, TXQUEUE ) ;
PurgeComm( m_hComDev, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
}
m_bOpened = TRUE ;
// Create a thread
HANDLE hCommWatchThread ;
DWORD dwThreadID ;
if (NULL == ( hCommWatchThread =
CreateThread( (LPSECURITY_ATTRIBUTES) NULL,
0,
(LPTHREAD_START_ROUTINE)CommWatchProc,
(LPVOID) this,
0, &dwThreadID )))
{
m_bOpened = FALSE ;
CloseHandle( m_hComDev ) ;
}
else
{
m_dwThreadID = dwThreadID ;
m_hCommWatchThread = hCommWatchThread ;
// assert DTR
EscapeCommFunction( m_hComDev, SETDTR ) ;
}
return ( m_bOpened ) ;
}
BOOL CWSerialComm::CloseCom( )
{
// set connected flag to FALSE
m_bOpened = FALSE ;
// block until thread has been halted
SetCommMask( m_hComDev, 0 ) ;
// drop DTR
EscapeCommFunction( m_hComDev, CLRDTR ) ;
// purge any outstanding reads/writes and close device handle
PurgeComm( m_hComDev, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
CloseHandle( m_hComDev ) ;
m_hComDev = 0;
return ( TRUE ) ;
}
DWORD CWSerialComm::
ReadCommBlock( )
{
BOOL fReadStat ;
DWORD dwErrorFlags;
DWORD dwToRead, dwRead;
COMSTAT comStatus;
// only try to read number of bytes in queue
ClearCommError( m_hComDev, &dwErrorFlags, &comStatus ) ;
dwToRead = min(READ_BUFF_SIZE,comStatus.cbInQue);
dwRead = 0;
if (dwToRead > 0)
{
fReadStat = ReadFile( m_hComDev, m_pReadBuff, dwToRead,
&dwRead, &m_osRead ) ;
if (!fReadStat && GetLastError() == ERROR_IO_PENDING)
fReadStat = GetOverlappedResult( m_hComDev, &m_osRead, &dwRead, TRUE);
if(!fReadStat || dwRead != dwToRead)
{
dwRead = 0 ;
ClearCommError( m_hComDev, &dwErrorFlags, &comStatus ) ;
OnCommPortError( dwErrorFlags ); //report the error
}
}
if( dwRead > 0 )
OnDataRead( m_pReadBuff, dwRead );
return dwRead;
} //
BOOL CWSerialComm::WriteDataBlock(const BYTE* lpByte , DWORD dwBytesToWrite)
{
BOOL fWriteStat ;
DWORD dwBytesWritten ;
DWORD dwErrorFlags;
COMSTAT comStatus;
ASSERT( IsOpen() );
fWriteStat = WriteFile( m_hComDev, lpByte, dwBytesToWrite,
&dwBytesWritten, &m_osWrite ) ;
if (!fWriteStat && GetLastError() == ERROR_IO_PENDING)
fWriteStat = GetOverlappedResult( m_hComDev, &m_osWrite, &dwBytesWritten, TRUE );
if( !fWriteStat || dwBytesWritten != dwBytesToWrite )
{
ClearCommError( m_hComDev, &dwErrorFlags, &comStatus ) ;
OnCommPortError( dwErrorFlags, FALSE );
}
return fWriteStat;
} // end of WriteDataBlock()
void CWSerialComm::OnDataRead( const LPBYTE lpData, DWORD dwLength )
{
}
BOOL CWSerialComm::OnCommPortError( DWORD dwError, BOOL bReading )
{
TRACE3( "%s, CommError:%d, SystemError:%d\n", ( bReading ? "Reading" : "Writting" ),
dwError, GetLastError() );
return TRUE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -