📄 serio.cpp
字号:
///////////////////////////////////////////////////////
// SerIO.cpp
/*
Value Meaning
RTS_CONTROL_DISABLE Disables the RTS line when the device is opened and leaves it disabled.
RTS_CONTROL_ENABLE Enables the RTS line when the device is opened and leaves it on.
RTS_CONTROL_HANDSHAKE Enables RTS handshaking. The driver raises the RTS line when the "type-ahead" (input) buffer is less than one-half full and lowers the RTS line when the buffer is more than three-quarters full. If handshaking is enabled, it is an error for the application to adjust the line by using the EscapeCommFunction function.
RTS_CONTROL_TOGGLE Specifies that the RTS line will be high if bytes are available for transmission. After all buffered bytes have been sent, the RTS line will be low.
*/
#include "stdafx.h"
#include "SerIO.h"
int CSerIO::m_nRTSCtl = 0 ;
CSerIO::CSerIO()
{
m_hCom = INVALID_HANDLE_VALUE;
m_strPort = "";
m_strCommParam = "";
m_dcb.DCBlength = sizeof( m_dcb );
m_dcb.Parity=MARKPARITY;
m_wos.Offset = 0 ;
m_wos.OffsetHigh = 0 ;
m_ros.Offset = 0 ;
m_ros.OffsetHigh = 0 ;
};
CSerIO::~CSerIO()
{
if( m_hCom != INVALID_HANDLE_VALUE )
Close();
}
int CSerIO::SetPortMode( int nMode , BOOL bRec )
{
if( m_hCom == INVALID_HANDLE_VALUE )
return -1;
if( GetCommState( m_hCom, &m_dcb ) == FALSE )
return -1;
if ( bRec )
{
m_dcb.fParity=1;
m_dcb.Parity = nMode ; // 0-4=no,odd,even,mark,space
Sleep(2);
}
else
{
if ( nMode == DATA_MODE )
{
m_dcb.fParity=1;
m_dcb.Parity = 4 ; // 0-4=no,odd,even,mark,space
Sleep(2);
}
else
{
m_dcb.fParity=1;
m_dcb.Parity = 3 ;
Sleep(2);
}
}
if( SetCommState( m_hCom, &m_dcb ) == FALSE )
return -1;
if ( m_nRTSCtl != 0 )
{
if ( bRec )
EscapeCommFunction(m_hCom, CLRRTS ) ;
else
EscapeCommFunction(m_hCom, SETRTS ) ;
Sleep(2) ;
}
return 0 ;
}
BOOL CSerIO::Open( LPCTSTR pszPort, LPCTSTR pszCommParam )
{
m_strPort = pszPort;
m_strCommParam = pszCommParam;
if( m_strPort.IsEmpty() || m_strCommParam.IsEmpty() )
{
SetLastError( SE_INVALID_PARAMETER );
return FALSE;
}
if( m_hCom != INVALID_HANDLE_VALUE )
{
SetLastError( SE_PORT_ALREADY_OPEN );
return FALSE;
}
// Open Communication Device
m_hCom = CreateFile(
m_strPort,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL );
if( m_hCom == INVALID_HANDLE_VALUE )
return FALSE;
if( SetupComm( m_hCom, 1024, 1024 ) == FALSE )
return FALSE;
if( GetCommState( m_hCom, &m_dcb ) == FALSE )
return FALSE;
// Build Device Control Block
if( !BuildCommDCB( m_strCommParam, &m_dcb ) )
return FALSE;
if( SetCommState( m_hCom, &m_dcb ) == FALSE )
return FALSE;
// Clear device buffer
if( PurgeComm( m_hCom, PURGE_TXCLEAR|PURGE_RXCLEAR ) == FALSE )
return FALSE;
// Event object for m_wos ( Overlapped structure )
m_wos.hEvent = CreateEvent(
NULL, // No security
TRUE, // Explicit reset req
FALSE, // Initial event reset
NULL ); // No name
// Event object for m_ros ( Overlapped structure )
m_ros.hEvent = CreateEvent(
NULL, // No security
TRUE, // Explicit reset req
FALSE, // Initial event reset
NULL ); // No name
if( m_wos.hEvent == NULL || m_ros.hEvent == NULL )
return FALSE;
return TRUE;
}
void CSerIO::SetReadTimerOver( int nInterOver , int nMultiOver )
{
COMMTIMEOUTS CommTimeouts ;
if( m_hCom == INVALID_HANDLE_VALUE )
return ;
if ( GetCommTimeouts( m_hCom, &CommTimeouts ) )
{
CommTimeouts.ReadIntervalTimeout = nInterOver ;
CommTimeouts.ReadTotalTimeoutMultiplier = nMultiOver ;
SetCommTimeouts( m_hCom, &CommTimeouts ) ;
}
}
BOOL CSerIO::Close()
{
// Check the device handle
if( m_hCom == INVALID_HANDLE_VALUE )
{
SetLastError( SE_PORT_NOT_OPEN );
return FALSE;
}
if( !CloseHandle( m_hCom ) )
return FALSE;
// Close event objects
CloseHandle( m_wos.hEvent );
CloseHandle( m_ros.hEvent );
m_hCom = INVALID_HANDLE_VALUE;
return TRUE;
}
BOOL CSerIO::Write( PCHAR pchBuffer, DWORD dwLength, DWORD& dwWritten )
{
BOOL bSuccess;
DWORD dwErrCode, dwErrorFlags;
COMSTAT ComStat;
DWORD dwTime = GetTickCount() ;
dwWritten = 0;
// Check the device handle
if( m_hCom == INVALID_HANDLE_VALUE )
{
SetLastError( SE_PORT_NOT_OPEN );
return FALSE;
}
if( pchBuffer == NULL )
{
SetLastError( SE_INVALID_PARAMETER );
return FALSE;
}
// Write to port
bSuccess = WriteFile(
m_hCom,
(PVOID)pchBuffer,
dwLength,
&dwWritten,
&m_wos );
if( !bSuccess )
{
dwErrCode = GetLastError();
if( dwErrCode == ERROR_IO_PENDING )
{
while( !GetOverlappedResult(
m_hCom,
&m_wos,
&dwWritten,
FALSE ) )
{
dwErrCode = GetLastError();
if( dwErrCode == ERROR_IO_INCOMPLETE )
{
if ( GetTickCount() - dwTime > 500 )
{
ClearCommError( m_hCom, &dwErrorFlags, &ComStat );
return FALSE;
}
Sleep(1) ;
continue;
}
else
{
ClearCommError( m_hCom, &dwErrorFlags, &ComStat );
break;
}
}
return TRUE;
}
else
{
ClearCommError( m_hCom, &dwErrorFlags, &ComStat );
return FALSE;
}
}
else
return TRUE;
}
BOOL CSerIO::Read( PCHAR pchBuffer, DWORD dwMaxLength, DWORD& dwRead )
{
BOOL bSuccess;
DWORD dwErrCode, dwErrorFlags;
DWORD dwLength;
COMSTAT ComStat;
DWORD dwTime = GetTickCount() ;
dwRead = 0;
if( m_hCom == INVALID_HANDLE_VALUE )
{
SetLastError( SE_PORT_NOT_OPEN );
return FALSE;
}
if( pchBuffer == NULL )
{
SetLastError( SE_INVALID_PARAMETER );
return FALSE;
}
ClearCommError( m_hCom, &dwErrorFlags, &ComStat ) ;
dwLength = min( dwMaxLength, ComStat.cbInQue ) ;
if( dwLength > 0 )
{
bSuccess = ReadFile(
m_hCom,
(PVOID)pchBuffer,
dwLength,
&dwRead,
&m_ros );
if( !bSuccess )
{
dwErrCode = GetLastError();
if( dwErrCode == ERROR_IO_PENDING )
{
while( !GetOverlappedResult(
m_hCom,
&m_ros,
&dwRead,
FALSE ) )
{
dwErrCode = GetLastError();
if( dwErrCode == ERROR_IO_INCOMPLETE )
{
if ( GetTickCount() - dwTime > 500 )
{
ClearCommError( m_hCom, &dwErrorFlags, &ComStat );
return FALSE;
}
Sleep(1) ;
continue;
}
else
{
ClearCommError( m_hCom, &dwErrorFlags, &ComStat );
return TRUE;
}
}
return TRUE;
}
else
{
ClearCommError( m_hCom, &dwErrorFlags, &ComStat );
return FALSE;
}
}
else
return TRUE;
}
else
{
Sleep( 10 );
return TRUE ;
}
}
BOOL CSerIO::PutChar( UCHAR uch )
{
UCHAR uCH = uch;
DWORD dwWritten;
// Put a character to port
return Write( (PCHAR)&uCH, 1, dwWritten );
}
BOOL CSerIO::GetChar( UCHAR& uch )
{
DWORD dwRead;
// Get a character from port
return Read( (PCHAR)&uch, 1, dwRead );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -