⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialport.cpp

📁 很好用的串口类
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    
    // Kill this thread.  break is not needed, but makes me feel better.
    AfxEndThread(100);
    break;
   }
  case 1: // read event
   {
    GetCommMask(port->m_hComm, &CommEvent);
    if (CommEvent & EV_CTS)
     ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_CTS_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
    if (CommEvent & EV_RXFLAG)
     ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_RXFLAG_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
    if (CommEvent & EV_BREAK)
     ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_BREAK_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
    if (CommEvent & EV_ERR)
     ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_ERR_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
    if (CommEvent & EV_RING)
     ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_RING_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
    
    if (CommEvent & EV_RXCHAR)
     // Receive character event from port.
     ReceiveChar(port, comstat);
     
    break;
   }  
  case 2: // write event
   {
    // Write character event from port
    WriteChar(port);
    break;
   }

  } // end switch

 } // close forever loop

 return 0;
}

//
// start comm watching
//
BOOL CSerialPort::StartMonitoring()
{
 if (!(m_Thread = AfxBeginThread(CommThread, this)))
  return FALSE;
 TRACE("Thread started\n");
 return TRUE; 
}

//
// Restart the comm thread
//
BOOL CSerialPort::RestartMonitoring()
{
 TRACE("Thread resumed\n");
 m_Thread->ResumeThread();
 return TRUE; 
}


//
// Suspend the comm thread
//
BOOL CSerialPort::StopMonitoring()
{
 TRACE("Thread suspended\n");
 m_Thread->SuspendThread(); 
 return TRUE; 
}


//
// If there is a error, give the right message
//
void CSerialPort::ProcessErrorMessage(char* ErrorText)
{
 char *Temp = new char[200];
 
 LPVOID lpMsgBuf;

 FormatMessage( 
  FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  NULL,
  GetLastError(),
  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  (LPTSTR) &lpMsgBuf,
  0,
  NULL 
 );

 sprintf(Temp, "WARNING:  %s Failed with the following error: \n%s\nPort: %d\n", (char*)ErrorText, lpMsgBuf, m_nPortNr); 
 MessageBox(NULL, Temp, "Application Error", MB_ICONSTOP);

 LocalFree(lpMsgBuf);
 delete[] Temp;
}

//
// Write a character.
//
void CSerialPort::WriteChar(CSerialPort* port)
{
 BOOL bWrite = TRUE;
 BOOL bResult = TRUE;

 DWORD BytesSent = 0;

 ResetEvent(port->m_hWriteEvent);

 // Gain ownership of the critical section
 EnterCriticalSection(&port->m_csCommunicationSync);

 if (bWrite)
 {
  // Initailize variables
  port->m_ov.Offset = 0;
  port->m_ov.OffsetHigh = 0;

  // Clear buffer
  PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

  bResult = WriteFile(port->m_hComm,       // Handle to COMM Port
       port->m_szWriteBuffer,     // Pointer to message buffer in calling finction
       strlen((char*)port->m_szWriteBuffer), // Length of message to send
       &BytesSent,        // Where to store the number of bytes sent
       &port->m_ov);       // Overlapped structure

  // deal with any error codes
  if (!bResult)  
  {
   DWORD dwError = GetLastError();
   switch (dwError)
   {
    case ERROR_IO_PENDING:
     {
      // continue to GetOverlappedResults()
      BytesSent = 0;
      bWrite = FALSE;
      break;
     }
    default:
     {
      // all other error codes
      port->ProcessErrorMessage("WriteFile()");
     }
   }
  } 
  else
  {
   LeaveCriticalSection(&port->m_csCommunicationSync);
  }
 } // end if(bWrite)

 if (!bWrite)
 {
  bWrite = TRUE;
 
  bResult = GetOverlappedResult(port->m_hComm, // Handle to COMM port 
           &port->m_ov,  // Overlapped structure
           &BytesSent,  // Stores number of bytes sent
           TRUE);    // Wait flag

  LeaveCriticalSection(&port->m_csCommunicationSync);

  // deal with the error code 
  if (!bResult)  
  {
   port->ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
  } 
 } // end if (!bWrite)

 // Verify that the data size send equals what we tried to send
 if (BytesSent != strlen((char*)port->m_szWriteBuffer))
 {
  TRACE("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)port->m_szWriteBuffer));
 }
}

//
// Character received. Inform the owner
//
void CSerialPort::ReceiveChar(CSerialPort* port, COMSTAT comstat)
{
 BOOL  bRead = TRUE; 
 BOOL  bResult = TRUE;
 DWORD dwError = 0;
 DWORD BytesRead = 0;
 unsigned char RXBuff;

 for (;;) 
 { 
  // Gain ownership of the comm port critical section.
  // This process guarantees no other part of this program 
  // is using the port object. 
  
  EnterCriticalSection(&port->m_csCommunicationSync);

  // ClearCommError() will update the COMSTAT structure and
  // clear any other errors.
  
  bResult = ClearCommError(port->m_hComm, &dwError, &comstat);

  LeaveCriticalSection(&port->m_csCommunicationSync);

  // start forever loop.  I use this type of loop because I
  // do not know at runtime how many loops this will have to
  // run. My solution is to start a forever loop and to
  // break out of it when I have processed all of the
  // data available.  Be careful with this approach and
  // be sure your loop will exit.
  // My reasons for this are not as clear in this sample 
  // as it is in my production code, but I have found this 
  // solutiion to be the most efficient way to do this.
  
  if (comstat.cbInQue == 0)
  {
   // break out when all bytes have been read
   break;
  }
      
  EnterCriticalSection(&port->m_csCommunicationSync);

  if (bRead)
  {
   bResult = ReadFile(port->m_hComm,  // Handle to COMM port 
          &RXBuff,    // RX Buffer Pointer
          1,     // Read one byte
          &BytesRead,   // Stores number of bytes read
          &port->m_ov);  // pointer to the m_ov structure
   // deal with the error code 
   if (!bResult)  
   { 
    switch (dwError = GetLastError()) 
    { 
     case ERROR_IO_PENDING:  
      { 
       // asynchronous i/o is still in progress 
       // Proceed on to GetOverlappedResults();
       bRead = FALSE;
       break;
      }
     default:
      {
       // Another error has occured.  Process this error.
       port->ProcessErrorMessage("ReadFile()");
       break;
      } 
    }
   }
   else
   {
    // ReadFile() returned complete. It is not necessary to call GetOverlappedResults()
    bRead = TRUE;
   }
  }  // close if (bRead)

  if (!bRead)
  {
   bRead = TRUE;
   bResult = GetOverlappedResult(port->m_hComm, // Handle to COMM port 
            &port->m_ov,  // Overlapped structure
            &BytesRead,  // Stores number of bytes read
            TRUE);    // Wait flag

   // deal with the error code 
   if (!bResult)  
   {
    port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
   } 
  }  // close if (!bRead)
    
  LeaveCriticalSection(&port->m_csCommunicationSync);

  // notify parent that a byte was received
  ::SendMessage((port->m_pOwner)->m_hWnd, WM_COMM_RXCHAR, (WPARAM) RXBuff, (LPARAM) port->m_nPortNr);
 } // end forever loop

}

//
// Write a string to the port
//
void CSerialPort::WriteToPort(char* string)
{  
 assert(m_hComm != 0);

 memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
 strcpy(m_szWriteBuffer, string);

 // set event for write
 SetEvent(m_hWriteEvent);
}

//
// Return the device control block
//
DCB CSerialPort::GetDCB()
{
 return m_dcb;
}

//
// Return the communication event masks
//
DWORD CSerialPort::GetCommEvents()
{
 return m_dwCommEvents;
}

//
// Return the output buffer size
//
DWORD CSerialPort::GetWriteBufferSize()
{
 return m_nWriteBufferSize;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -