📄 datacomm.cpp
字号:
} // end of ReadCommBlock()
BOOL CDataComm::OpenConnection()
{
char szPort[ 15 ], szTemp[ 10 ] ;
BOOL fRetVal ;
HANDLE hCommWatchThread ;
DWORD dwThreadID ;
COMMTIMEOUTS CommTimeOuts ;
// load the COM prefix string and append port number
////LoadString( GETHINST( hWnd ), IDS_COMPREFIX, szTemp, sizeof( szTemp ) ) ;
strcpy(szTemp,"COM");
wsprintf( szPort, "%s%d", (LPSTR) szTemp,m_nPort) ;
// open COMM device
if ((m_hComm =
CreateFile( szPort, 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
{
// get any early notifications
SetCommMask(m_hComm, EV_RXCHAR|EV_RLSD|EV_TXEMPTY) ;
// setup device buffers
SetupComm(m_hComm,m_nInputBufferSize,m_nOutputBufferSize) ;
// purge any information in the buffer
PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
// set up for overlapped I/O
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF ;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;
CommTimeOuts.ReadTotalTimeoutConstant = 1000 ;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0 ;
CommTimeOuts.WriteTotalTimeoutConstant = 1000 ;
SetCommTimeouts(m_hComm, &CommTimeOuts ) ;
}
fRetVal = SetupConnection() ;
if (fRetVal)
{
m_bConnected= TRUE ;
// Create a secondary thread
// to watch for an event.
if (NULL == (hCommWatchThread =
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)DataCommWatchProc,
(LPVOID) this,0, &dwThreadID )))
{
TRACE0("Fail to create watch thread.");
m_bConnected= FALSE ;
CloseHandle(m_hComm) ;
m_hComm=0;
m_hThread=NULL;
m_dwThreadID=0;
fRetVal = FALSE ;
return fRetVal;
}
m_dwThreadID= dwThreadID ;
m_hThread= hCommWatchThread ;
SetThreadPriority(m_hThread,THREAD_PRIORITY_NORMAL);
// assert DTR
EscapeCommFunction(m_hComm, SETDTR ) ;
}
else
{
m_bConnected= FALSE ;
CloseHandle(m_hComm) ;
//m_hComm=0;
}
// restore cursor
return ( fRetVal ) ;
} // end of OpenConnection()
//---------------------------------------------------------------------------
// BOOL NEAR SetupConnection( HWND hWnd )
//
// Description:
// This routines sets up the DCB based on settings in the
// TTY info structure and performs a SetCommState().
//
// Parameters:
// HWND hWnd
// handle to TTY window
//
// Win-32 Porting Issues:
// - Win-32 requires a slightly different processing of the DCB.
// Changes were made for configuration of the hardware handshaking
// lines.
//
//---------------------------------------------------------------------------
BOOL CDataComm::SetupConnection()
{
BOOL fRetVal ;
DCB dcb ;
ZeroMemory(&dcb,sizeof(dcb));
dcb.DCBlength = sizeof( DCB ) ;
GetCommState(m_hComm, &dcb ) ;
dcb.BaudRate =m_nBaudRate ;
dcb.ByteSize =8;
dcb.Parity =NOPARITY;
dcb.StopBits =ONESTOPBIT;
// setup hardware flow control
dcb.fOutxDsrFlow =0;
dcb.fDtrControl = DTR_CONTROL_ENABLE ;
dcb.fOutxCtsFlow =1;
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE ;
// setup software flow control
dcb.fInX = dcb.fOutX =0;
dcb.XonChar = ASCII_XON ;
dcb.XoffChar = ASCII_XOFF ;
dcb.XonLim = 100 ;
dcb.XoffLim = 100 ;
// other various settings
dcb.fBinary = TRUE ;
dcb.fParity = FALSE ;
fRetVal = SetCommState(m_hComm, &dcb ) ;
return ( fRetVal ) ;
} // end of SetupConnection()
//---------------------------------------------------------------------------
// BOOL NEAR CloseConnection( HWND hWnd )
//
// Description:
// Closes the connection to the port. Resets the connect flag
// in the TTYINFO struct.
//
// Parameters:
// HWND hWnd
// handle to TTY window
//
// Win-32 Porting Issues:
// - Needed to stop secondary thread. SetCommMask() will signal the
// WaitCommEvent() event and the thread will halt when the
// CONNECTED() flag is clear.
// - Use new PurgeComm() API to clear communications driver before
// closing device.
//
//---------------------------------------------------------------------------
BOOL CDataComm::CloseConnection()
{
// set connected flag to FALSE
if(!m_bConnected)
return TRUE;
m_bConnected = FALSE ;
m_lpUserInstance=NULL;
// disable event notification and wait for thread
// to halt
SetCommMask(m_hComm, 0 ) ;
SetEvent(m_hQuitEvent);
// block until thread has been halted
//while(m_dwThreadID!= 0)
::TerminateThread(m_hThread, 2);
while(m_dwWriteThreadID!=0){Sleep(0);}
while(m_dwReadThreadID!=0){Sleep(0);}
ResetEvent(m_hQuitEvent);
// drop DTR
EscapeCommFunction(m_hComm, CLRDTR ) ;
// purge any outstanding reads/writes and close device handle
PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
CloseHandle(m_hComm) ;
m_hComm=NULL;
ZeroMemory(&m_WriteOS,sizeof(OVERLAPPED));
ZeroMemory(&m_ReadOS,sizeof(OVERLAPPED));
m_bConnected=FALSE;
m_dwThreadID=0;
m_hThread=NULL;
m_dwWriteThreadID=0;
m_hWriteThread=NULL;
m_dwReadThreadID=0;
m_hReadThread=NULL;
m_hQuitEvent=NULL;
m_hWriteEvent=NULL;
m_hCTSEvent=NULL;
m_hReadEvent=NULL;
// ClearBuffer();
// change the selectable items in the menu
return ( TRUE ) ;
} // end of CloseConnection()
//---------------------------------------------------------------------------
// BOOL NEAR WriteCommBlock( HWND hWnd, BYTE *pByte )
//
// Description:
// Writes a block of data to the COM port specified in the associated
// TTY info structure.
//
// Parameters:
// HWND hWnd
// handle to TTY window
//
// BYTE *pByte
// pointer to data to write to port
//
// Win-32 Porting Issues:
// - WriteComm() has been replaced by WriteFile() in Win-32.
// - Overlapped I/O has been implemented.
//
//---------------------------------------------------------------------------
BOOL CDataComm::WriteCommBlock(BYTE* lpByte , DWORD dwBytesToWrite)
{
BOOL fWriteStat ;
DWORD dwBytesWritten ;
DWORD dwErrorFlags;
DWORD dwError;
COMSTAT ComStat;
char szError[ 10 ] ;
fWriteStat = WriteFile(m_hComm, lpByte, dwBytesToWrite,
&dwBytesWritten, &m_WriteOS) ;
// Note that normally the code will not execute the following
// because the driver caches write operations. Small I/O requests
// (up to several thousand bytes) will normally be accepted
// immediately and WriteFile will return true even though an
// overlapped operation was specified
if (!fWriteStat)
{
if(GetLastError() == ERROR_IO_PENDING)
{
// We should wait for the completion of the write operation
// so we know if it worked or not
// This is only one way to do this. It might be beneficial to
// the to place the writing operation in a separate thread
// so that blocking on completion will not negatively
// affect the responsiveness of the UI
// If the write takes long enough to complete, this
// function will timeout according to the
// CommTimeOuts.WriteTotalTimeoutConstant variable.
// At that time we can check for errors and then wait
// some more.
while(!GetOverlappedResult(m_hComm,&m_WriteOS,&dwBytesWritten,TRUE))
{
dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
// normal result if not finished
continue;
else
{
// an error occurred, try to recover
wsprintf( szError, "<CE-%u>", dwError ) ;
MessageBox(NULL,szError,"Write Error",MB_OK);
ClearCommError(m_hComm, &dwErrorFlags, &ComStat ) ;
if ((dwErrorFlags > 0) &&m_bDisplayError)
{
wsprintf( szError, "<CE-%u>", dwErrorFlags ) ;
MessageBox(NULL,szError,"Write Error",MB_OK);
}
break;
}
}
}
else
{
// some other error occurred
ClearCommError(m_hComm, &dwErrorFlags, &ComStat ) ;
if ((dwErrorFlags > 0) && m_bDisplayError)
{
wsprintf( szError, "<CE-%u>", dwErrorFlags ) ;
MessageBox(NULL,szError,"Write Error",MB_OK);
}
return ( FALSE );
}
}
return ( TRUE ) ;
} // end of WriteCommBlock()
void CDataComm::WriteToSerial(BYTE* pbyTransferBlock,UINT nStreamLength)
{
DWORD dwEvtMask=0;
HANDLE phWaitObjects[3]={
m_hQuitEvent,
m_hWriteEvent,
m_hCTSEvent
};
while(1)
{
dwEvtMask=WaitForMultipleObjects(3,phWaitObjects,FALSE,25);
if(dwEvtMask==WAIT_OBJECT_0)
break;
if(dwEvtMask==WAIT_OBJECT_0+1)
{
while(1)
{
WriteCommBlock(pbyTransferBlock,nStreamLength);
break;
if(WAIT_OBJECT_0==WaitForSingleObject(m_hQuitEvent,50))
goto END;
}
}
if(dwEvtMask==WAIT_OBJECT_0+2)
{
static bFull;
bFull=!bFull;
}
if(dwEvtMask==WAIT_TIMEOUT)
{
WriteCommBlock(pbyTransferBlock,nStreamLength);
}
}
END:
m_hWriteThread=NULL;
m_dwWriteThreadID=0;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -