#include "pch.h" #include "HvSerialPort.h" int HvSerialPort1::Init() { return R_OK; } int HvSerialPort1::SetParams(int nPortNum, int BaudRate, CString Settings) { m_nPort = nPortNum; m_nBaudRate = BaudRate; m_Settings = Settings; return R_OK; } int HvSerialPort1::Open() { // TODO: ÔÚ´Ë´¦Ìí¼ÓʵÏÖ´úÂë. //Open Port int j; CString s1, s2; CString ComPortName; m_strResult.Empty(); if (this->m_nPort == 0) { m_strResult.Format(_T("COM not specified %d"),m_nPort); return R_ERR; } if (this->m_bOpened) { m_strResult.Format(_T("COM%d already Opened"),m_nPort); return R_OK; } ComPortName.Format(_T("\\\\.\\COM%d"), this->m_nPort); hCom1 = CreateFile(ComPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);//FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED if (hCom1 == INVALID_HANDLE_VALUE) { m_dwError = GetLastError(); m_bOpened = false; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, m_dwError, 0, s1.GetBuffer(2048), 2048, NULL); s1.ReleaseBuffer(); m_strResult.Format(_T("Open COM%d Err %d ,%s "), this->m_nPort, this->m_dwError, s1); return R_ERR; } else { m_dwError = GetLastError(); m_strResult.Format(_T("COM%d OK."), this->m_nPort); 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(m_Settings, &dcb1); dcb1.BaudRate = m_nBaudRate; if (m_Settings.Find(_T("8")) != -1) { dcb1.ByteSize = 8; } else if (m_Settings.Find(_T("7")) != -1) { dcb1.ByteSize = 8; } else if (m_Settings.Find(_T("6")) != -1) { dcb1.ByteSize = 8; } else if (m_Settings.Find(_T("5")) != -1) { dcb1.ByteSize = 8; } if (m_Settings.Find(_T("N")) != -1) { dcb1.fParity = FALSE; dcb1.Parity = NOPARITY; } else if (m_Settings.Find(_T("O")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = ODDPARITY; } else if (m_Settings.Find(_T("E")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = EVENPARITY; } else if (m_Settings.Find(_T("M")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = MARKPARITY; } else if (m_Settings.Find(_T("S")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = SPACEPARITY; } if (m_Settings.Find(_T("1.5")) != -1) { dcb1.StopBits = ONE5STOPBITS; } else if (m_Settings.Find(_T("1")) != -1) { dcb1.StopBits = ONESTOPBIT; } else if (m_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) { m_strResult.Format(_T("SetCommState Fail %d %s \r\n"), m_nBaudRate, m_Settings); CloseHandle(hCom1); m_bOpened = false; return R_ERR; } 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); m_strResult += s1; COMMTIMEOUTS comtimeout1; COMSTAT comstat1; GetCommTimeouts(hCom1, &comtimeout1); comtimeout1.ReadIntervalTimeout = 1; //Á½¸ö×Ö·ûÖ®¼äµÄʱ¼ä comtimeout1.ReadTotalTimeoutMultiplier = 0; //ÿ¸ö×Ö·ûµÈ´ýµÄʱ¼ä£¬¶Á¶à¸ö×Ö·ûÔòµÈ´ýʱ¼äΪµ¥¸öʱ¼ä³ËÒÔ×Ö·û¸öÊý comtimeout1.ReadTotalTimeoutConstant = 2; //¶Áȡʱ£¬ÔÙÁíÍâ¶àµÈ´ýµÄʱ¼ä¡£ comtimeout1.WriteTotalTimeoutMultiplier = 0; //дÈëʱ£¬Ã¿¸ö×Ö·ûµÈ´ýµÄʱ¼ä£¬Ð´Èë¶à¸ö×Ö·ûÔòµÈ´ýʱ¼äΪµ¥¸öʱ¼ä³ËÒÔ×Ö·û¸öÊý¡£ comtimeout1.WriteTotalTimeoutConstant = 0; //дÈëʱ£¬ÔÙÁíÍâ¶àµÈ´ýµÄʱ¼ä¡£ SetCommTimeouts(hCom1, &comtimeout1); j = ClearCommError(hCom1, &m_dwError, &comstat1); s1.Format(_T("ClearCommError j %d errors %d "), j, m_dwError); s2 = s1; s1.Format(_T("cbInQue %d "), comstat1.cbInQue); s2 += s1; s1.Format(_T("cbOutQue %d "), comstat1.cbOutQue); s2 += s1; //PurgeComBuf(); ClearBuf(); m_bOpened = true; //Start Read Thread // MyThreadProc1ToRun = 1; // AfxBeginThread(MyJumper1, (LPVOID)this); return R_OK; } int HvSerialPort1::ClearStatData() { LastSendBytes = 0; LastRecvBytes = 0; SendBytes = 0; RecvBytes = 0; SendSpeed = 0; RecvSpeed = 0; return R_OK; } int HvSerialPort1::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 HvSerialPort1::Close() { // TODO: ÔÚ´Ë´¦Ìí¼ÓʵÏÖ´úÂë. if (m_bOpened) { // SendSign(STOP); MyThreadProc1ToRun = 0; Sleep(10); // wait for Thread stop //WaitForMultipleObjects(nCount); // close port CloseHandle(hCom1); m_bOpened = 0; hCom1 = INVALID_HANDLE_VALUE; m_strResult.Format(_T("COM%d Closed"), m_nPort); return R_OK; } else { m_strResult.Format(_T("COM%d not Opened"),m_nPort); return R_ERR; } } int HvSerialPort1::SetRecvDoneCallBack(pRecvDone pRecvDoneFunc) { // TODO: ÔÚ´Ë´¦Ìí¼ÓʵÏÖ´úÂë. if (pRecvDoneFunc != NULL) { RecvDoneCB = pRecvDoneFunc; m_bRecvDoneCBSet = 1; } else { RecvDoneCB = NULL; m_bRecvDoneCBSet = 0; } return R_OK; } UINT HvSerialPort1::MyJumper1(LPVOID pParam) //Ïß³ÌÌø°å { HvSerialPort1 *pInput = (HvSerialPort1 *)pParam; //·´Ìøµ½ÕæÕýµÄÖ´ÐгÌÐò return pInput->MyThreadProc1(0); } DWORD WINAPI HvSerialPort1::MyThreadProc1(LPVOID pParam) { //´®¿Ú½ÓÊÕÊý¾Ýº¯Êý //½ÓÊÕµ½µÄÊý¾Ý ֪ͨ·½Ê½ // 1. windowsÏûÏ¢¶ÓÁÐ // 2. callback º¯Êý // ²»Í¬Ïß³Ì // 3. Event // 4. Buffer OVERLAPPED osRead; HANDLE hEventArr[2]; memset(&osRead, 0, sizeof(OVERLAPPED)); osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); SetCommMask(hCom1, EV_RXCHAR | EV_TXEMPTY); hEventArr[0] = osRead.hEvent; // hEventArr[1] = *g_OutPutList.GetEvent(); CString s1, s2; // SysLog(_T("Ï߳̿ªÊ¼ÔËÐÐ\r\n")); MyThreadProc1Running = 1; /* static OVERLAPPED ovlap1, ovlap2; */ //SysLog(_T("×¼±¸½ÓÊÕ\r\n")); DWORD dNumtoRead = 1000; dNumtoRead = 64; //nDataToSend = 0; DWORD wCount2 = 0; DWORD dwSent = 0; int nRunCount = 0; //¼ÆËã½ÓÊÕËÙ¶È; int LastSpeedTime = (int)GetTimemS(); int nThisRecv = 0; COMSTAT cs; OVERLAPPED os; DWORD dwTrans; DWORD dwReaded; for (; MyThreadProc1ToRun == 1;) { DWORD dwEvtMask = 0; ///* // BOOL result = WaitCommEvent(hCom1, &dwEvtMask, NULL); // &os); // if (!result) { // if (GetLastError() == ERROR_IO_PENDING) // { // GetOverlappedResult(hCom1, &os, &dwTrans, true); // } // if (dwEvtMask & EV_RXCHAR) if (1) { Sleep(1); } else { ClearCommError(hCom1, &m_dwError, &cs); int bytes = cs.cbInQue; dwReaded = 0; if (bytes > 0) { int j = ReadFile(hCom1, RecvBuf2, bytes, &dwReaded, NULL); if (j > 0) { //m_CS1.Lock(); EnterCriticalSection(&g_cs); memcpy(RecvBuf + RecvBufDataLen, RecvBuf2, dwReaded); RecvBufDataLen += dwReaded; //m_CS1.Unlock(); LeaveCriticalSection(&g_cs); } } else { Sleep(1); } } } if (RecvBufDataLen > 1024) { RecvBufDataLen = 0; } //EscapeCommFunction(hCom1, SETDTR); //*/ } //SysLog(_T("Ìø³ö½ÓÊÕÑ­»·\r\n")); // hcurDC.SelectObject(def_font); // CloseHandle(hCom); //SysLog(_T("Ï߳̽áÊøÔËÐÐ\r\n\r\n")); MyThreadProc1Running = 0; return 0; } int HvSerialPort1::ClearBuf() { COMSTAT cs; for (int i = 0; i < 100;i++) { ClearCommError(hCom1, &m_dwError, &cs); int bytes = cs.cbInQue; if (bytes > 0) { Sleep(10); } PurgeComm(hCom1, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); if (bytes == 0) break; } RecvBufDataLen = 0; RecvBufPos = 0; return 0; } int HvSerialPort1::Send(void * pBuf, int len1) { // TODO: ÔÚ´Ë´¦Ìí¼ÓʵÏÖ´úÂë. CString s1; int i, j; DWORD numsent; if (!m_bOpened) { return R_ERR; } j = WriteFile(hCom1, pBuf, len1, &numsent, NULL); if (j != 0) { m_strResult.Format(_T("Send To COM%d OK %dB : "), this->m_nPort, numsent); for (i = 0; (unsigned)i < numsent; i++) { m_strResult.AppendFormat(_T("%c"), ((char *)pBuf)[i]); } m_strResult.AppendFormat(_T("\r\n")); } else { m_dwError = GetLastError(); m_strResult.Format(_T("Send To COM%d fail. Error:%d SentBytes:%d "), this->m_nPort, m_dwError, numsent); } SendBytes += numsent; TotalSendBytes += numsent; return numsent; return R_OK; } int HvSerialPort1::Recv(void * pBuf, int len1) { return RecvFromCom(pBuf, len1); } int HvSerialPort1::RecvFromBuf(void * pBuf, int len1) { CString s1; int i, j; DWORD numreaded = 0; int numtoread = len1; m_strResult.Format(_T("ToRead %d "), len1); for (i = 0; i < 20; i++) { int k; //m_CS1.Lock(); EnterCriticalSection(&g_cs); if (RecvBufDataLen) { if (RecvBufDataLen >= numtoread) { memcpy((char *)pBuf+numreaded, RecvBuf, numtoread); numreaded += numtoread; RecvBufDataLen -= numtoread; numtoread = 0; memmove(RecvBuf, RecvBuf + numtoread, RecvBufDataLen); } else { memcpy((char *)pBuf + numreaded, RecvBuf, RecvBufDataLen); numreaded += RecvBufDataLen; RecvBufDataLen = 0; RecvBufPos = 0; numtoread -= RecvBufDataLen; } } //m_CS1.Unlock(); LeaveCriticalSection(&g_cs); if (numtoread == 0) break; Sleep(1); } if (numreaded > 0) { m_strResult.AppendFormat(_T("Read From COM%d OK %dB "), this->m_nPort, numreaded); for (i = 0; (unsigned)i < numreaded; i++) { m_strResult.AppendFormat(_T("%c"), ((char *)pBuf)[i]); } m_strResult.AppendFormat(_T("\r\n")); } else { m_strResult.Format(_T("Read From COM%d failed \r\n"), this->m_nPort); } m_strResult.AppendFormat(_T("ToRun %d, Running %d"), MyThreadProc1ToRun, MyThreadProc1Running); return numreaded; } int HvSerialPort1::RecvFromCom(void * pBuf, int len1) { // TODO: ÔÚ´Ë´¦Ìí¼ÓʵÏÖ´úÂë. CString s1; int i, j; DWORD numreaded; if (!m_bOpened) { return R_ERR; } int len2 = 0; //Sleep(n/10); int nTryCount2 = 0; m_strResult.Format(_T("ToRead %d "), len1); for (int i = 0; i < m_nCountToTry; i++) { numreaded = 0; j = ReadFile(hCom1, (char *)pBuf + len2, len1 - len2, &numreaded, NULL); if (j != 0) { len2 += numreaded; ((char *)pBuf)[len2] = 0; if (len2 >= len1) 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) { m_strResult.AppendFormat(_T("Read From COM%d OK %dB "), this->m_nPort, numreaded); for (i = 0; (unsigned)i < numreaded; i++) { m_strResult.AppendFormat(_T("%c"), ((char *)pBuf)[i]); } m_strResult.AppendFormat(_T("\r\n")); } else { m_strResult.AppendFormat(_T("Read From COM%d failed \r\n"),this->m_nPort); } RecvBytes += numreaded; TotalRecvBytes += numreaded; return numreaded; return R_OK; }