📄 portctl.cpp
字号:
// SerialCtl.cpp: implementation of the SerialCtl class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "PortCtl.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
SerialCtl::SerialCtl()
{
hCom = NULL;
hCommWatchThread = NULL;
memset(Data, 0, MAXNUM);
DelayRead = 1;
CircleTimeSpan = 1;
OPEN_FLAG = false;
m_lParam = 0;
}
void SerialCtl::SetSerial(CString Com, long Baud, int Data, int End, CString Parity)
{
strcpy(Serial.COM, Com);
Serial.BAUD = Baud;
Serial.DATA = Data;
Serial.END = End-1;
if ( Parity == "NONE" || Parity == "none" )
Serial.PARITY = NOPARITY;
else if ( Parity == "EVEN" || Parity == "even" )
Serial.PARITY = EVENPARITY;
else if ( Parity == "ODD" || Parity == "odd" )
Serial.PARITY = ODDPARITY;
else
Serial.PARITY = NOPARITY;
}
void SerialCtl::CloseSerial()
{
if ( m_OverWrite.hEvent != NULL )
CloseHandle(m_OverWrite.hEvent);
if ( m_OverRead.hEvent != NULL )
CloseHandle(m_OverRead.hEvent);
if ( hCommWatchThread != NULL )
{
TerminateThread(hCommWatchThread, 1);
hCommWatchThread = NULL;
}
if ( hCom )
{
CloseHandle(hCom);
hCom = NULL;
}
OPEN_FLAG = false;
}
void SerialCtl::OpenSerial()
{
DWORD ErrorFlag;
memset(&m_OverWrite, 0, sizeof(OVERLAPPED));
m_OverWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
memset(&m_OverRead, 0, sizeof(OVERLAPPED));
m_OverRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
hCom = CreateFile(Serial.COM,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL
);
if ( hCom == INVALID_HANDLE_VALUE )
{
// AfxMessageBox("打开错误,看检查串口是否已经打开。");
OPEN_FLAG = false;
return;
}
SetCommMask(hCom, EV_RXCHAR | EV_TXEMPTY);
PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
SetupComm(hCom, INBUF, OUTBUF);
GetCommState(hCom, &dcb);
// dcb.fDtrControl = 0;
// dcb.fRtsControl = 0;
// dcb.fTXContinueOnXoff = 0;
dcb.StopBits = Serial.END;
dcb.BaudRate = Serial.BAUD;
dcb.ByteSize = Serial.DATA;
dcb.Parity = Serial.PARITY;
if ( !SetCommState(hCom, &dcb) )
{
AfxMessageBox("串口设置错误!");
if ( hCom )
{
CloseHandle(hCom);
hCom = NULL;
}
OPEN_FLAG = false;
return;
}
ClearCommError(hCom, &ErrorFlag, &ComStat);
/* memset(&m_OverWrite, 0, sizeof(OVERLAPPED));
m_OverWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
memset(&m_OverRead, 0, sizeof(OVERLAPPED));
m_OverRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
*/
OPEN_FLAG = true;
}
void SerialCtl::ListenSerial(long delayRead, long circleTimeSpan)
{
DelayRead = delayRead;
CircleTimeSpan = circleTimeSpan;
hCommWatchThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)hCommWatchPro,
(LPVOID)this,
0,
(LPDWORD)&hCommWatchThread
);
if ( hCommWatchThread == NULL )
{
AfxMessageBox("串口线程建立失败!");
return;
}
}
void SerialCtl::StopListenSerial()
{
if ( hCommWatchThread != NULL )
{
TerminateThread(hCommWatchThread, 1);
hCommWatchThread = NULL;
}
}
BOOL SerialCtl::WriteSerial(const BYTE * SendData, const DWORD SendLen)
{
BOOL WriteFlag2;
BOOL bError = TRUE;
DWORD ErrorFlag;
DWORD ecode1, ecode2;
DWORD Len = SendLen;
// while ( !HasOverlappedIoCompleted(&m_OverWrite) );
// while ( ComStat.cbOutQue != 0 ){}
ClearCommError(hCom, &ErrorFlag, &ComStat);
WriteFlag2 = WriteFile(hCom, SendData, SendLen, 0, &m_OverWrite);
if ( !WriteFlag2 )
{
ecode1 = GetLastError();
if ( ecode1 == ERROR_IO_PENDING )
{
DWORD l;
BOOL f = FALSE;
while ( !GetOverlappedResult(hCom, &m_OverWrite, &l, TRUE ) )
{
ecode2 = GetLastError();
/* if ( ecode2 == ERROR_OPERATION_ABORTED )
{
TRACE("995\n");
PurgeComm(hCom, PURGE_TXABORT|PURGE_TXCLEAR);
f = TRUE;
break;
}
*/ if ( ecode2 == ERROR_IO_INCOMPLETE )
{
f = FALSE;
continue;
}
else
{
PurgeComm(hCom, PURGE_TXABORT|PURGE_TXCLEAR);
f = TRUE;
break;
}
// Sleep(1);
}
if ( f == FALSE )
{
bError = FALSE;
}
else
{
bError = TRUE;
}
}
}
else
{
bError = FALSE;
}
// PurgeComm(hCom, PURGE_TXABORT|PURGE_TXCLEAR);
return TRUE;
}
/*
void SerialCtl::ReadSerial(BYTE * resData, long * length)
{
DWORD ErrorFlag;
DWORD dwErrorFlags;
BOOL ReadFlag = FALSE;
int len = 0;
memset(Data, 0, MAXNUM);
// ClearCommError(hCom, &ErrorFlag, &ComStat);
// if ( ReadNum > 0 )
// len = ReadNum;
// else
{
if ( ComStat.cbInQue )
len = ComStat.cbInQue;
else
{
resData = NULL;
length = 0;
return;
}
// len = READBUFLEN;
}
* length = len;
ReadFlag = ReadFile(hCom, Data, len, 0, &m_OverRead);
// TRACE("%ld\r\n",len);
if ( !ReadFlag )
{
// PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
return;
}
memcpy(resData, Data, len);
// ClearCommError(hCom, &dwErrorFlags, &ComStat);
// PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
// ComStat.cbInQue = 0;
// return &Data[0];
}
*/
int SerialCtl::ReadSerial2(BYTE * resData, int length)
{
DWORD ErrorFlag;
ClearCommError(hCom, &ErrorFlag, &ComStat);
if ( ComStat.cbInQue )
{
if ( ComStat.cbInQue >= length )
{
ReadFile(hCom, resData, length, 0, &m_OverRead);
return length;
}
else
{
int k=ComStat.cbInQue;
ReadFile(hCom, resData, k, 0, &m_OverRead);
return k;
}
}
else
{
resData = NULL;
return 0;
}
}
void SerialCtl::ReadSerial(BYTE * resData, int * length)
{
DWORD dwBytesRead;
DWORD dwError;
DWORD ErrorFlag;
BOOL ReadFlag = FALSE;
int len = 0;
memset(Data, 0, MAXNUM);
ClearCommError(hCom, &ErrorFlag, &ComStat);
if ( ComStat.cbInQue )
len = ComStat.cbInQue;
else
{
resData = NULL;
length = 0;
return;
}
* length = len;
ReadFlag = ReadFile(hCom, Data, len, 0, &m_OverRead);
if ( !ReadFlag )
{
if ( GetLastError() == ERROR_IO_PENDING )
{
while ( !GetOverlappedResult(hCom, &m_OverRead, &dwBytesRead, TRUE ))
{
dwError = GetLastError();
if ( dwError == ERROR_IO_INCOMPLETE )
continue;
}
}
return;
}
memcpy(resData, Data, len);
}
void SerialCtl::ClearSerialBuf()
{
// DWORD dwErrorFlags;
// ClearCommError(hCom, &dwErrorFlags, &ComStat);
PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
ComStat.cbInQue = 0;
}
bool SerialCtl::IsSerialOpen()
{
return OPEN_FLAG;
}
CString SerialCtl::GetVersion()
{
return "当前串口通讯模块版本:2.0 2004-2005 RT-Hou.Ke";
}
float SerialCtl::GetVer()
{
return 2.0f;
}
BOOL SerialCtl::isCanSend()
{
if ( ComStat.cbOutQue )
return TRUE;
else
return FALSE;
}
/*
UINT hCommWatchPro(LPVOID pParam)
{
SerialCtl * wnd = (SerialCtl *)pParam;
OVERLAPPED os;
DWORD dwMask = 0,
dwTrans;
DWORD dwErrorFlags;
DCB dcb;
memset(&os, 0, sizeof(OVERLAPPED));
os.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if ( os.hEvent == NULL )
{
AfxMessageBox("辅助线程事件建立错误!");
return -1;
}
while ( wnd->hCom != INVALID_HANDLE_VALUE )
{
//GetCommState(wnd->hCom, &dcb);
//if ( dcb.fAbortOnError )
ClearCommError(wnd->hCom, &dwErrorFlags, &wnd->ComStat);
if ( wnd->ComStat.cbInQue )
{
// ClearCommError(wnd->hCom, &dwErrorFlags, &wnd->ComStat);
if ( !WaitCommEvent(wnd->hCom, &dwMask, &os) )
{
if ( GetLastError() == ERROR_IO_PENDING )
GetOverlappedResult(wnd->hCom, &os, &dwTrans, TRUE);
//else
//{
// AfxMessageBox("GetLastError() != ERROR_IO_PENDING");
// CloseHandle(os.hEvent);
// return -1;
// }/
}
Sleep(1000);//wnd->DelayRead);
AfxGetMainWnd()->PostMessage(WM_SERIALGET, 0, wnd->m_lParam);
// ClearCommError(wnd->hCom, &dwErrorFlags, &wnd->ComStat);
// static long i=0;
// TRACE("..................%d...................\r\n", ++i);
// if (i>10000) i = 0;
}
Sleep(wnd->CircleTimeSpan);
}
CloseHandle(os.hEvent);
return 0;
}
*/
UINT hCommWatchPro(LPVOID pParam)
{
SerialCtl * wnd = (SerialCtl *)pParam;
OVERLAPPED os;
DWORD dwMask = 0;
DWORD dwErrorFlags;
DWORD dwEvtMask = 0;
memset(&os, 0, sizeof(OVERLAPPED));
os.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if ( os.hEvent == NULL )
{
AfxMessageBox("辅助线程事件建立错误!");
return -1;
}
SetCommMask(wnd->hCom, EV_RXCHAR|EV_TXEMPTY); // 串口事件监视
while ( wnd->hCom != INVALID_HANDLE_VALUE )
{
WaitCommEvent(wnd->hCom, &dwEvtMask, &os); // 等待串口通信事件的发生
if ( (dwEvtMask & EV_RXCHAR) == EV_RXCHAR ) // 缓冲区有数据
{
ClearCommError(wnd->hCom, &dwErrorFlags, &wnd->ComStat);
if ( wnd->ComStat.cbInQue ) // 缓冲区数据个数
{
Sleep(wnd->DelayRead);
AfxGetMainWnd()->PostMessage(WM_SERIALGET, 0, wnd->m_lParam);
}
}
Sleep(wnd->CircleTimeSpan);
}
CloseHandle(os.hEvent);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -