?? comport.cpp
字號:
// ComPort.cpp: implementation of the CComPort class.
// 芯藝 (c) copyright 2004
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ComPort.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CComPort::CComPort()
{
m_nCurrentCom=0;
memset(&m_ovRead,0,sizeof(OVERLAPPED));
memset(&m_ovWrite,0,sizeof(OVERLAPPED));
}
CComPort::~CComPort()
{
m_strLastError.Empty();
}
BOOL CComPort::Open(int portnum)
{
//如果要打開的端口號與當前打開的端口相同,返回
if(m_nCurrentCom==portnum)
return TRUE;
Close();//關閉當前端口
m_strLastError.Empty();
if(m_ovRead.hEvent)
ResetEvent(m_ovRead.hEvent);
else
m_ovRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(m_ovRead.hEvent==NULL)
return FALSE;
if(m_ovWrite.hEvent)
ResetEvent(m_ovWrite.hEvent);
else
m_ovWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(m_ovWrite.hEvent==NULL)
return FALSE;
COMMTIMEOUTS TimeOuts;
DCB dcb;
CString strCom;
strCom.Format("COM%d",portnum);
m_hCom=CreateFile(strCom //端口符號鏈接
,GENERIC_READ|GENERIC_WRITE //操作屬性:讀并寫
,0 //不共享
,NULL //無安全屬性
,OPEN_EXISTING //打開現存文件,若不存在則返回失敗
,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED //重疊操作
,NULL //無創建屬性
);
if(m_hCom==INVALID_HANDLE_VALUE)
return FALSE;
SetupComm(m_hCom,1024,1024);//設置輸入輸出緩沖區
/*
在串行接收時相鄰兩個字節到達時間間隔的超時毫秒數
在ReadFile函數中第一個字節到達后生效
0為不使用
*/
TimeOuts.ReadIntervalTimeout=MAXWORD;
/*
下四個域設置讀寫的總超時時間
總超時時間計算方法:
ReadTotalTimeoutConstant+(ReadTotalTimeoutMultiplier*讀字節數)
寫類似讀
*/
/*讀超時設為0,使ReadFile立即返回*/
TimeOuts.ReadTotalTimeoutConstant=0;
TimeOuts.ReadTotalTimeoutMultiplier=0;
TimeOuts.WriteTotalTimeoutConstant=2000;
TimeOuts.WriteTotalTimeoutMultiplier=50;
SetCommTimeouts(m_hCom, &TimeOuts);//設置超時
if(!GetCommState(m_hCom,&dcb))
{
Close();
return FALSE;
}
dcb.fBinary=TRUE;//二進制方式,WINDOWS API只支持此方式
dcb.BaudRate=9600;
dcb.ByteSize=8;
dcb.fParity=FALSE;//校驗禁止
SetCommState(m_hCom,&dcb);
m_nCurrentCom=portnum;
return TRUE;
}
void CComPort::Close()
{
if(m_nCurrentCom)
CloseHandle(m_hCom);
m_nCurrentCom=0;
}
//同步寫入操作
UINT CComPort::Write(UCHAR *buf, UINT len)
{
DWORD length=len;
COMSTAT ComStat;
DWORD dwErrorFlags;
ClearCommError(m_hCom,&dwErrorFlags,&ComStat);
if(WriteFile(m_hCom,buf,length,&length,&m_ovWrite)==0)
{
if(GetLastError()==ERROR_IO_PENDING)
{
GetOverlappedResult(m_hCom,&m_ovWrite,&length,TRUE);// 等待
}
else
length=0;
}
return length;
}
//異步讀取操作 反回:0:成功 1:超時 2:I/O錯誤 [3:用戶取消,pEvent[1]設置用戶取消事件時可用]
UINT CComPort::Read(UCHAR *buf, UINT len , DWORD timeout)
{
DWORD WaitResult;
HANDLE pEvent[2];
pEvent[0]=m_ovRead.hEvent;
DWORD length;
ClearCommError(m_hCom,&length,NULL);
length=0;
ResetEvent(m_ovRead.hEvent);
if(!ReadFile(m_hCom,buf,len,&length,&m_ovRead))
{
if(GetLastError()==ERROR_IO_PENDING) //重疊操作返回
{
//等待接收數據、取消操作和超時
WaitResult=WaitForMultipleObjects(1,pEvent,FALSE,timeout);
if(WaitResult==0)
{
GetOverlappedResult(m_hCom, &m_ovRead,&length, FALSE) ;
m_strLastError.Empty();
}
else if(WaitResult==WAIT_TIMEOUT)//超時
{
m_strLastError="\r\n通信超時";
return 1;
}
else if(WaitResult==WAIT_FAILED)
{
m_strLastError="\r\n當前端口不可用";
return 2;
}
}
else//I/O錯誤
{
m_strLastError="\r\n當前端口不可用";
return 2;
}
}
return 0;
}
void CComPort::GetError(CString &str)
{
str=m_strLastError;
m_strLastError.Empty();
}
void CComPort::ClearBuffer()
{
if(m_nCurrentCom>0)
PurgeComm(m_hCom,PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_RXABORT);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -