?? serial.cpp
字號:
// Serial.cpp
#include "stdafx.h"
#include "Serial.h"
CSerial::CSerial()
{
m_hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_bThreadAlive = false;
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
m_hIDComDev = INVALID_HANDLE_VALUE;
m_bOpened = FALSE;
}
CSerial::~CSerial()
{
Close();
}
BOOL CSerial::Open( CWnd* pOwner, int nPort, int nBaud )
{
m_pOwner = pOwner;
if( m_bOpened ) return( TRUE );
m_Port = nPort;
char szPort[15];
char szComParams[50];
DCB dcb;
wsprintf( szPort, "COM%d", nPort );
m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
if( m_hIDComDev == INVALID_HANDLE_VALUE ) return( FALSE );
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 5000;
SetCommTimeouts( m_hIDComDev, &CommTimeOuts );
wsprintf( szComParams, "COM%d:%d,n,8,1", nPort, nBaud );
m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
dcb.DCBlength = sizeof( DCB );
GetCommState( m_hIDComDev, &dcb );
dcb.BaudRate = nBaud;
dcb.ByteSize = 8;
unsigned char ucSet;
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_DTRDSR ) != 0 );
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_RTSCTS ) != 0 );
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_XONXOFF ) != 0 );
if( !SetCommState( m_hIDComDev, &dcb ) ||
!SetupComm( m_hIDComDev, 10000, 10000 ) ||
m_OverlappedRead.hEvent == NULL ||
m_OverlappedWrite.hEvent == NULL ){
DWORD dwError = GetLastError();
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hIDComDev );
return( FALSE );
}
m_bOpened = TRUE;
return( m_bOpened );
}
BOOL CSerial::Close( void )
{
if( !m_bOpened || m_hIDComDev == INVALID_HANDLE_VALUE ) return( TRUE );
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hIDComDev );
m_hIDComDev = INVALID_HANDLE_VALUE;
m_bOpened = FALSE;
m_hIDComDev = NULL;
return( TRUE );
}
BOOL CSerial::WriteCommByte( unsigned char ucByte )
{
BOOL bWriteStat;
DWORD dwBytesWritten;
bWriteStat = WriteFile( m_hIDComDev, (LPSTR) &ucByte, 1, &dwBytesWritten, &m_OverlappedWrite );
if( !bWriteStat && ( GetLastError() == ERROR_IO_PENDING ) ){
if( WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 ) ) dwBytesWritten = 0;
else{
GetOverlappedResult( m_hIDComDev, &m_OverlappedWrite, &dwBytesWritten, FALSE );
m_OverlappedWrite.Offset += dwBytesWritten;
}
}
return( TRUE );
}
int CSerial::SendData( const char *buffer, int size )
{
if( !m_bOpened || m_hIDComDev == INVALID_HANDLE_VALUE ) return( 0 );
DWORD dwBytesWritten = 0;
int i;
for( i=0; i<size; i++ ){
WriteCommByte( buffer[i] );
dwBytesWritten++;
}
Sleep(size);
return( (int) dwBytesWritten );
}
int CSerial::ReadDataWaiting( void )
{
if( !m_bOpened || m_hIDComDev == INVALID_HANDLE_VALUE ) return( 0 );
DWORD dwErrorFlags;
COMSTAT ComStat;
ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
return( (int) ComStat.cbInQue );
}
int CSerial::ReadData( void *buffer, int limit )
{
if( !m_bOpened || m_hIDComDev == INVALID_HANDLE_VALUE ) return( 0 );
BOOL bReadStatus;
DWORD dwBytesRead, dwErrorFlags;
COMSTAT ComStat;
ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
if( !ComStat.cbInQue ) return( 0 );
dwBytesRead = (DWORD) ComStat.cbInQue;
if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit;
bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
if( !bReadStatus ){
if( GetLastError() == ERROR_IO_PENDING ){
WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
return( (int) dwBytesRead );
}
return( 0 );
}
return( (int) dwBytesRead );
}
UINT CSerial::CommThread(LPVOID pParam)
{
DWORD nBytesRead, nToRead;
WPARAM wPara;
// Cast the void pointer passed to the thread back to
// a pointer of CSerialPort class
CSerial *port = (CSerial*)pParam;
if( port->m_hIDComDev==INVALID_HANDLE_VALUE ){
return 1;
}
// Set the status variable in the dialog class to
// TRUE to indicate the thread is running.
port->m_bThreadAlive = TRUE;
while( 1 ){
if( WaitForSingleObject( port->m_hEvent, 5 )==WAIT_OBJECT_0 )break;
nToRead = port->ReadDataWaiting();
if( nToRead==0 ){
Sleep(100);
continue;
}
if( nToRead > 1023 )nToRead = 1023;
nBytesRead = port->ReadData( port->m_inBuf, nToRead );
port->m_inBuf[nBytesRead] = 0;
if( nBytesRead>0 ){
char *recBytes;
recBytes = (char *)malloc( nBytesRead+1 );
if( recBytes ){
memcpy( recBytes, port->m_inBuf, nBytesRead );
wPara = (port->m_Port<<24) | nBytesRead; // 高字節(jié)為端口號
PostMessage( port->m_pOwner->m_hWnd, WM_COMM_RXSTR, (WPARAM)wPara, (LPARAM)recBytes );
}
}
}
port->m_bThreadAlive = FALSE;
return 0;
}
void CSerial::Stop()
{
do
{
SetEvent(m_hEvent);
} while (m_bThreadAlive);
}
BOOL CSerial::Start()
{
if (!AfxBeginThread(CommThread, this))return FALSE;
return TRUE;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -