📄 serialport.cpp
字号:
LocalFree(lpMsgBuf);
delete[] Temp;
}
//
// Write a character.
//
void CSerialPort::WriteChar(CSerialPort* port)
{
BOOL bWrite = TRUE;
BOOL bResult = TRUE;
DWORD BytesSent = 0;
ResetEvent(port->m_hWriteEvent);
// Gain ownership of the critical section
EnterCriticalSection(&port->m_csCommunicationSync);
if (bWrite)
{
// Initailize variables
port->m_ov.Offset = 0;
port->m_ov.OffsetHigh = 0;
// Clear buffer
PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
bResult = WriteFile(port->m_hComm, // Handle to COMM Port
port->m_szWriteBuffer, // Pointer to message buffer in calling finction
strlen((char*)port->m_szWriteBuffer), // Length of message to send
&BytesSent, // Where to store the number of bytes sent
&port->m_ov); // Overlapped structure
// deal with any error codes
if (!bResult)
{
DWORD dwError = GetLastError();
switch (dwError)
{
case ERROR_IO_PENDING:
{
// continue to GetOverlappedResults()
BytesSent = 0;
bWrite = FALSE;
break;
}
default:
{
// all other error codes
port->ProcessErrorMessage("WriteFile()");
}
}
}
else
{
LeaveCriticalSection(&port->m_csCommunicationSync);
}
} // end if(bWrite)
if (!bWrite)
{
bWrite = TRUE;
bResult = GetOverlappedResult(port->m_hComm, // Handle to COMM port
&port->m_ov, // Overlapped structure
&BytesSent, // Stores number of bytes sent
TRUE); // Wait flag
LeaveCriticalSection(&port->m_csCommunicationSync);
// deal with the error code
if (!bResult)
{
port->ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
}
} // end if (!bWrite)
// Verify that the data size send equals what we tried to send
if (BytesSent != strlen((char*)port->m_szWriteBuffer))
{
TRACE("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)port->m_szWriteBuffer));
}
}
//
// Character received. Inform the owner
//
void CSerialPort::ReceiveChar(CSerialPort* port, COMSTAT comstat)
{
BOOL bRead = TRUE;
BOOL bResult = TRUE;
DWORD dwError = 0;
DWORD BytesRead = 0;
unsigned char RXBuff;
for (;;)
{
// Gain ownership of the comm port critical section.
// This process guarantees no other part of this program
// is using the port object.
EnterCriticalSection(&port->m_csCommunicationSync);
// ClearCommError() will update the COMSTAT structure and
// clear any other errors.
bResult = ClearCommError(port->m_hComm, &dwError, &comstat);
LeaveCriticalSection(&port->m_csCommunicationSync);
// start forever loop. I use this type of loop because I
// do not know at runtime how many loops this will have to
// run. My solution is to start a forever loop and to
// break out of it when I have processed all of the
// data available. Be careful with this approach and
// be sure your loop will exit.
// My reasons for this are not as clear in this sample
// as it is in my production code, but I have found this
// solutiion to be the most efficient way to do this.
if (comstat.cbInQue == 0)
{
// break out when all bytes have been read
break;
}
EnterCriticalSection(&port->m_csCommunicationSync);
if (bRead)
{
bResult = ReadFile(port->m_hComm, // Handle to COMM port
&RXBuff, // RX Buffer Pointer
1, // Read one byte
&BytesRead, // Stores number of bytes read
&port->m_ov); // pointer to the m_ov structure
// deal with the error code
if (!bResult)
{
switch (dwError = GetLastError())
{
case ERROR_IO_PENDING:
{
// asynchronous i/o is still in progress
// Proceed on to GetOverlappedResults();
bRead = FALSE;
break;
}
default:
{
// Another error has occured. Process this error.
port->ProcessErrorMessage("ReadFile()");
break;
}
}
}
else
{
// ReadFile() returned complete. It is not necessary to call GetOverlappedResults()
bRead = TRUE;
}
} // close if (bRead)
if (!bRead)
{
bRead = TRUE;
bResult = GetOverlappedResult(port->m_hComm, // Handle to COMM port
&port->m_ov, // Overlapped structure
&BytesRead, // Stores number of bytes read
TRUE); // Wait flag
// deal with the error code
if (!bResult)
{
port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
}
} // close if (!bRead)
LeaveCriticalSection(&port->m_csCommunicationSync);
// notify parent that a byte was received
::SendMessage((port->m_pOwner)->m_hWnd, WM_COMM_RXCHAR, (WPARAM) RXBuff, (LPARAM) port->m_nPortNr);
} // end forever loop
}
//
// Write a string to the port
//
void CSerialPort::WriteToPort(char* string)
{
assert(m_hComm != 0);
memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
strcpy(m_szWriteBuffer, string);
// set event for write
SetEvent(m_hWriteEvent);
}
//
// Return the device control block
//
DCB CSerialPort::GetDCB()
{
return m_dcb;
}
//
// Return the communication event masks
//
DWORD CSerialPort::GetCommEvents()
{
return m_dwCommEvents;
}
//
// Return the output buffer size
//
DWORD CSerialPort::GetWriteBufferSize()
{
return m_nWriteBufferSize;
}
///////////////////////////////////////////////////////////////////
//增加4个函数方便收发数据块
//SendBlock(BYTE *pBuf, unsigned long nLength):发送数据块
//virtual OnReceived(BYTE *pBuf, UINT nLength):当接受到指定长度的数据块时
//默认函数将发送消息给窗口
//SetExpRcv(nLength):设定接收数据块的长度
unsigned long CSerialPort::SendBlock(BYTE *pBuf, unsigned long nLength)
{
BOOL bWrite = TRUE;
BOOL bResult = TRUE;
unsigned long nBytesSent=0;
DWORD BytesSent = 0;
ResetEvent(this->m_hWriteEvent);
// Gain ownership of the critical section
EnterCriticalSection(&this->m_csCommunicationSync);
if (bWrite)
{
// Initailize variables
this->m_ov.Offset = 0;
this->m_ov.OffsetHigh = 0;
// Clear buffer
PurgeComm(this->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
bResult = WriteFile(this->m_hComm, // Handle to COMM Port
pBuf, // Pointer to message buffer in calling finction
nLength, // Length of message to send
&nBytesSent, // Where to store the number of bytes sent
&this->m_ov); // Overlapped structure
// deal with any error codes
if (!bResult)
{
DWORD dwError = GetLastError();
switch (dwError)
{
case ERROR_IO_PENDING:
{
// continue to GetOverlappedResults()
nBytesSent = 0;
bWrite = FALSE;
break;
}
default:
{
// all other error codes
this->ProcessErrorMessage("WriteFile()");
}
}
}
else
{
LeaveCriticalSection(&this->m_csCommunicationSync);
}
} // end if(bWrite)
if (!bWrite)
{
bWrite = TRUE;
bResult = GetOverlappedResult(this->m_hComm, // Handle to COMM port
&this->m_ov, // Overlapped structure
&nBytesSent, // Stores number of bytes sent
TRUE); // Wait flag
LeaveCriticalSection(&this->m_csCommunicationSync);
// deal with the error code
if (!bResult)
{
this->ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
}
} // end if (!bWrite)
// Verify that the data size send equals what we tried to send
if (nBytesSent != nLength)
{
TRACE("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)this->m_szWriteBuffer));
}
TRACE("Byts Sent:%d\n",nBytesSent);
return nBytesSent;
}
void CSerialPort::ReceiveBlock(COMSTAT comstat)
{
BOOL bRead = TRUE;
BOOL bResult = TRUE;
DWORD dwError = 0;
DWORD nBytesRcv = 0;
for (;;)
{
// Gain ownership of the comm port critical section.
// This process guarantees no other part of this program
// is using the port object.
EnterCriticalSection(&this->m_csCommunicationSync);
// ClearCommError() will update the COMSTAT structure and
// clear any other errors.
bResult = ClearCommError(this->m_hComm, &dwError, &comstat);
LeaveCriticalSection(&this->m_csCommunicationSync);
if (comstat.cbInQue == 0)
{
// break out when all bytes have been read
break;
}
EnterCriticalSection(&this->m_csCommunicationSync);
if (bRead)
{
bResult = ReadFile(this->m_hComm, // Handle to COMM port
RxdBuf, // RX Buffer Pointer
m_nBytesExpected, // Read one byte
&nBytesRcv, // Stores number of bytes read
&this->m_ov); // pointer to the m_ov structure
// deal with the error code
if (!bResult)
{
switch (dwError = GetLastError())
{
case ERROR_IO_PENDING:
{
// asynchronous i/o is still in progress
// Proceed on to GetOverlappedResults();
bRead = FALSE;
break;
}
default:
{
// Another error has occured. Process this error.
this->ProcessErrorMessage("ReadFile()");
break;
}
}
}
else
{
// ReadFile() returned complete. It is not necessary to call GetOverlappedResults()
bRead = TRUE;
}
} // close if (bRead)
if (!bRead)
{
bRead = TRUE;
bResult = GetOverlappedResult(this->m_hComm, // Handle to COMM port
&this->m_ov, // Overlapped structure
&nBytesRcv, // Stores number of bytes read
TRUE); // Wait flag
// deal with the error code
if (!bResult)
{
this->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
}
} // close if (!bRead)
LeaveCriticalSection(&this->m_csCommunicationSync);
// notify parent that a byte was received
OnReceived ((BYTE*)RxdBuf, nBytesRcv);
} // end forever loop
}
void CSerialPort::OnReceived(BYTE *pBuf, UINT nLength)
{
::PostMessage((this->m_pOwner)->m_hWnd, WM_COMM_RXD, (WPARAM)pBuf, (LPARAM)nLength);
}
void CSerialPort::SetExpRcv(UINT nLength)
{
m_nBytesExpected=nLength;
if(RxdBuf==NULL)
{
RxdBuf=new BYTE[nLength+128];
}
else
{
delete RxdBuf;
RxdBuf=new BYTE[nLength+128];
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -