📄 serialport.cpp
字号:
// set the timeout values
m_CommTimeouts.ReadIntervalTimeout = 1000;
m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000;
m_CommTimeouts.ReadTotalTimeoutConstant = 1000;
m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;
m_CommTimeouts.WriteTotalTimeoutConstant = 1000;
// configure
if (SetCommTimeouts(m_hComm, &m_CommTimeouts))
{
if (SetCommMask(m_hComm, dwCommEvents))
{
if (GetCommState(m_hComm, &m_dcb))
{
m_dcb.fRtsControl = RTS_CONTROL_ENABLE; // set RTS bit high!
if (BuildCommDCB(szBaud, &m_dcb))
{
if (SetCommState(m_hComm, &m_dcb))
; // normal operation... continue
else
ProcessErrorMessage("SetCommState()");
}
else
ProcessErrorMessage("BuildCommDCB()");
}
else
ProcessErrorMessage("GetCommState()");
}
else
ProcessErrorMessage("SetCommMask()");
}
else
ProcessErrorMessage("SetCommTimeouts()");
delete [] szPort;
delete [] szBaud;
// flush the port
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
// release critical section
LeaveCriticalSection(&m_csCommunicationSync);
TRACE("Initialisation for communicationport %d completed.\nUse Startmonitor to communicate.\n", portnr);
return TRUE;
}
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;
}
void CSerialPort::ReceiveChar(CSerialPort * port,COMSTAT comstat)
{
BOOL bRead = TRUE;
BOOL bResult = TRUE;
DWORD dwError = 0;
DWORD BytesRead = 0;
int counter;
counter = -1;
unsigned char RxBuff;
// MessageBox(NULL, "RECEIVE CHAR", "Application Error", MB_ICONSTOP);
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
// counter ++;
// Rx_Buffer[counter] = RxBuffer;
// ::PostMessage(NULL,WM_COMM_RXCHAR, RxBuff, (int) port->m_nPortNr);
// ::SendMessage((port->m_pOwner)->m_hWnd, WM_COMM_RXCHAR, (WPARAM) RxBuff, (LPARAM) port->m_nPortNr);
// ::SendMessage(WM_COMM_RXCHAR, (WPARAM) RxBuff, (LPARAM) port->m_nPortNr);
// LONG ss;
// BOOL m_1;
// m_1 = IsNT();
// Sleep(10);
OnCommunication( RxBuff, (int)port->m_nPortNr);
} // end forever loop
}
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 m_nWriteSize
PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
//strlen((char*)port->m_szWriteBuffer)
bResult = WriteFile(port->m_hComm, // Handle to COMM Port
port->m_szWriteBuffer, // Pointer to message buffer in calling finction
port->m_nWriteSize, // Length of message to send
&BytesSent, // Where to store the number of bytes sent
&port->m_ov); // Overlapped structure
// deal with any error codes
StartFlag = TRUE; //
//
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));
}
}
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);
}
void CSerialPort::WriteToPort(char* string,int n)
{
assert(m_hComm != 0);
memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
// memset(m_szWriteBuffer, 0, n);
// strncpy(m_szWriteBuffer, string, n);
memcpy(m_szWriteBuffer, string, n);
m_nWriteSize=n;
CString strTemp, strTemp1;
for (int i=0;i<8;i++)
{
strTemp.Format("%02X", m_szWriteBuffer[i]);
strTemp1 = strTemp1 + strTemp + " ";
}
// AfxMessageBox("发送数据:" + strTemp1);
// set event for write
SetEvent(m_hWriteEvent);
}
BOOL CSerialPort::StartMonitoring()
{
// start comm watching
if (!(m_Thread = AfxBeginThread(CommThread, this)))
return FALSE;
TRACE("Thread started\n");
return TRUE;
}
BOOL CSerialPort::RestartMonitoring()
{/*程序没有用上*/
// Restart the comm thread
TRACE("Thread resumed\n");
m_Thread->ResumeThread();
return TRUE;
}
BOOL CSerialPort::StopMonitoring()
{
delete [] m_szWriteBuffer;
m_szWriteBuffer = NULL;
m_stopflag = 1;
SetEvent(m_hShutdownEvent);
// Sleep(100);
// CloseHandle(m_hComm);
// MessageBox(NULL, "Handle", "Close", MB_ICONSTOP);
// Suspend the comm thread
// TRACE("Thread suspended\n");
// m_Thread->SuspendThread();
// GetExitCodeThread(m_Thread,&m_ExitCode);//得到推退出码
// TerminateThread(m_Thread,0);
// CloseHandle(m_Thread);
return TRUE;
}
LONG CSerialPort::OnCommunication(unsigned char ch,int port)
{
CString temp1,temp2,temp3;
CString temp4;
CString temp;
char m_EndChar;
// int m_ProStatus; //进度条显示
//m_ProStatus = (int)m_AddCounter/()
if (port <= 0 || port > 255)
return -1;
if(char(ch) == 0x1b) //无响应,找下一地址
{
m_Result = m_Respond;
if(StartFlag)
{
if(port >=1 && port <=255)
{
SetEvent(hEventResult[1]);
}
}
m_Respond = ""; //准备重新接收
return 0;
}
else
{
// CString Respond;
// m_EndChar = (unsigned char)ch;
// Respond.Format("%c",m_EndChar);
result[resultlength++] = ch;
// m_Respond = m_Respond + Respond;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -