#include "stdafx.h"
#include "SerialPort.h"
CCom::CCom()
{
m_hCom = NULL;
Cnter = 0;
memset(&m_OverlappedWrite, 0, sizeof(OVERLAPPED));
memset(&m_OverlappedRead, 0, sizeof(OVERLAPPED));
}
CCom::~CCom()
{
}
BOOL CCom::SetComPar(DWORD BaudRate, char WordLength, char StopBits, char Parity)
{
if(!m_hCom)
return FALSE;
DCB dcb;
dcb.DCBlength = sizeof(DCB);
if(!GetCommState(m_hCom, &dcb))
return FALSE;
dcb.BaudRate = BaudRate;
dcb.ByteSize = WordLength;
dcb.Parity = Parity;
BYTE stopb = 0;
if(StopBits == 1)
stopb = 0;
else if (StopBits == 2)
stopb = 2;
dcb.StopBits = stopb;
if(!SetCommState(m_hCom, &dcb))
return FALSE;
return TRUE;
}
BOOL CCom::SetCacheSize(DWORD RxCacheSize, DWORD TxCacheSize)
{
if(!m_hCom){
return FALSE;
}
if(!SetupComm(m_hCom, RxCacheSize, TxCacheSize)) {
return FALSE;
}
return TRUE;
}
void CCom::ClearCache()
{
if(!m_hCom){
return ;
}
PurgeComm(m_hCom,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
}
BOOL CCom::OpenPort(const char* Com, DWORD BaudRate, char WordLength, char StopBits, char Parity)
{
char strport[11];
memset(strport, 0, 11);
if(*(Com + 4)){
strcpy(strport, "\\\\.\\COM");
strcpy(strport + 7, Com + 3);
}else{
strcpy(strport, Com);
}
m_hCom = CreateFile(strport, //COM口
GENERIC_READ | GENERIC_WRITE, //允许读和写
0, //独占方式
NULL,
OPEN_EXISTING, //打开而不是创建
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //重叠方式
NULL );
if(m_hCom == (HANDLE) - 1){
m_hCom = NULL;
return FALSE;
}
if(!SetComPar(BaudRate, WordLength, StopBits, Parity)){
Close();
return FALSE;
}
if(!SetCacheSize(1024, 1024)){
Close();
return FALSE;
}
ClearCache();
COMMTIMEOUTS TimeOuts;
TimeOuts.ReadIntervalTimeout = 10;
TimeOuts.ReadTotalTimeoutConstant = 0;
TimeOuts.ReadTotalTimeoutMultiplier = 0;
TimeOuts.WriteTotalTimeoutConstant = 100;
TimeOuts.WriteTotalTimeoutMultiplier = 500;
BOOL sig = SetCommTimeouts(m_hCom, &TimeOuts);
m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
return TRUE;
}
int CCom::Send(BYTE *pBuf, DWORD SendByte, DWORD TimeOut)
{
DWORD dwBeWritten;
if(!m_hCom){
return 0;
}
PurgeComm(m_hCom, PURGE_RXCLEAR);
if(!WriteFile(m_hCom, (LPSTR)pBuf, SendByte, &dwBeWritten, &m_OverlappedWrite)){
if(GetLastError() == ERROR_IO_PENDING){
DWORD Result = WaitForSingleObject(m_OverlappedWrite.hEvent, TimeOut);
if(WAIT_TIMEOUT == Result || WAIT_OBJECT_0 == Result){
GetOverlappedResult(m_hCom, &m_OverlappedWrite, &dwBeWritten, FALSE);
}
} else {
dwBeWritten = 0;
}
}
if(dwBeWritten == SendByte){
PurgeComm(m_hCom, PURGE_TXCLEAR);
}
return (int)dwBeWritten; //返回实际写入的字节数
}
//extend read option, if Flag == TRUE, clear the receive buffer before return.
int CCom::ReadEX(BYTE *pBuf, DWORD ReadByte, DWORD TimeOut, int Flag)
{
if(!m_hCom){
return 0;
}
DWORD dwBytesRead, dwErrorFlags;
ClearCommError(m_hCom, &dwErrorFlags, NULL);
if(!ReadFile(m_hCom, pBuf, ReadByte, &dwBytesRead, &m_OverlappedRead)){
if(GetLastError() == ERROR_IO_PENDING){
DWORD Result = WaitForSingleObject(m_OverlappedRead.hEvent, TimeOut);
if(WAIT_TIMEOUT == Result || WAIT_OBJECT_0 == Result){
GetOverlappedResult(m_hCom, &m_OverlappedRead, &dwBytesRead, FALSE);
} else {
dwBytesRead = 0;
}
} else {
dwBytesRead = 0;
}
}
DWORD dwFlags = PURGE_RXABORT;
if(dwBytesRead == 0 || Flag){
dwFlags |= PURGE_RXCLEAR; //清除接收缓存区
}
PurgeComm(m_hCom, dwFlags);
return (int)dwBytesRead;
}
int CCom::Read(BYTE *pBuf, DWORD ReadByte, DWORD TimeOut)
{
return ReadEX(pBuf, ReadByte, TimeOut, FALSE);
}
void CCom::Close()
{
if(m_hCom) {
CloseHandle(m_hCom); //handle to object to close
}
if(m_OverlappedRead.hEvent) {
CloseHandle(m_OverlappedRead.hEvent);
}
if(m_OverlappedWrite.hEvent){
CloseHandle(m_OverlappedWrite.hEvent);
}
m_hCom = NULL;
m_OverlappedRead.hEvent = NULL;
m_OverlappedWrite.hEvent = NULL;
}
void CCom::StratCounter()
{
Cnter = GetTickCount();
}
DWORD CCom::GetCounter()
{
return GetTickCount() - Cnter;
}