📄 serial.cpp
字号:
// Serial.cpp: implementation of the CSerial class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Serial.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSerial::CSerial()
{
m_hCom = 0;
memset(&m_writeov,0,sizeof(OVERLAPPED));
memset(&m_readov,0, sizeof(OVERLAPPED));
memset(&m_waitov,0,sizeof(OVERLAPPED));
memset(&m_comstat,0,sizeof(COMSTAT));
memset(&m_commtimeouts,0,sizeof(COMMTIMEOUTS));
memset(&dcb,0,sizeof(DCB));
}
CSerial::~CSerial()
{
Close();
}
BOOL CSerial::Open(LPCSTR lpszPortNum , DWORD dwBaudRate, BYTE byParity, BYTE byStopBits, BYTE byByteSize)
{
BOOL bSuccess=TRUE;
m_readov.hEvent = CreateEvent(NULL , TRUE , FALSE , TOKENREADNAME);//TRUE--设置自动重置信号事件
if(m_readov.hEvent==INVALID_HANDLE_VALUE)
return FALSE;
m_writeov.hEvent = CreateEvent(NULL , TRUE , FALSE , TOKENWRITENAME);
if(m_writeov.hEvent==INVALID_HANDLE_VALUE)
return FALSE;
m_waitov.hEvent = CreateEvent(NULL , FALSE , FALSE , TOKENWAITNAME);//FALSE- -设置自动重置信号事件
if(m_waitov.hEvent==INVALID_HANDLE_VALUE)
return FALSE;
m_hCom = CreateFile(lpszPortNum ,
GENERIC_READ|GENERIC_WRITE ,
0 ,
NULL ,
OPEN_EXISTING ,
FILE_FLAG_OVERLAPPED ,
NULL);
if(m_hCom == INVALID_HANDLE_VALUE)
{
CSerial::Close();
return FALSE;
}
//Omit the call to SetupComm to use the default queue sizes.Get the current configuration.
bSuccess = GetCommState(m_hCom , &dcb);
if(!bSuccess)
{
CSerial::Close();
return FALSE;
}
//Fill in the DCB: baud=9600, 8 data bits, no parity, 1 stop bit are default parameters
dcb.DCBlength = sizeof(DCB);
dcb.BaudRate = dwBaudRate;
dcb.ByteSize = byByteSize;
dcb.Parity = byParity;
dcb.StopBits = byStopBits;
bSuccess = SetCommState(m_hCom , &dcb);
if(!bSuccess)
{
CSerial::Close();
return FALSE;
}
m_commtimeouts.ReadIntervalTimeout=MAXDWORD;
m_commtimeouts.ReadTotalTimeoutConstant=0;
m_commtimeouts.ReadTotalTimeoutMultiplier=0;
m_commtimeouts.WriteTotalTimeoutConstant=3;
m_commtimeouts.WriteTotalTimeoutMultiplier=1;
bSuccess = SetCommTimeouts(m_hCom, &m_commtimeouts);
if(!bSuccess)
{
CSerial::Close();
return FALSE;
}
bSuccess = SetupComm(m_hCom, 1500, 1500);
if(!bSuccess)
{
CSerial::Close();
return FALSE;
}
bSuccess = PurgeComm(m_hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
//设置串口监听事件
bSuccess=SetCommMask(m_hCom ,EV_RXCHAR);
if(!bSuccess)
{
CloseHandle(m_hCom);
return FALSE;
}
DWORD dwErrorFlags=0;
bSuccess = ClearCommError(m_hCom, &dwErrorFlags, &m_comstat);
if(!bSuccess)
{
CSerial::Close();
return FALSE;
}
return TRUE;
}
void CSerial::Close()
{
if(m_readov.hEvent!=INVALID_HANDLE_VALUE&&m_readov.hEvent!=0)
{
CloseHandle(m_readov.hEvent);
m_readov.hEvent=0;
}
if(m_writeov.hEvent!=INVALID_HANDLE_VALUE&&m_writeov.hEvent!=0)
{
CloseHandle(m_writeov.hEvent);
m_writeov.hEvent=0;
}
if(m_waitov.hEvent!=INVALID_HANDLE_VALUE&&m_waitov.hEvent!=0)
{
CloseHandle(m_waitov.hEvent);
m_waitov.hEvent=0;
}
if(m_hCom!=INVALID_HANDLE_VALUE&&m_hCom!=0)
{
CloseHandle(m_hCom);
m_hCom=0;
}
}
/*
DWORD CSerial::WriteData(const UCHAR* pData , DWORD nLen ,const char* cShow)
{
if(nLen<1)
return 0;
DWORD write=0;
TRACE("\nWrite^%s^m_hCom:%x^nLen:%d",cShow,m_hCom,nLen);
if(!WriteFile(m_hCom, pData, nLen, &write, &m_writeov))
{
if(GetLastError()==ERROR_IO_PENDING)
{
if(!GetOverlappedResult(m_hCom, &m_writeov, &write, FALSE))
{
if(GetLastError()==ERROR_IO_INCOMPLETE)
{
WRITEWAIT:
switch(WaitForSingleObject(m_writeov.hEvent,nLen*1))
{
case WAIT_OBJECT_0:
TRACE("\nWRITE WAIT_OBJECT_0^write:%d",write);
break;
case WAIT_TIMEOUT:
TRACE("\nWRITE WAIT_TIMEOUT^write:%d",write);
goto WRITEWAIT;
//CancelIo(m_hCom);//???是否将读写缓冲区清空???
break;
default:
TRACE("\nWRITE default^write:%d",write);
break;
}
}
}
}
}
ResetEvent(m_writeov.hEvent);
TRACE("\nWRITEEND^write:%d",write);
return write;
}
*/
BOOL CSerial::WaitData(DWORD& mask, const char *cShow)
{
// TRACE("\nm_waitov.hEvent:%x",m_waitov.hEvent);
// TRACE("\nWAIT^m_hCom:%x",m_hCom);
if(!WaitCommEvent(m_hCom , &mask , &m_waitov))
{
if(GetLastError()==ERROR_IO_PENDING)
{
//此处必须设置等待时间为无限长,才能阻塞串口
switch(WaitForSingleObject(m_waitov.hEvent,1000))
// switch(WaitForSingleObject(m_waitov.hEvent,INFINITE))
{
case WAIT_OBJECT_0:
// TRACE("\nWAIT^WAIT_OBJECT_0");
break;
case WAIT_TIMEOUT:
ClearError();
//CancelIo(m_hCom);
// TRACE("\nWAIT^WAIT_TIMEOUT");
break;
default:
// TRACE("\nWAIT^default");
break;
}
}
}
return true;
}
DWORD CSerial::WriteData(const UCHAR* pData , DWORD nLen, const char* cShow)
{
if(nLen<1)
return 0;
DWORD write=0;
TRACE("\nWRITEBEGIN^nLen:%d",nLen);
//TRACE("\nWrite^%s^m_hCom:%x^nLen:%d",cShow,m_hCom,nLen);
if(!WriteFile(m_hCom, pData, nLen, &write, &m_writeov))
{
if(GetLastError() == ERROR_IO_PENDING)
{
GetOverlappedResult(m_hCom, &m_writeov, &write, TRUE);
}//end last error == io pending
} //end readfile
ResetEvent(m_writeov.hEvent);
TRACE("\nWRITEEND^write:%d",write);
return write;
}
DWORD CSerial::ReadData(UCHAR* pData, DWORD nLen,const char* cShow)
{
if(nLen<1)
return 0;
DWORD read=0;
//TRACE("\nRead^%s^m_hCom:%x^nLen:%d",cShow,m_hCom,nLen);
if(!ReadFile(m_hCom, pData, nLen, &read, &m_readov))
{
if(GetLastError()==ERROR_IO_PENDING)
{
if(!GetOverlappedResult(m_hCom, &m_readov, &read, FALSE))
{
if(GetLastError()==ERROR_IO_INCOMPLETE)
{
READWAIT:
switch(WaitForSingleObject(m_readov.hEvent,nLen*1))
{
case WAIT_OBJECT_0:
// TRACE("\nREAD WAIT_OBJECT_0^read:%d",read);
break;
case WAIT_TIMEOUT:
// TRACE("\nREAD WAIT_TIMEOUT^read:%d",read);
//CancelIo(m_hCom);//???是否将读写缓冲区清空???
goto READWAIT;
break;
default:
// TRACE("\nREAD default^read:%d",read);
break;
}
}
}
}
}
ResetEvent(m_readov.hEvent);
// TRACE("\nREADEND^%s^read:%d",cShow,read);
return read;
}
/*DWORD CSerial::ReadData(UCHAR* pData, DWORD nLen)
{
if(nLen<1)
return 0;
DWORD read=0;
if(!ReadFile(m_hCom, pData, nLen, &read, &m_readov))
{
if(GetLastError()==ERROR_IO_PENDING)
{
GetOverlappedResult(m_hCom, &m_readov, &read, FALSE);
}
}
ResetEvent(m_readov.hEvent);
return read;
}
*/
BOOL CSerial::ClearError(const char* cShow)
{
DWORD dwErrorFlags=0;
BOOL bSuccess=ClearCommError(m_hCom, &dwErrorFlags, &m_comstat);
// TRACE("\n%s^IN:%d^OUT:%d^bSuccess:%d",cShow,m_comstat.cbInQue,m_comstat.cbOutQue,bSuccess);
return bSuccess;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -