13,825
社区成员
发帖
与我相关
我的任务
分享
#ifndef __COM99
#define __COM99
#define WM_COMDATA WM_APP+201
#define WM_COMERR WM_APP+202
template <class T1>
union TProcHelper
{
DWORD __stdcall (*ThdProc)(void*);
DWORD __stdcall (T1::*ClsProc)(void);
};
//***********************************
class TxCom
{
private:
bool tRun;
HANDLE hThd;
HANDLE hCom;
HANDLE hWin;
char mComName[16];
char mComState[16];
DWORD mdwSize;
OVERLAPPED xOverlapped;
OVERLAPPED wOverlapped;
OVERLAPPED rOverlapped;
//***********************************
protected:
virtual void OnRecv()
{
COMSTAT ComStat;
DWORD dwError;
ClearCommError(hCom, &dwError, &ComStat);
if(ComStat.cbInQue>=mdwSize && IsWindow(hWin))
SendMessage(hWin,WM_COMDATA,(UINT)this,ComStat.cbInQue);
}
//***********************************
virtual void OnError()
{
if(IsWindow(hWin))
PostMessage(hWin,WM_COMERR,(UINT)this,NULL);
}
//***********************************
DWORD __stdcall ThreadFunc(void)
{
tRun =true;
SetCommMask(hCom,EV_RXCHAR|EV_ERR);
while(tRun)
{
DWORD dwMask =0;
DWORD dwLength =0;
if (!WaitCommEvent(hCom,&dwMask,&xOverlapped))
{
if(::GetLastError() == ERROR_IO_PENDING)
::GetOverlappedResult(hCom, &xOverlapped, &dwLength, TRUE);
else
continue;
}
if((dwMask & EV_RXCHAR)==EV_RXCHAR)
OnRecv();
else if((dwMask & EV_ERR)==EV_ERR)
OnError();
}
return 0;
}
//***********************************
public:
TxCom()
{
tRun=false;
hThd=NULL;
hWin=NULL;
hCom=INVALID_HANDLE_VALUE;
memset(mComName,0,16);
memset(mComState,0,16);
mdwSize=0;
memset(&xOverlapped,0,sizeof(OVERLAPPED));
memset(&wOverlapped,0,sizeof(OVERLAPPED));
memset(&rOverlapped,0,sizeof(OVERLAPPED));
xOverlapped.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
wOverlapped.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
rOverlapped.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
::InitializeCriticalSection(&_Mutex);
}
//***********************************
~TxCom()
{
Close();
CloseHandle(xOverlapped.hEvent);
CloseHandle(wOverlapped.hEvent);
CloseHandle(rOverlapped.hEvent);
::DeleteCriticalSection(&_Mutex);
}
//***********************************//
const HANDLE GetComHandle(void)
{
return hCom;
}
//***********************************
const PCHAR GetComName(void)
{
return mComName;
}
//***********************************
void SetParantWnd(HWND hWnd)
{
hWin = hWnd;
}
//***********************************
void SetReadSize(DWORD dwSize) //设置读数据空间
{
mdwSize = dwSize;
}
//***********************************
void ClearInBuffer() //清楚接收缓冲区
{
::PurgeComm(hCom, PURGE_RXABORT | PURGE_RXCLEAR );
}
//***********************************
void ClearOutBuffer() //清楚发送缓冲区
{
::PurgeComm(hCom, PURGE_TXABORT | PURGE_TXCLEAR );
}
//***********************************
bool IsOpen(void) //判断端口是否打开
{
return hCom != INVALID_HANDLE_VALUE;
}
//***********************************
bool Open(PCHAR strCom,PCHAR strState)//打开指定端口
{
if(IsOpen()) return false;
hCom=CreateFile(strCom,GENERIC_READ|GENERIC_WRITE,
0,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL);
if(!IsOpen()) return false;
strcpy(mComName,strCom);
strcpy(mComState,strState);
SetupComm(hCom,2048,1024);
COMMTIMEOUTS tmover;
tmover.ReadIntervalTimeout = MAXWORD;
tmover.ReadTotalTimeoutMultiplier = 0;
tmover.ReadTotalTimeoutConstant = 0;
tmover.WriteTotalTimeoutMultiplier = 200;
tmover.WriteTotalTimeoutConstant = 2000;
SetCommTimeouts(hCom,&tmover);
DCB dcb;
dcb.DCBlength=sizeof(DCB);
BuildCommDCB(strState,&dcb);
SetCommState(hCom,&dcb);
PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
TProcHelper<TxCom> pHelper;
pHelper.ClsProc=&TxCom::ThreadFunc;
hThd=CreateThread(NULL, 0,pHelper.ThdProc, this, 0, NULL);
return true;
}
//***********************************
bool Close() //关闭指定端口
{
if(IsOpen())
{
tRun=false;
SetCommMask(hCom, 0);
SetEvent(xOverlapped.hEvent);
if(::WaitForSingleObject(hThd, 500) != WAIT_OBJECT_0)
TerminateThread(hThd, 0);
else
CloseHandle(hThd);
hThd=NULL;
ResetEvent(xOverlapped.hEvent);
CloseHandle(hCom);
hCom=INVALID_HANDLE_VALUE;
memset(mComName,0,16);
return true;
}
return false;
}
//---------------------------------------------------------------------------
ULONG Read(char *strbuf,ULONG ilen) //接收数据
{
if(!IsOpen()) return 0;
COMSTAT ComStat;
DWORD dwError;
if(::ClearCommError(hCom, &dwError, &ComStat) && dwError > 0)
{
::PurgeComm(hCom, PURGE_RXABORT | PURGE_RXCLEAR);
return 0;
}
if(ilen>ComStat.cbInQue) ilen =ComStat.cbInQue;
DWORD rtlen=0;
if(!::ReadFile(hCom,strbuf,ilen,&rtlen,&rOverlapped))
{
if(::GetLastError() == ERROR_IO_PENDING)
::GetOverlappedResult(hCom, &rOverlapped, &rtlen, TRUE);
else
::ClearCommError(hCom,&dwError,&ComStat);
}
return rtlen;
}
//---------------------------------------------------------------------------
ULONG Write(char *strbuf,ULONG ilen) //发送数据
{
if(!IsOpen()) return 0;
COMSTAT ComStat;
DWORD dwError;
if(::ClearCommError(hCom, &dwError, NULL) && dwError > 0)
::PurgeComm(hCom, PURGE_TXABORT | PURGE_TXCLEAR);
DWORD rtlen=0;
if (!::WriteFile(hCom,strbuf,ilen,&rtlen,&wOverlapped))
{
if(::GetLastError() == ERROR_IO_PENDING)
::GetOverlappedResult(hCom, &wOverlapped, &rtlen, TRUE);
else
::ClearCommError(hCom,&dwError,&ComStat);
}
return rtlen;
}
};
#endif
//pcomm.dll
comState = sio_open(comPort);
if (comState != SIO_OK )
{
ShowMessage("串口 1 打开失败") ;
return false ;
}
else
{
comState = sio_ioctl(comPort, B9600 , P_NONE | BIT_8 | STOP_1) ;
if (comState != SIO_OK)
{
ShowMessage("串口 1 初始化失败") ;
return false ;
}
}
sio_write(comPort, "@00R", 4);
Sleep(300) ;
sio_read(comPort, buf, 70);