#pragma once
|
/*
|
*
|
* ´®¿ÚͨѶͷÎļþ
|
*
|
* Version: V1.01
|
* Date: 2015-06-30
|
* Description:
|
* 2015-07-10 Add Speed Function;
|
* 2015-07-24 ÓÅ»¯ËٶȼÆË㣬ÿ1ÃëÒ»´Î¸ÄΪÿ°ëÃëÒ»´Î
|
*/
|
inline double GetTimeMs()
|
{
|
LARGE_INTEGER perfreq;
|
LARGE_INTEGER percounter1;
|
QueryPerformanceFrequency(&perfreq);
|
QueryPerformanceCounter(&percounter1);
|
|
double time1=(double)percounter1.QuadPart/perfreq.QuadPart;
|
return (time1*1000);
|
};
|
|
class CSerialCom
|
{
|
public:
|
enum Results {
|
R_OK,
|
R_ERR,
|
};
|
HANDLE hCom1;
|
int IsOpened;
|
|
int Port;
|
int BaudRate;
|
CString Settings;
|
|
DWORD dwError;
|
CString strResult;
|
int m_nCountToTry = 2;
|
int m_nCountToWait = 0;
|
|
volatile DWORD TotalSendBytes,TotalRecvBytes;
|
volatile DWORD SendBytes,RecvBytes;
|
volatile DWORD LastSendBytes,LastRecvBytes;
|
volatile DWORD SendSpeed,RecvSpeed;
|
volatile double LastTime;
|
CSerialCom(void)
|
{
|
this->hCom1=INVALID_HANDLE_VALUE;
|
this->IsOpened=0;
|
|
this->Port=0;
|
this->BaudRate=0;
|
this->Settings.Empty();
|
|
this->dwError=0;
|
};
|
~CSerialCom(void)
|
{
|
if (this->IsOpened) {this->Close();}
|
this->hCom1=INVALID_HANDLE_VALUE;
|
};
|
|
int Open()
|
{
|
int j;
|
CString s1,s2;
|
CString ComPortName;
|
if (this->Port==0) {return 0;}
|
if (this->IsOpened) {return -1;}
|
ComPortName.Format(_T("\\\\.\\COM%d"),this->Port);
|
hCom1=CreateFile(ComPortName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);//FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED
|
if (hCom1==INVALID_HANDLE_VALUE)
|
{
|
dwError=GetLastError();
|
IsOpened=false;
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,0,dwError,0,s1.GetBuffer(2048),2048,NULL);
|
s1.ReleaseBuffer();
|
|
strResult.Format(_T("Open COM%d Err %d ,%s "),this->Port,this->dwError,s1);
|
return 0;
|
}
|
else
|
{
|
dwError=GetLastError();
|
|
strResult.Format(_T("COM%d OK."),this->Port);
|
LastTime = GetTimeMs();
|
TotalSendBytes = 0; TotalRecvBytes = 0;
|
LastSendBytes = 0; SendBytes = 0; RecvBytes = 0;
|
LastRecvBytes = 0; SendSpeed = 0; RecvSpeed = 0;
|
}
|
|
j=SetupComm(hCom1,256,256);
|
|
DCB dcb1;
|
j=GetCommState(hCom1,&dcb1);
|
BuildCommDCB(Settings,&dcb1);
|
|
dcb1.BaudRate=BaudRate;
|
|
if (Settings.Find(_T("8")) != -1) { dcb1.ByteSize = 8; }
|
else if (Settings.Find(_T("7")) != -1) { dcb1.ByteSize = 8; }
|
else if (Settings.Find(_T("6")) != -1) { dcb1.ByteSize = 8; }
|
else if (Settings.Find(_T("5")) != -1) { dcb1.ByteSize = 8; }
|
|
if (Settings.Find(_T("N")) != -1) { dcb1.fParity = FALSE; dcb1.Parity = NOPARITY;}
|
else if (Settings.Find(_T("O")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = ODDPARITY;}
|
else if (Settings.Find(_T("E")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = EVENPARITY;}
|
else if (Settings.Find(_T("M")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = MARKPARITY;}
|
else if (Settings.Find(_T("S")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = SPACEPARITY;}
|
|
if (Settings.Find(_T("1.5")) != -1) { dcb1.StopBits = ONE5STOPBITS;}
|
else if (Settings.Find(_T("1")) != -1) { dcb1.StopBits = ONESTOPBIT; }
|
else if (Settings.Find(_T("2")) != -1) { dcb1.StopBits = TWOSTOPBITS; }
|
|
dcb1.fDtrControl=0;
|
dcb1.fDsrSensitivity=false;
|
dcb1.fBinary=1;
|
dcb1.fOutxCtsFlow=false;
|
dcb1.fOutxDsrFlow=false;
|
dcb1.fRtsControl=RTS_CONTROL_DISABLE;
|
|
j=SetCommState(hCom1,&dcb1);
|
if (j == 0)
|
{
|
strResult.Format(_T("SetCommState Fail %d %s \r\n"),BaudRate,Settings);
|
CloseHandle(hCom1);
|
IsOpened = false;
|
return 0;
|
}
|
j=GetCommState(hCom1,&dcb1);
|
|
CString strParity;
|
CString strStopBit;
|
|
if (dcb1.Parity == NOPARITY) { strParity = _T("N"); }
|
else if (dcb1.Parity == EVENPARITY) { strParity = _T("E"); }
|
else if (dcb1.Parity == ODDPARITY) { strParity = _T("O"); }
|
else if (dcb1.Parity == MARKPARITY) { strParity = _T("M"); }
|
else if (dcb1.Parity == SPACEPARITY) { strParity = _T("S"); }
|
else { strParity = _T("X"); }
|
|
if (dcb1.StopBits == ONESTOPBIT) { strStopBit = _T("1"); }
|
else if (dcb1.StopBits == ONE5STOPBITS) { strStopBit = _T("1.5"); }
|
else if (dcb1.StopBits == TWOSTOPBITS) { strStopBit = _T("2"); }
|
else { strStopBit = _T("3"); }
|
|
s1.Format(_T("%d %d-%s-%s"), dcb1.BaudRate,dcb1.ByteSize, strParity, strStopBit);
|
strResult += s1;
|
|
COMMTIMEOUTS comtimeout1;
|
COMSTAT comstat1;
|
GetCommTimeouts(hCom1,&comtimeout1);
|
|
comtimeout1.ReadIntervalTimeout=1; //Á½¸ö×Ö·ûÖ®¼äµÄʱ¼ä
|
comtimeout1.ReadTotalTimeoutMultiplier=0; //ÿ¸ö×Ö·ûµÈ´ýµÄʱ¼ä£¬¶Á¶à¸ö×Ö·ûÔòµÈ´ýʱ¼äΪµ¥¸öʱ¼ä³ËÒÔ×Ö·û¸öÊý
|
comtimeout1.ReadTotalTimeoutConstant=1; //¶Áȡʱ£¬ÔÙÁíÍâ¶àµÈ´ýµÄʱ¼ä¡£
|
comtimeout1.WriteTotalTimeoutMultiplier=0; //дÈëʱ£¬Ã¿¸ö×Ö·ûµÈ´ýµÄʱ¼ä£¬Ð´Èë¶à¸ö×Ö·ûÔòµÈ´ýʱ¼äΪµ¥¸öʱ¼ä³ËÒÔ×Ö·û¸öÊý¡£
|
comtimeout1.WriteTotalTimeoutConstant=0; //дÈëʱ£¬ÔÙÁíÍâ¶àµÈ´ýµÄʱ¼ä¡£
|
|
SetCommTimeouts(hCom1,&comtimeout1);
|
j=ClearCommError(hCom1,&dwError,&comstat1);
|
s1.Format(_T("ClearCommError j %d errors %d "),j,dwError);
|
s2=s1;
|
s1.Format(_T("cbInQue %d "),comstat1.cbInQue);
|
s2+=s1;
|
s1.Format(_T("cbOutQue %d "),comstat1.cbOutQue );
|
s2+=s1;
|
|
PurgeComm(hCom1,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_TXCLEAR);
|
|
IsOpened = true;
|
return 1;
|
};
|
int Purge()
|
{
|
return PurgeComm(hCom1,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_TXCLEAR);
|
}
|
void Close()
|
{
|
LastSendBytes=0;
|
LastRecvBytes=0;
|
SendBytes=0;
|
RecvBytes=0;
|
SendSpeed=0;
|
RecvSpeed=0;
|
|
if (IsOpened)
|
{
|
IsOpened=false;
|
CString s1;
|
strResult.Format(_T("Close COM %d "),this->Port);
|
CloseHandle(hCom1);
|
}
|
};
|
int CSerialCom::CalSpeed()
|
{
|
double thistime = GetTimeMs();
|
double diftime = thistime - LastTime;
|
if (diftime >= 500)
|
{
|
SendSpeed = (DWORD)(SendBytes * 1000 / diftime);
|
RecvSpeed = static_cast<DWORD> (RecvBytes * 1000 / diftime);
|
LastSendBytes = SendBytes; SendBytes = 0;
|
LastRecvBytes = RecvBytes; RecvBytes = 0;
|
LastTime = thistime;
|
}
|
return 0;
|
}
|
int CSerialCom::Send(const char * buffer, int n)
|
{
|
CString s1;
|
int i,j;
|
DWORD numsent;
|
|
if (!IsOpened) {return 0;}
|
|
j=WriteFile(hCom1,buffer,n,&numsent,NULL);
|
|
if (j!=0)
|
{
|
strResult.Format(_T("Send To COM%d OK %dB : "),this->Port,numsent);
|
for (i=0;(unsigned )i<numsent;i++)
|
{
|
strResult.AppendFormat(_T("%c"),buffer[i]);
|
}
|
strResult.AppendFormat(_T("\r\n"));
|
}
|
else
|
{
|
dwError=GetLastError();
|
strResult.Format(_T("Send To COM%d fail. Error:%d SentBytes:%d "),this->Port,dwError,numsent);
|
}
|
SendBytes+=numsent;
|
TotalSendBytes+=numsent;
|
return numsent;
|
};
|
int CSerialCom::Read(char * buffer, int numToRead)
|
{
|
CString s1;
|
int i,j;
|
DWORD numreaded;
|
if (!IsOpened) {return 0;}
|
int len2=0;
|
//Sleep(n/10);
|
int nTryCount2 = 0;
|
for (int i = 0; i < m_nCountToTry; i++)
|
{
|
j = ReadFile(hCom1, buffer+len2, numToRead-len2, &numreaded, NULL);
|
if (j != 0){
|
len2 += numreaded;
|
buffer[len2] = 0;
|
if (len2 >= numToRead) break;
|
nTryCount2 = 0;
|
}
|
else{
|
if (len2 > 0) {
|
nTryCount2++;
|
if (nTryCount2 >= m_nCountToWait) break;
|
}
|
}
|
if (len2 > 0 && nTryCount2 >= m_nCountToWait) break;
|
}
|
numreaded = len2;
|
if (numreaded > 0){
|
strResult.Format(_T("Read From COM%d OK %dB "), this->Port, numreaded);
|
for (i = 0; (unsigned)i < numreaded; i++)
|
{
|
strResult.AppendFormat(_T("%c"), buffer[i]);
|
}
|
strResult.AppendFormat(_T("\r\n"));
|
}
|
else{
|
strResult.Format(_T("Read From COM failed \r\n"));
|
}
|
|
RecvBytes+=numreaded;
|
TotalRecvBytes+=numreaded;
|
|
return numreaded;
|
};
|
};
|
/*
|
ÓëÒÔÍùDOSÏ´®ÐÐͨÐųÌÐò²»Í¬µÄÊÇ£¬Windows²»ÌᳫӦÓóÌÐòÖ±½Ó¿ØÖÆÓ²¼þ£¬¶øÊÇͨ¹ýWindows²Ù×÷ϵͳÌṩµÄÉ豸Çý¶¯³ÌÐòÀ´½øÐÐÊý¾Ý´«µÝ¡£
|
´®ÐпÚÔÚWin 32ÖÐÊÇ×÷ΪÎļþÀ´½øÐд¦ÀíµÄ£¬¶ø²»ÊÇÖ±½Ó¶Ô¶Ë¿Ú½øÐвÙ×÷£¬¶ÔÓÚ´®ÐÐͨÐÅ£¬Win 32 ÌṩÁËÏàÓ¦µÄÎļþI/Oº¯ÊýÓëͨÐź¯Êý£¬
|
ͨ¹ýÁ˽âÕâЩº¯ÊýµÄʹÓ㬿ÉÒÔ±àÖƳö·ûºÏ²»Í¬ÐèÒªµÄͨÐųÌÐò¡£
|
ÓëͨÐÅÉ豸Ïà¹ØµÄ½á¹¹ÓÐCOMMCONFIG £¬COMMPROP£¬COMMTIMEOUTS£¬COMSTAT£¬DCB£¬MODEMDEVCAPS£¬MODEMSETTINGS¹²7¸ö£¬
|
ÓëͨÐÅÓйصÄWindows APIº¯Êý¹²ÓÐ26¸ö£¬Ïêϸ˵Ã÷¿É²Î¿¼MSDN°ïÖúÎļþ¡£ÒÔϽ«½áºÏʵÀý£¬¸ø³öʵÏÖ´®ÐÐͨÐŵÄÈýÖÖ·½·¨¡£
|
|
*/
|
|