📄 asynccom.cpp
字号:
// ComModem.cpp: implementation of the CAsyncCom class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "AsyncCom.h"
#include <direct.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//MODEM拨号的状态
#define MODEM_CORRECT_EXECUTE 0 //
#define MODEM_INVIALID_ATCOM 1 //
#define MODEM_CONNECTED 2 //
#define MODEM_CARRIER 3 //
#define MODEM_NOCARRIER 4 //
#define MODEM_BUSY 5 //
#define MODEM_RING 6 //
#define MODEM_NODIALONE 7 //
#define MODEM_UNKNOW_RETURN 10 //
//#define EVENT_RECEIVE 1 // 收到数据
//#define EVENT_SEND 2 // 发送数据
//#define EVENT_ERROR 3 // 错误
DWORD WINAPI ThreadWatchComm(LPVOID pParm);
//DWORD WINAPI ThreadTest(LPVOID pParm);
/*
功 能:重叠操作处理线程
设计者:
时 间:2001-5
函数名:ThreadWatchComm(LPVOID pParm)
参 数: pParm:CAsyncCom的实例句柄
*/
DWORD WINAPI ThreadWatchComm(LPVOID pParm)
{
CAsyncCom * pCom = (CAsyncCom*)pParm;
DWORD dwTransfer,dwEvtMask;
// DWORD retrycount;
// DWORD errcode;
COMSTAT stat;
COMSTAT ComStat;
DWORD dwErrorFlags;
DWORD err;
if(!SetCommMask(pCom->hComDev,EV_RXCHAR|EV_TXEMPTY|EV_ERR|EV_RLSD)) //|EV_ERR
return FALSE;
while(!pCom->ThreadExit)
{
dwEvtMask = 0;
dwTransfer = 0;
if(!WaitCommEvent(pCom->hComDev,&dwEvtMask,&pCom->os))
{
err = GetLastError();
if(ERROR_IO_PENDING == err)
{
GetOverlappedResult(pCom->hComDev,&pCom->os,&dwTransfer,0);
}
else
{
ClearCommError(pCom->hComDev,&err,&stat);
Sleep(100);
continue;
}
}
if(!pCom->ProcEventFlags)
{
Sleep(50);
continue;
}
// if((dwEvtMask & EV_RXCHAR)==EV_RXCHAR)//收到字符
{
// Sleep(50);
if(ComStat.cbInQue > 0)
{
pCom->ProcessEvent(EV_RXCHAR,0);
}
ClearCommError(pCom->hComDev,&dwErrorFlags,&ComStat);
}
if((dwEvtMask & EV_TXEMPTY) == EV_TXEMPTY)//发送字符
pCom->ProcessEvent(EV_TXEMPTY,0);
if((dwEvtMask & EV_RLSD) == EV_RLSD)//DCD信号改变状态
pCom->ProcessEvent(EV_RLSD,0);
if((dwEvtMask & EV_ERR) == EV_ERR)//线路错误
{
err = GetLastError();
pCom->ProcessEvent(EV_ERR,err);
}
}
ExitThread(0);
return 0;
}
//##ModelId=3BDCCE3E004E
CAsyncCom::CAsyncCom()
{
m_reqthreadexitcount = 0;
ThreadExit = TRUE;
ConnMethod = CONNMETOD_COM;
IsOpen = FALSE;
ProcEventFlags = TRUE;
// postRecvEvent = NULL;
read_os.hEvent = NULL;
// postSendEvent = NULL;
write_os.hEvent = NULL;
os.hEvent = NULL;
hThreadWatchComm = NULL;
}
//##ModelId=3BDCCE3E0057
CAsyncCom::~CAsyncCom()
{
}
//##ModelId=3B2864BA0195
/*
功能:打开串口的操作
设计者:
*/
//##ModelId=3BDCCE3E004D
CAsyncCom::Open()
{
m_reqthreadexitcount = 0;
int comMask,comBuf,comState;
COMMTIMEOUTS CommTimeOuts;
DCB dcb;
hComDev = CreateFile(sComName,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,//
NULL);
if(hComDev == (HANDLE)-1)
{
OnError(GetLastError());
return 0;
}
IsOpen = TRUE;
DWORD dwTemp;
// if(BaudRate>0)
// dwTemp = 1000 / (BaudRate / 8);
// else
dwTemp = 0;
CommTimeOuts.ReadIntervalTimeout = 0xffffffff;
CommTimeOuts.ReadTotalTimeoutMultiplier = ((dwTemp > 0) ? dwTemp : 1);
CommTimeOuts.ReadTotalTimeoutConstant = 0;
if(BaudRate == 0)
CommTimeOuts.WriteTotalTimeoutMultiplier = 1;
else
CommTimeOuts.WriteTotalTimeoutMultiplier = 2*CBR_9600/BaudRate;//( npTTYInfo ) ;
CommTimeOuts.WriteTotalTimeoutConstant = 1000;//1000;
SetCommTimeouts( hComDev, &CommTimeOuts);
SetCommMask(hComDev, EV_RXCHAR);
PurgeComm( hComDev, PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
comMask = SetCommMask(hComDev,EV_RXFLAG);
comBuf = SetupComm(hComDev,4096,4096);
comState = GetCommState(hComDev,&dcb);
dcb.BaudRate = BaudRate;//CBR_19200
dcb.ByteSize = ByteSize;//8
switch(Parity)
{
case 0:
dcb.Parity = NOPARITY;//NOPARITY;
break;
case 1:
dcb.Parity = ODDPARITY;
break;
case 2:
dcb.Parity = EVENPARITY;
break;
}
switch(StopBits)
{
case 1:
dcb.StopBits = ONESTOPBIT;
break;
case 2:
dcb.StopBits = TWOSTOPBITS;
break;
default:
dcb.StopBits = 1;
break;
}
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb.fBinary = 1;
dcb.fParity = 1;
/* dcb.fErrorChar = 0;
dcb.ErrorChar = 0;
dcb.EvtChar = 0;
dcb.fOutxDsrFlow = 0;
dcb.fOutxDsrFlow = 0;
dcb.fInX = 0;
dcb.fOutX = 0;
dcb.XonChar = 17 ;
dcb.XoffChar = 19 ;
dcb.XonLim = 2048 ;
dcb.XoffLim = 512 ;
dcb.fDsrSensitivity = 0;
dcb.fTXContinueOnXoff = 0;//
dcb.fNull = 0;//
dcb.fAbortOnError = 0;//
*/
comState = SetCommState(hComDev,&dcb);
InitEvent();
InitThread();//启动线程控制重叠操作
return 1;
}
//##ModelId=3B2864BA0146
/*
功能:关闭串口的操作
设计者:
*/
//##ModelId=3BDCCE3E0011
CAsyncCom::Close()
{
ThreadExit = TRUE;
CloseEvent();
if(hComDev)
{
CloseHandle(hComDev);
hComDev = NULL;
IsOpen = FALSE;
}
CloseThread();
}
//##ModelId=3B2864BA01BD
/*
功能:初始化重叠操作
设计者:
*/
//##ModelId=3BDCCE3E0076
CAsyncCom::InitEvent()
{
memset(&read_os,0,sizeof(OVERLAPPED));
read_os.hEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
memset(&write_os,0,sizeof(OVERLAPPED));
write_os.hEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
memset(&os,0,sizeof(OVERLAPPED));
os.hEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
return 1;
}
//##ModelId=3BDCCE3E0075
CAsyncCom::InitThread()
{
ThreadExit = FALSE;
hThreadWatchComm = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadWatchComm,(LPVOID)this,0,&Thread_TimeOut_id);
return 1;
}
//##ModelId=3BDCCE3E0061
CAsyncCom::CloseEvent()
{
if(read_os.hEvent)
CloseHandle(read_os.hEvent);
if(write_os.hEvent)
CloseHandle(write_os.hEvent);
if(os.hEvent)
CloseHandle(os.hEvent);
read_os.hEvent = NULL;
write_os.hEvent = NULL;
os.hEvent = NULL;
}
//##ModelId=3BDCCE3E006B
CAsyncCom::CloseThread()
{
DWORD ExitCode = 1;
if(hThreadWatchComm)
{
ThreadExit = 1;
/* if(m_reqthreadexitcount == 3)
{
::TerminateThread(hThreadWatchComm,&ExitCode);
hThreadWatchComm = NULL;
return 1;
}
else
{
if(::WaitForSingleObject(hThreadWatchComm,100)==WAIT_TIMEOUT)
{
m_reqthreadexitcount ++;
return 0;
}
else
{
CloseHandle(hThreadWatchComm);
hThreadWatchComm = NULL;
return 1;
}
}
*/
if(::WaitForSingleObject(hThreadWatchComm,500)==WAIT_TIMEOUT)
{
::TerminateThread(hThreadWatchComm,ExitCode);
}
CloseHandle(hThreadWatchComm);
hThreadWatchComm = NULL;
return 1;
}
return 1;
}
//##ModelId=3BDCCE3D03E7
CAsyncCom::OnError(DWORD err)
{
DWORD err1;
COMSTAT stat;
ClearCommError(hComDev,&err1,&stat);
}
//##ModelId=3B2864BA0128
/*
功 能:数据发送函数,调用此函数发送数据缓冲区的数据
设计者:
时 间:2001-5
函数名:Write(BYTE *buff, DWORD bufflen,BOOL bOver)
参 数: BYTE *buff 发送数据缓冲区
DWORD bufflen 请求发送数据长度
BOOL bOver 是否重叠控制
返回值: 成功的发送数据长度
*/
//##ModelId=3BDCCE3D03DE
DWORD CAsyncCom::Write(BYTE *buff, DWORD bufflen,BOOL bOver)
{
DWORD lenreturn;
DWORD dwErrorFlags;
COMSTAT ComStat;
if(!IsOpen)
return 0;
PurgeComm(hComDev, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
BOOL fState = WriteFile(hComDev,buff,bufflen,&lenreturn,&write_os);
if(!fState)
{
if(GetLastError()==ERROR_IO_PENDING)
{
if(bOver)//bOver
{
while(!GetOverlappedResult(hComDev,&write_os,&lenreturn,TRUE))
{
if(GetLastError() == ERROR_IO_INCOMPLETE)
continue;
else
{
ClearCommError(hComDev,&dwErrorFlags,&ComStat);
break;
}
}
}
}
else
{
lenreturn = -1;
ClearCommError(hComDev,&dwErrorFlags,&ComStat);
}
}
// WriteFile_COMM(buff, bufflen,'s',TRUE);
return lenreturn;
}
//##ModelId=3B2864BA011D
/*
功 能:数据接收函数,调用此函数接收数据到缓冲区中
设计者:
时 间:2001-5
函数名:Read(BYTE *pBuff, DWORD NumRead)
参 数: BYTE *pBuff 接收数据缓冲区
DWORD NumRead 请求接收数据长度
返回值: 成功接收的数据长度
*/
//##ModelId=3BDCCE3D03DB
DWORD CAsyncCom::Read(BYTE *pBuff, DWORD NumRead)
{
DWORD numByte;
COMSTAT ComStat ;
DWORD dwErrorFlags;
// DWORD len;
BOOL fReadStat;
if(!IsOpen)
return 0;
if(NumRead<=0)
return 0;
if(!ClearCommError(hComDev, &dwErrorFlags, &ComStat))
return 0;
// len = NumRead;
fReadStat = ReadFile(hComDev,pBuff,NumRead,&numByte,&read_os);
if (!fReadStat)
{
if (GetLastError()==ERROR_IO_PENDING)
{
while(!GetOverlappedResult(hComDev,&read_os,&numByte,TRUE))
{
if(GetLastError() == ERROR_IO_INCOMPLETE)
continue;
}
}
else
{
numByte=0;
ClearCommError(hComDev,&dwErrorFlags,&ComStat);
}
}
// WriteFile_COMM(pBuff, numByte,'r',TRUE);
return numByte;
}
//##ModelId=3BDCCE3D03D1
CAsyncCom::ProcessEvent(DWORD Event,DWORD sign)
{
switch(Event)
{
case EV_RXCHAR:
ProcessReceiveData(sign);
break;
// case EV_TXEMPTY:
// OnSend();
break;
case EV_ERR:
OnError(sign);
break;
}
}
//##ModelId=3BDCCE3D03C7
void CAsyncCom::ProcessReceiveData(DWORD sign)
{
OnReceive();
}
//##ModelId=3B2864BA00D6
/*
功 能:清除缓冲区的错误
设计者:
时 间:2001-5
函数名:ClearBuffError()
参 数: 无
返回值: 无
*/
//##ModelId=3BDCCE3D0395
CAsyncCom::ClearBuffError()
{
DWORD len;
COMSTAT comstat;
PurgeComm(hComDev,PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
ClearCommError(hComDev,&len,&comstat);
}
void CAsyncCom::WriteFile_COMM(BYTE *buf, int Len,BYTE m_WR,BOOL Flags)
{
// if(!Flags)
return;
CString str,temp,stemp;
CString sfile,sDir;
CFile file;
BOOL bo;
sfile.Format(".\\log\\COMM_CODE.txt");
_mkdir(".\\log");
bo = file.Open(sfile.GetBuffer(sfile.GetLength()),CFile::modeWrite);
if(!bo)
{
bo = file.Open(sfile.GetBuffer(sfile.GetLength()),CFile::modeWrite|CFile::modeCreate);
if(!bo)
{
bo = file.Open(sfile.GetBuffer(sfile.GetLength()),CFile::modeWrite|CFile::modeCreate);
if(!bo)
{
return ;
}
}
}
str ="";
for(int i = 0;i<Len;i++)
{
temp.Format("%02x ",buf[i]);
str = str + temp;
}
long len1 = file.GetLength();
file.Seek(len1,CFile::begin);
str.MakeUpper();
stemp.Format("[ %s ] %s\r\n",m_WR=='s'?"Send ":"Receive",str);
file.Write(stemp.GetBuffer(stemp.GetLength()),stemp.GetLength());
file.Close();
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -