📄 serialportbase.cpp
字号:
// CSerialPortBase.cpp: implementation of the CSerialPortBase class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <process.h>
#include "SerialPortBase.h"
unsigned int _stdcall CSerialPortBase::ThreadFunc( void* pArg )
{
CSerialPortBase* pSerialPortBase = (CSerialPortBase*) pArg;
return pSerialPortBase->Run();
}
BOOL CSerialPortBase::SetPortName(LPCTSTR strPortName)
{
if ( IsThreadRunning() )
{
return FALSE;
}
else
{
int len = strlen(strPortName);
if ( len <10 )
{
for ( int i=0; i<=len; i++ )
{
m_strPortName[i]=strPortName[i];
}
return TRUE;
}
else
{
return FALSE;
}
}
}
unsigned int CSerialPortBase::Run()
{
m_bRunning = OnStartup();
EventLoop2();
OnShutdown();
m_hThread = INVALID_HANDLE_VALUE;
return 0;
}
DWORD CSerialPortBase::StartThread( void )
{
if ( IsRunning() )
{
TRACE("The thread 0x%0X is already runnung\n", m_nThreadID);
return 0;
}
// Create the thread
m_hThread = (HANDLE)_beginthreadex( NULL, 0, ThreadFunc, this, 0, &m_nThreadID );
if ( m_hThread == INVALID_HANDLE_VALUE )
{
// Error creating thread
m_bRunning = FALSE;
TRACE("The thread start failed\n");
return -1;
}
else
{
TRACE("The thread 0x%0X has started\n", m_nThreadID);
// Success
m_bRunning = TRUE;
return 0;
}
}
void CSerialPortBase::StopThread()
{
if ( IsRunning() )
{
m_bRunning = FALSE;
}
if ( IsThreadRunning() )
{
::WaitForSingleObject(GetHandle(), INFINITE);
}
}
BOOL CSerialPortBase::OnStartup( void )
{
if ( FALSE == SerialPortOpen(m_strPortName) )
return FALSE;
if ( FALSE == ConfigurePort() )
return FALSE;
if ( FALSE == ConfigureTimeOuts() )
return FALSE;
return TRUE;
}
void CSerialPortBase::OnShutdown( void )
{
SerialPortClose();
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSerialPortBase::CSerialPortBase()
:m_hThread(INVALID_HANDLE_VALUE)
,m_bRunning(FALSE)
,m_hSerialPort(INVALID_HANDLE_VALUE)
{
}
CSerialPortBase::~CSerialPortBase()
{
}
BOOL CSerialPortBase::SerialPortOpen(LPCTSTR lpszPortName)
{
// if ( m_hSerialPort != INVALID_HANDLE_VALUE )
// {
// CloseHandle(m_hSerialPort);
// }
m_hSerialPort = ::CreateFile (lpszPortName, // Pointer to the name of the port
GENERIC_READ | GENERIC_WRITE,
// Access (read-write) mode
0, // Share mode
NULL, // Pointer to the security attribute
OPEN_EXISTING,// How to open the serial port
0, // Port attributes
NULL); // Handle to port with attribute
// to copy
if ( m_hSerialPort == INVALID_HANDLE_VALUE )
{
TRACE("Err CreateFile!");
return FALSE;
}
else
{
return TRUE;
}
}
BOOL CSerialPortBase::ConfigurePort()
{
DCB PortDCB;
// Initialize the DCBlength member.
PortDCB.DCBlength = sizeof (DCB);
// Get the default port setting information.
GetCommState (m_hSerialPort, &PortDCB);
// Change the DCB structure settings.
PortDCB.BaudRate = 9600; // Current baud
PortDCB.fBinary = TRUE; // Binary mode; no EOF check
PortDCB.fParity = TRUE; // Enable parity checking
PortDCB.fOutxCtsFlow = FALSE; // No CTS output flow control
PortDCB.fOutxDsrFlow = FALSE; // No DSR output flow control
PortDCB.fDtrControl = DTR_CONTROL_ENABLE;
// DTR flow control type
PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity
PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx
PortDCB.fOutX = FALSE; // No XON/XOFF out flow control
PortDCB.fInX = FALSE; // No XON/XOFF in flow control
PortDCB.fErrorChar = FALSE; // Disable error replacement
PortDCB.fNull = FALSE; // Disable null stripping
PortDCB.fRtsControl = RTS_CONTROL_ENABLE;
// RTS flow control
PortDCB.fAbortOnError = FALSE; // Do not abort reads/writes on
// error
PortDCB.ByteSize = 8; // Number of bits/byte, 4-8
PortDCB.Parity = NOPARITY; // 0-4=no,odd,even,mark,space
PortDCB.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2
// Configure the port according to the specifications of the DCB
// structure.
if (!SetCommState (m_hSerialPort, &PortDCB))
{
// Could not configure the serial port.
return FALSE;
}
else
{
return TRUE;
}
}
BOOL CSerialPortBase::ConfigureTimeOuts()
{
// Retrieve the time-out parameters for all read and write operations
// on the port.
COMMTIMEOUTS CommTimeouts;
GetCommTimeouts (m_hSerialPort, &CommTimeouts);
// Change the COMMTIMEOUTS structure settings.
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
CommTimeouts.ReadTotalTimeoutConstant = 100;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 1000;
// Set the time-out parameters for all read and write operations
// on the port.
if (!SetCommTimeouts (m_hSerialPort, &CommTimeouts))
{
// // Could not set the time-out parameters.
// MessageBox (hMainWnd, TEXT("Unable to set the time-out parameters"),
// TEXT("Error"), MB_OK);
// dwError = GetLastError ();
return FALSE;
}
else
{
return TRUE;
}
}
void CSerialPortBase::SerialPortClose()
{
CloseHandle(m_hSerialPort);
m_hSerialPort = INVALID_HANDLE_VALUE;
}
void CSerialPortBase::EventLoop2()
{
BYTE Byte;
DWORD dwBytesTransferred;
// Loop for waiting for the data.
do
{
// Read the data from the serial port.
ReadFile (m_hSerialPort, &Byte, 1, &dwBytesTransferred, 0);
// Display the data read.
if (dwBytesTransferred == 1)
{
ProcessChar (Byte);
}
else
{
TRACE("TimeOut!\n");
}
Sleep(100);
}
while (m_hSerialPort != INVALID_HANDLE_VALUE && m_bRunning ) ;
}
void CSerialPortBase::ProcessChar (TCHAR Byte)
{
TRACE("AA ");
}
#if 0
void CSerialPortBase::EventLoop()
{
DWORD dwCommModemStatus;
// Specify a set of events to be monitored for the port.
SetCommMask (m_hSerialPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);
while (m_hSerialPort != INVALID_HANDLE_VALUE && m_bRunning )
{
// Wait for an event to occur for the port.
WaitCommEvent (m_hSerialPort, &dwCommModemStatus, 0);
TRACE("Passed WaitCommEvent!\n");
// Re-specify the set of events to be monitored for the port.
SetCommMask (m_hSerialPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING);
if( dwCommModemStatus & EV_CTS ) //#define EV_CTS 0x0008 // CTS changed state
{
//TRACE( "CSerialPortBase::OnCommEvent: CTS changed state\n" );
OnCommEventCTS();
}
if( dwCommModemStatus & EV_ERR ) //#define EV_ERR 0x0080 // Line status error occurred
{
//TRACE( "CSerialPortBase::OnCommEvent: Error\n" );
OnCommEventErr();
}
if( dwCommModemStatus & EV_DSR ) //#define EV_DSR 0x0010 // DSR changed state
{
//TRACE( "CSerialPortBase::OnCommEvent: DSR changed state\n" );
OnCommEventDSR();
}
if( dwCommModemStatus & EV_RLSD ) //#define EV_RLSD 0x0020 // RLSD changed state
{
//TRACE( "CSerialPortBase::OnCommEvent: RLSD changed state\n" );
OnCommEventRLSD();
}
if( dwCommModemStatus & EV_BREAK ) //#define EV_BREAK 0x0040 // BREAK received
{
//TRACE( "CSerialPortBase::OnCommEvent: Break detected\n" );
OnCommEventBreak();
}
if( dwCommModemStatus & EV_TXEMPTY ) //#define EV_TXEMPTY 0x0004 // Transmitt Queue Empty
{
//TRACE( "CSerialPortBase::OnCommEvent: Transmitt Queue Empty\n" );
OnCommEventTxEmpty();
}
if( dwCommModemStatus & EV_RXCHAR ) //#define EV_RXCHAR 0x0001 // Any Character received
{
//TRACE( "CSerialPortBase::OnCommEvent: Any Character received\n" );
OnCommEventRxChar();
}
if( dwCommModemStatus & EV_RXFLAG ) //#define EV_RXFLAG 0x0002 // Received certain character
{
//TRACE( "CSerialPortBase::OnCommEvent: Received certain character\n" );
OnCommEventRxFlag();
}
if( dwCommModemStatus & EV_RING ) //#define EV_RING 0x0100 // Ring signal detected
{
//TRACE( "CSerialPortBase::OnCommEvent: Ring signal detected\n" );
OnCommEventRing();
}
if( dwCommModemStatus & EV_PERR ) //#define EV_PERR 0x0200 // Printer error occured
{
//TRACE( "CSerialPortBase::OnCommEvent: Printer error occured\n" );
OnCommEventPERR();
}
if( dwCommModemStatus & EV_RX80FULL ) //#define EV_RX80FULL 0x0400 // Receive buffer is 80 percent full
{
//TRACE( "CSerialPortBase::OnCommEvent: Receive buffer is 80 percent full\n" );
OnCommEventRx80Full();
}
if( dwCommModemStatus & EV_EVENT1 ) //#define EV_EVENT1 0x0800 // Provider specific event 1
{
//TRACE( "CSerialPortBase::OnCommEvent: Provider specific event 1\n" );
OnCommEventEvent1();
}
if( dwCommModemStatus & EV_EVENT2 ) //#define EV_EVENT2 0x1000 // Provider specific event 2
{
//TRACE( "CSerialPortBase::OnCommEvent: Provider specific event 2\n" );
OnCommEventEvent2();
}
}
m_bRunning = FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// Comm Event Handlers
///////////////////////////////////////////////////////////////////////////////
void CSerialPortBase::OnCommEventRxChar(void)
{ //#define EV_RXCHAR 0x0001 // Any Character received
BYTE Byte;
DWORD dwBytesTransferred;
// Loop for waiting for the data.
do
{
// Read the data from the serial port.
ReadFile (m_hSerialPort, &Byte, 1, &dwBytesTransferred, 0);
// Display the data read.
if (dwBytesTransferred == 1)
ProcessChar (Byte);
} while (dwBytesTransferred == 1);
}
void CSerialPortBase::OnCommEventRxFlag(void) {} //#define EV_RXFLAG 0x0002 // Received certain character
void CSerialPortBase::OnCommEventTxEmpty(void) {} //#define EV_TXEMPTY 0x0004 // Transmitt Queue Empty
void CSerialPortBase::OnCommEventCTS(void) {} //#define EV_CTS 0x0008 // CTS changed state
void CSerialPortBase::OnCommEventDSR(void) {} //#define EV_DSR 0x0010 // DSR changed state
void CSerialPortBase::OnCommEventRLSD(void) {} //#define EV_RLSD 0x0020 // RLSD changed state
void CSerialPortBase::OnCommEventBreak(void) {} //#define EV_BREAK 0x0040 // BREAK received
void CSerialPortBase::OnCommEventErr(void) {} //#define EV_ERR 0x0080 // Line status error occurred
void CSerialPortBase::OnCommEventRing(void) {} //#define EV_RING 0x0100 // Ring signal detected
void CSerialPortBase::OnCommEventPERR(void) {} //#define EV_PERR 0x0200 // Printer error occured
void CSerialPortBase::OnCommEventRx80Full(void) {} //#define EV_RX80FULL 0x0400 // Receive buffer is 80 percent full
void CSerialPortBase::OnCommEventEvent1(void) {} //#define EV_EVENT1 0x0800 // Provider specific event 1
void CSerialPortBase::OnCommEventEvent2(void) {} //#define EV_EVENT2 0x1000 // Provider specific event 2
///////////////////////////////////////////////////////////////////////////////
// Write to Port
///////////////////////////////////////////////////////////////////////////////
BOOL CSerialPortBase::Write(LPCTSTR lpBuffer, DWORD nNumberOfBytesToWrite)
{
DWORD dwNumBytesWritten;
DWORD dwStart=0;
while (dwStart < nNumberOfBytesToWrite )
{
if ( FALSE == WriteFile(m_hSerialPort,
&lpBuffer[dwStart],
nNumberOfBytesToWrite - dwStart,
&dwNumBytesWritten,
NULL) )
{
return FALSE;
}
else
{
dwStart+=dwNumBytesWritten;
}
}
return TRUE;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -