#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 (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 )iPort,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°ïÖúÎļþ¡£ÒÔϽ«½áºÏʵÀý£¬¸ø³öʵÏÖ´®ÐÐͨÐŵÄÈýÖÖ·½·¨¡£ */