📄 serialport.cpp
字号:
// SerialPort.cpp: implementation of the CSerialPort class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SerialPort.h"
#include "process.h"
#include <assert.h>
/***********global variable**********/
UINT WINAPI CommThread(void* lpParameter);
HANDLE g_hReadSignal;
HANDLE g_hWriteSignal;
UCHAR RXBuffer;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSerialPort::CSerialPort()
{
m_ov.hEvent = NULL;
m_ov.Offset = 0;
m_ov.Internal = 0;
m_hWriteEvent = NULL;
m_szWriteBuffer = NULL;
m_hShutdownEvent = NULL;
m_nSendDataLen = 0;
}
CSerialPort::~CSerialPort()
{
SetEvent(m_hShutdownEvent);
delete [] m_szWriteBuffer;
}
/*/*******************************************************************
--Function name:
--Function Description:
--Function involved:
--Global variable :
--Input :
--Output:
--Designer: song Time : 08.3.17
--Modifier: Time :
--Version: v0.1
--*******************************************************************/
void ReceiveChar(CSerialPort *port)
{
BOOL bRead = TRUE;
BOOL bResult = TRUE;
DWORD dwError = 0;
DWORD BytesRead = 0;
COMSTAT comstat;
while (1)
{
bResult = ClearCommError(port->m_hCom,&dwError,&comstat);
if (comstat.cbInQue == 0)
{
break;
}
if (bRead)
{
bResult = ReadFile(port->m_hCom,
&RXBuffer,
1,
&BytesRead,
&port->m_ov);
if (!bResult)
{
switch(dwError = GetLastError())
{
case ERROR_IO_PENDING:
{
bRead = FALSE;
break;
}
default:
{
port->ProcessErrorMessage("ReadFile()");
break;
}
}
}
else
{
bRead = TRUE;
}
}
if (!bRead)
{
bRead = TRUE;
bResult = GetOverlappedResult(port->m_hCom,
&port->m_ov,
&BytesRead,
TRUE);
if (!bResult)
{
port->ProcessErrorMessage("GetOverlappedResult() in ReadFile()");
}
}
SetEvent(g_hReadSignal);
ResetEvent(port->m_ov.hEvent);
}
}
/*/*******************************************************************
--Function name:
--Function Description:
--Function involved:
--Global variable :
--Input :
--Output:
--Designer: song Time : 08.3.17
--Modifier: Time :
--Version: v0.1
--*******************************************************************/
void WriteChar(CSerialPort *port)
{
BOOL bWrite = TRUE;
BOOL bResult = TRUE;
DWORD BytesSent = 0;
OutputDebugString("write function is running");
ResetEvent(port->m_hWriteEvent);
if (bWrite)
{
port->m_ov.Offset = 0;
port->m_ov.Internal = 0;
port->m_ov.OffsetHigh = 0;
/* clear buffer */
PurgeComm(port->m_hCom,PURGE_RXCLEAR | PURGE_TXCLEAR |PURGE_RXABORT | PURGE_TXABORT);
bResult = WriteFile(port->m_hCom,
port->m_szWriteBuffer,
port->m_nSendDataLen,
&BytesSent,
&port->m_ov);
/* deal with any error codes */
if (!bResult)
{
DWORD dwError = GetLastError();
switch(dwError)
{
case ERROR_IO_PENDING:
{
BytesSent = 0;
bWrite = FALSE;
break;
}
default:
{
port->ProcessErrorMessage("WriteFile()");
}
}
}
}
if (!bWrite)
{
bWrite = TRUE;
bResult = GetOverlappedResult(port->m_hCom,
&port->m_ov,
&BytesSent,
TRUE);
if (!bResult)
{
port->ProcessErrorMessage("GetoverlappedResults() in WriteFile()");
}
}
if (BytesSent != port->m_nSendDataLen)
{
OutputDebugString("WARNING:writeFile() error..BytesSent;Message Length\n");
ResetEvent(port->m_ov.hEvent);
}
FlushFileBuffers(port->m_hCom);
SetEvent(g_hWriteSignal);
}
/*/*******************************************************************
--Function name:
--Function Description:
--Function involved:
--Global variable :
--Input :
--Output:
--Designer: song Time : 08.3.17
--Modifier: Time :
--Version: v0.1
--*******************************************************************/
UINT WINAPI CommThread(void* lpParameter)
{
CSerialPort *port = (CSerialPort*)lpParameter;
BOOL bResult = TRUE;
DWORD CommEvent = 0;
DWORD dwError = 0;
COMSTAT commStat;
DWORD receiveEvent = 0;
if (port->m_hCom)
{
PurgeComm(port->m_hCom,PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
}
OutputDebugString("thread1 is running");
while (1)
{
bResult = WaitCommEvent(port->m_hCom,&CommEvent,&port->m_ov);
if (!bResult)
{
switch(dwError = GetLastError())
{
case ERROR_IO_PENDING:
{
break;
}
case 87:
{
break;
}
default:
{
port->ProcessErrorMessage("WaitCommEvent()");
}
}
ClearCommError(port->m_hCom,&dwError,&commStat);
} //end of if(!bResult)
CommEvent = WaitForMultipleObjects(3,port->m_hEventArray,FALSE,INFINITE);
switch(CommEvent)
{
case 0: //shutdown event
{
_endthreadex(0);
CloseHandle(port->m_hCom);
break;
}
case 1: //read event
{
ResetEvent(port->m_ov.hEvent);
if (GetCommMask(port->m_hCom,&receiveEvent))
{
if (receiveEvent & EV_RXCHAR)
{
ReceiveChar(port);
}
}
break;
}
case 2: //write event
{
ResetEvent(port->m_hWriteEvent);
WriteChar(port);
break;
}
}
}
return 0;
}
/*/*******************************************************************
--Function name:
--Function Description:
--Function involved:
--Global variable :
--Input :
--Output:
--Designer: song Time : 08.3.17
--Modifier: Time :
--Version: v0.1
--*******************************************************************/
BOOL CSerialPort::InitPort(UINT portNum, UINT baud, char parity, UINT dataBits, UINT stopsBits, DWORD dwCommEvents, UINT nBufferSize)
{
DWORD dwError;
BOOL bResult = FALSE;
char *szPort = new char[50];
char *szBaud = new char[50];
// prepare port strings
sprintf(szPort, "COM%d", portNum);
sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, dataBits, stopsBits);
if (m_szWriteBuffer != NULL)
delete [] m_szWriteBuffer;
m_szWriteBuffer = new char[nBufferSize];
m_nPortNr = portNum;
m_nBaud = baud;
m_nParity = parity;
m_nDatabits = dataBits;
m_nStopbits = stopsBits;
m_nWriteBufferSize = nBufferSize;
m_dwCommEvents = dwCommEvents;
if (m_ov.hEvent != NULL)
{
ResetEvent(m_ov.hEvent);
}
else
{
m_ov.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
}
if (m_hWriteEvent != NULL)
{
ResetEvent(m_hWriteEvent);
}
else
{
m_hWriteEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
}
if (m_hShutdownEvent != NULL)
{
ResetEvent(m_hShutdownEvent);
}
else
{
m_hShutdownEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
}
SetThreadPriority(m_hShutdownEvent,THREAD_PRIORITY_HIGHEST);
/* this event is used for work thread to notify main thread read operation is complete*/
g_hReadSignal = CreateEvent(NULL,TRUE,FALSE,NULL);
g_hWriteSignal = CreateEvent(NULL,TRUE,FALSE,NULL);
m_hEventArray[0] = m_hShutdownEvent;
m_hEventArray[1] = m_ov.hEvent;
m_hEventArray[2] = m_hWriteEvent;
// get a handle to the port
m_hCom = CreateFile(szPort, // communication port string (COMX)
GENERIC_READ | GENERIC_WRITE, // read/write types
0, // comm devices must be opened with exclusive access
NULL, // no security attributes
OPEN_EXISTING, // comm devices must use OPEN_EXISTING
FILE_FLAG_OVERLAPPED, // Async I/O
0); // template must be 0 for comm devices
if (m_hCom == INVALID_HANDLE_VALUE)
{
// port not found
dwError=GetLastError();
switch(dwError)
{
case 0:
break;
default:
break;
}
delete [] szPort;
delete [] szBaud;
return FALSE;
}
/* set the timeout values,the base unit is ms */
m_Timeouts.ReadIntervalTimeout = 1000;
m_Timeouts.ReadTotalTimeoutMultiplier = 1000;
m_Timeouts.ReadTotalTimeoutConstant = 1000;
m_Timeouts.WriteTotalTimeoutMultiplier = 1000;
m_Timeouts.WriteTotalTimeoutConstant = 1000;
/* set the timeout values,if success return nonzero */
if (SetCommTimeouts(m_hCom,&m_Timeouts))
{
/* set event mask to monitor given port event */
if (SetCommMask(m_hCom,m_dwCommEvents))
{
/* get the current DCB structure */
if(GetCommState(m_hCom,&m_dcb))
{
/* change DCB settings */
if (BuildCommDCB(szBaud,&m_dcb))
{
/* set the current DCB structure */
if (SetCommState(m_hCom,&m_dcb))
{
/* there is no error ,continue execute */
}
else
{
ProcessErrorMessage("SetCommState()");
}
}
else
{
ProcessErrorMessage("BuildCommDCB()");
}
}
else
{
ProcessErrorMessage("GetCommState()");
}
}
else
{
ProcessErrorMessage("SetCommMask()");
}
}
else
{
ProcessErrorMessage("SetCommTimeouts()");
}
return TRUE;
}
/*/*******************************************************************
--Function name:
--Function Description:
--Function involved:
--Global variable :
--Input :
--Output:
--Designer: song Time : 08.3.17
--Modifier: Time :
--Version: v0.1
--*******************************************************************/
void CSerialPort::ProcessErrorMessage(char *ErrorText)
{
char *Temp = new char[200];
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
sprintf(Temp, "WARNING: %s Failed with the following error: \n%s\nPort: %d\n", (char*)ErrorText, lpMsgBuf, m_nPortNr);
MessageBox(NULL, Temp, "Application Error", MB_ICONSTOP);
LocalFree(lpMsgBuf);
delete[] Temp;
}
/*/*******************************************************************
--Function name:
--Function Description:
--Function involved:
--Global variable :
--Input :
--Output:
--Designer: song Time : 08.3.17
--Modifier: Time :
--Version: v0.1
--*******************************************************************/
BOOL CSerialPort::StartMonitoring()
{
if (!(m_handle = (HANDLE)_beginthreadex(NULL,0,CommThread,this,0,NULL)))
{
return FALSE;
}
ResumeThread(m_handle);
OutputDebugString("thread is running");
return TRUE;
}
/*/*******************************************************************
--Function name:
--Function Description:
--Function involved:
--Global variable :
--Input :
--Output:
--Designer: song Time : 08.3.17
--Modifier: Time :
--Version: v0.1
--*******************************************************************/
void CSerialPort::WriteData(char *string,UINT length)
{
assert(m_hCom);
memset(m_szWriteBuffer,0,m_nWriteBufferSize);
memcpy(m_szWriteBuffer,string,length);
m_nSendDataLen = length;
SetEvent(m_hWriteEvent);
}
/*/*******************************************************************
--Function name:
--Function Description:
--Function involved:
--Global variable :
--Input :
--Output:
--Designer: song Time : 08.3.17
--Modifier: Time :
--Version: v0.1
--*******************************************************************/
BOOL CSerialPort::StopMonitoring()
{
OutputDebugString("Thread suspended\n");
SuspendThread(m_hCom);
return TRUE;
}
/*/*******************************************************************
--Function name:
--Function Description:
--Function involved:
--Global variable :
--Input :
--Output:
--Designer: song Time : 08.3.17
--Modifier: Time :
--Version: v0.1
--*******************************************************************/
BOOL CSerialPort::RestartMonitoring()
{
OutputDebugString("Thread resumed\n");
ResumeThread(m_hCom);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -