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

📄 rs232port.cpp

📁 mod_RSsim
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   timeout.WriteTotalTimeoutConstant = 2000;
   timeout.WriteTotalTimeoutMultiplier = 60;    // 60ms per char sent
                                                
   error = SetCommTimeouts(h232Port, &timeout);
   if (! error)
   {
   CString errMsg("Error: Could configure the timeouts.");

      RSDataMessage(errMsg);
      AfxMessageBox(errMsg, MB_OK|MB_ICONEXCLAMATION);
      ClosePort();
      return FALSE;
   }
   
   RSDataMessage("Timeouts configured (100ms/500ms)\n");
   // done
   m_lastCharIncommingtime = GetTickCount() + PORT_MAX_IDLETIME*5;
   return (TRUE);
} // ConfigurePort

// ----------------------------------- Purge ---------------------------
// remove all characters from the RX buffer (eliminates back-log)
//
BOOL CRS232Port::Purge()
{
BOOL ret;

   if (!keepPolling)
      return FALSE;
   ASSERT(INVALID_HANDLE_VALUE != h232Port);
   // interlock
   EnterCriticalSection(&critSec);

   ret = PurgeComm(h232Port, PURGE_RXCLEAR);
   LeaveCriticalSection(&critSec);
   return (ret);
} // Purge

// ---------------------------------- ClosePort -------------------------
// PURPOSE:
BOOL CRS232Port::ClosePort()
{
   
   // interlock
   EnterCriticalSection(&critSec);
   if (INVALID_HANDLE_VALUE != h232Port)
   {
      // tell dialog that we are closing it (this is so fast anyway)
      RSStateChanged(RSPORTCURRENTLY_CLOSING);
      RSDataMessage("Closing port\n");
      CloseHandle(h232Port);
   }
   // set HANDLE to closed so we know in future
   h232Port = INVALID_HANDLE_VALUE;
   LeaveCriticalSection(&critSec);
   return (TRUE);
} // ClosePort

// ---------------------------------- Send --------------------------------
// PURPOSE: This one should be clear
//
LONG CRS232Port::Send(int numberOfBytestoWrite, 
                      const BYTE* bufferPtr, 
                      CHAR* debugStrPtr
                     )
{
BOOL error;
DWORD numberOfBytesWritten=0;

   ASSERT (numberOfBytestoWrite>0);
   if (!keepPolling)
      return FALSE;
   // send the bytes out on the wire
   if (INVALID_HANDLE_VALUE==h232Port)
   {
      OutputDebugString("Error: Cannot send. Port closed!\n");   // busy shutting down the app
      return FALSE;
   }
   
   // flag our intention
   RSStateChanged(RSPORTCURRENTLY_WRITTING);
   // interlock
   EnterCriticalSection(&critSec);
   //error = EscapeCommFunction(h232Port, CLRDTR);
//   ASSERT(0);
   error = WriteFile(h232Port,
                      bufferPtr,
                      numberOfBytestoWrite,                 // nNumberOfBytesToWrite,
                      &numberOfBytesWritten,
                      NULL); 
  // Sleep(50);
//   error = EscapeCommFunction(h232Port, SETDTR);
   LeaveCriticalSection(&critSec);
   
   // output it in windows debugger
   RSDataDebugger(bufferPtr, numberOfBytesWritten, TRUE);
   return (TRUE);
} // Send

// ------------------------------ GenDataDebugger ------------------------------
/*static*/ 
void CRS232Port::GenDataDebugger(const BYTE * buffer, LONG length, int transmit)
{
CString debuggerString;
BYTE *data;
byte hiNib,loNib;
   /*
   //convert BIN-ary to ASCII for display
   data = new BYTE[(length*2)+1];
   for (int i = 0; i < length; i++)
   {
       hiNib = ( *(buffer+i) >>4) & 0x0f;
       loNib = ( *(buffer+i)    ) & 0x0f;
       data[(i*2)]   = ( (hiNib < 0x0A) ? ('0' + hiNib) : ('A' + hiNib-10) );
       data[(i*2)+1] = ( (loNib < 0x0A) ? ('0' + loNib) : ('A' + loNib-10) );
   }

   data[(length*2)] = '\0';
   */
   //convert BIN-ary to ASCII for display
   data = new BYTE[(length*3)+1];
   BYTE* pChar = data;
   for (int i = 0; i < length; i++)
   {
       hiNib = ( *(buffer+i) >>4) & 0x0f;
       loNib = ( *(buffer+i)    ) & 0x0f;
       *pChar++ = ( (hiNib < 0x0A) ? ('0' + hiNib) : ('A' + hiNib-10) );
       *pChar++ = ( (loNib < 0x0A) ? ('0' + loNib) : ('A' + loNib-10) );
       *pChar++ = ' ';
   }
   --*pChar = '\0';
   //data[(length*2)] = '\0';

   if (transmit)
   {
      if (length)
         pGlobalDialog->OnCharactersSent();
      debuggerString.Format("TX:%s\n", data);
   }
   else
   {
      if (length)
         pGlobalDialog->OnCharactersReceived();
      debuggerString.Format("RX:%s\n", data);
   }

   // Send to debugger list-box
   if (length)
      pGlobalDialog->AddCommsDebugString(debuggerString);

#ifdef _COMMS_DEBUGGING
   OutputDebugString(debuggerString);
#endif

   delete (data);
} // GenDataDebugger


// ---------------------------- UpdateModemStatus -------------------------
void CRS232Port::UpdateModemStatus()
{
DWORD status;

   if (!keepPolling)
      return;
   // get ready to read bytes
   if (INVALID_HANDLE_VALUE==h232Port)
   {
      OutputDebugString("Error: Cannot get modem. Port closed!\n");   // busy shutting down the app
      Sleep(0);
      return;
   }


   
   GetCommModemStatus(h232Port,  &status);
   RSModemStatus(status);

   // display on scope when status changes
   if (m_lastModemStatus != status)
   {
   CString modemDescr;
      modemDescr.Format("Modem status : [CTS %c] [DSR %c] [RING %c]",
                           (status & MS_CTS_ON ? 'X' : '_'),
                           (status & MS_DSR_ON ? 'X' : '_'),
                           (status & MS_RING_ON? 'X' : '_')
                        );
      RSDataMessage(modemDescr);

      m_lastModemStatus = status;
   }
}


// ------------------------------ Recieve ------------------------------------
// return TRUE if a telegram was read.
// return false if no packet was read, this routine will keep trying to build a 
// full telegram.
LONG CRS232Port::Recieve(DWORD * numberOfBytesLong, CHAR* bufferPtr, CHAR* debugStrPtr)
{
BOOL error;
DWORD numberOfBytesWritten=0;
DWORD readAheadLength;        // # bytes we probably need (depends on what we have in the buffer so far)
DWORD numberOfBytesRead, dwCommError, tickCount;
BYTE * rxBuffPtr;
CString debuggerStr;

   RSStateChanged(RSPORTCURRENTLY_READING);
   if (!keepPolling)
      return FALSE;
   // get ready to read bytes
   if (INVALID_HANDLE_VALUE==h232Port)
   {
      OutputDebugString("Error: Cannot RX. Port closed!\n");   // busy shutting down the app
      Sleep(0);
      return FALSE;
   }

   // check if port has been idle for too long
   tickCount = GetTickCount();
   if (((LONG)tickCount - (LONG)m_lastCharIncommingtime) > PORT_MAX_IDLETIME)
   {
      m_lastCharIncommingtime = tickCount + PORT_MAX_IDLETIME*5;
      if (rxBufferIndex)
      {
      CString msg;
         msg = "Port idle, buffer cleared!\n";   // idle
         OutputDebugString(msg);
         RSDataMessage(msg);
         //OnHWError(0);
      }
      // start recieving from fresh again
      rxBufferIndex = 0;   // set up our RX buffer
      memset(rxBuffer, 0 , sizeof(rxBuffer));
      OnHWError(0);
   }

   rxBuffPtr = &rxBuffer[rxBufferIndex];
   *numberOfBytesLong = 0;

   // Work out our read-ahead length
   //
   readAheadLength = SimulationSerialPort::CalculateReadAheadLength(rxBuffer, rxBufferIndex);

   ASSERT(rxBufferIndex + readAheadLength < sizeof(rxBuffer));
#ifdef _COMMS_DEBUGGING
   //debuggerStr.Format("Read-ahead %d bytes\n", readAheadLength);
   //OutputDebugString(debuggerStr);
#endif
   
   // read what-ever is on the port, up to a maximum of readAheadLength.
   numberOfBytesRead = 0;
   EnterCriticalSection(&critSec);
   error = ReadFile(h232Port,
                      rxBuffPtr,
                      readAheadLength,                 // nNumberOfBytesToWrite,
                      &numberOfBytesRead,
                      NULL);
   LeaveCriticalSection(&critSec);
   rxBufferIndex+=numberOfBytesRead;
   
   // display the chars in the debugger
   RSDataDebugger(rxBuffPtr, numberOfBytesRead, FALSE);
   // keep idle tick count alive since we just got a char(s)
   if (numberOfBytesRead)
      m_lastCharIncommingtime = GetTickCount();
   
   if (0==error)
   {
      // clear it
      ClearCommError(h232Port, &dwCommError, NULL);
      // clear the buffers
      rxBufferIndex = 0;
      numberOfBytesRead = 0;
      OnHWError(dwCommError);
   }
   // done reading
   RSStateChanged(RSPORTCURRENTLY_IDLE);
   if (rxBufferIndex)
   {
      *numberOfBytesLong = numberOfBytesRead;
      memcpy(bufferPtr, rxBuffPtr, numberOfBytesRead);
      return(TRUE);
   }
   return (FALSE);   // no data avail yet
} // Recieve

// -------------------------------------- Poll ------------------------------
// The main simulator thread loop
//
void CRS232Port::Poll(CHAR * debugStr)
{
DWORD numBytes;
CHAR buffer[MAX_MODBUS_MESSAGELEN];
CHAR debugMsg[80];
BOOL discard;

   while (keepPolling)  // check to see if we must quit this loop
   {
      discard = FALSE;

      UpdateModemStatus();
      if ((! m_masterHasWork) && (Recieve(&numBytes, buffer, debugMsg)) )
      {
         // test to see if they want this thread to die.
         if (!keepPolling)
            break;
         //CMODMessage msg(buffer, numBytes);
         //if (msg.CRCOK())
         //{
            // build a response etc
            OnProcessData(buffer, numBytes, &discard);   //
         //}
      }
      else
      {
         m_masterHasWork = FALSE;
         if (! OnProcessData(buffer, 0 , &discard))
            Sleep(10);  // allow this thread some "space" when it is not doing anything
                        // only needed at times when the port is not available.
      }
      if (discard)
         rxBufferIndex = 0;
   }
   OutputDebugString("Poll loop exiting\n");
} // Poll



⌨️ 快捷键说明

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