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

📄 rs232port.cpp

📁 mod_RSsim
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////
//
// FILE: RS232Port.cpp : implementation file
//
// See _README.CPP
//
// Implementation of the CRS232Port class.
// Requires MFC headder <afxmt.h>
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "RS232Port.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


// ------------------------------ AsyncFriend ------------------------------
// Worker thread function, this is a friend of the CRS232Port class
//
UINT AsyncFriend(LPVOID pParam)
{
CHAR     debugStr2[MAX_DEBUG_STR_LEN];
CHAR     debugStr[MAX_DEBUG_STR_LEN];
CRS232Port* portPtr;

   portPtr = (CRS232Port*)pParam;
   try 
   { 
		
      // call the function the thread will run in
      if (portPtr->IsKindOf(RUNTIME_CLASS( CRS232Port)))
      {
         // wait untill the Application is ready for us
         CSingleLock lk(&portPtr->m_threadStartupEvent);
         lk.Lock(5000); // wait max 5 seconds

         portPtr->RSStateChanged(RSPORTCURRENTLY_VOID);
         
         // stays in a loop at this point
         portPtr->Poll(debugStr);
      }
      else
      {
         sprintf(debugStr2, "CRS232Port AsyncFriend pointer corruption!!!!\n");
         OutputDebugString(debugStr2);
      }
   }
   catch (...) 
   {
      CString msg;
         msg.Format("INTERNAL APPLICATION ERROR FILE %s LINE: %d\n%s\n%s", 
            __FILE__, __LINE__, __MY_APPVERSION__, __DATE__);
      OutputDebugString(msg);

      portPtr->RSDataMessage(msg);
      //OutputDebugString( "Catch\n" );
      //sprintf(debugStr2, "CRS232Port AsyncFriend Exception !!!!\n");
      //OutputDebugString(debugStr2);
   }
   portPtr->m_listenThreadStatus = RS232_EX_TERMINATED;
   {
   CString d;
      d.Format("[Comms thread %4d Terminating.]\n", GetCurrentThreadId());
      OutputDebugString(d);
   }
   portPtr->m_threadDeadEvent.SetEvent();// CEvent
   OutputDebugString("Port object thread returning to System\n");
   
   //AfxEndThread(0);

   return(0);
} // AsyncFriend


char commsParityStr[] = "NOEMS";   //NOPARITY ODDPARITY EVENPARITY MARKPARITY SPACEPARITY
char commsStopStr[][4] = {// ONESTOPBIT ONE5STOPBITS TWOSTOPBITS
   "1",
   "1.5",
   "2"
};

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC( CRS232Port, CObject);

CRS232Port::CRS232Port()
{
   m_debuggerStep = 0;
   m_masterHasWork = FALSE;

   h232Port = INVALID_HANDLE_VALUE;
   m_lastModemStatus = 0xFFFF;

   // create the listening thread
   m_listenThreadStatus = RS232_EX_PENDING;
   m_pWorkerThread      = AfxBeginThread((AFX_THREADPROC)AsyncFriend,
                                     this,
                                     THREAD_PRIORITY_TIME_CRITICAL, 0,
                                     CREATE_SUSPENDED
                                    );

   rxBufferIndex = 0;   // set up our RX buffer
   memset(rxBuffer, 0 , sizeof(rxBuffer));
   keepPolling = TRUE;
   m_lastCharIncommingtime = GetTickCount() + PORT_MAX_IDLETIME*5;
   InitializeCriticalSection(&critSec);
}

CRS232Port::~CRS232Port()
{
   ClosePort();
   // caller must wait for thread to die, if not already dead
   OutputDebugString("Port object deleted\n");
   TerminateThread(m_pWorkerThread,0);
}

#ifdef _DEBUG
VOID CRS232Port::Dump(CDumpContext& dc) const
{
   // call the base class first
   CObject::Dump(dc);

   // dump our object to the debuggers output
   // all important members can be dumped at this stage.
   dc << "RS232 Port: " << "\n";
} // Dump
#endif // _DEBUG

// ------------------------- RSStateChanged ----------------------------
void CRS232Port::RSStateChanged(DWORD state)
{
   // do nothing in the base class
} // RSStateChanged
/*
// ------------------------- RSDataDebugger ----------------------------
void CRS232Port::RSDataDebugger(const BYTE * buffer, LONG length, BOOL transmit)
{
CString prefix, ASCIIdata;
LONG index, i;
   if (transmit)
      prefix = "TX:";
   else
      prefix = "RX:";
   index = 0;
   while (index < length)
   {
      i=0;
      OutputDebugString("\n");
      OutputDebugString(prefix);
      while ((index+i < length)&&(i<8))
      {
         ASCIIdata.Format("%02X", buffer[index+i]);
         OutputDebugString(ASCIIdata);
         i++;
      }
      index +=8;
   }
} // RSDataDebugger
  */
// --------------------------------- OpenPort ---------------------------
BOOL CRS232Port::OpenPort(LPCTSTR oPortName)
{
CHAR longPortName[MAX_PORT_NAME];
BOOL  error;
CString msg;

   portNameS = oPortName;
   GetLongComPortName(portNameS, longPortName);  // get windows port name in long format   
   // for COM ports >COM9 Windows uses a different naming format, hence this 
   // little catch and we have to be compatible.

   portName = longPortName;
   h232Port =  CreateFile( portName,                    // PIP 1823-400-1997
                               GENERIC_READ | GENERIC_WRITE,
                               (DWORD)NULL,   // exclusive access
                               NULL,          // no security
                               OPEN_EXISTING,
                               FILE_ATTRIBUTE_NORMAL,
                               NULL           // hTemplate
                             );
   if (INVALID_HANDLE_VALUE ==h232Port)
   {
      AfxMessageBox("Error: Could not open the RS232 port!", MB_OK|MB_ICONEXCLAMATION);
      return FALSE;
   }

   msg.Format("Port %s opened.\n" , longPortName);
//   OutputDebugString(msg);
   RSDataMessage(msg);

   // set up the comms parameters now that we have a handle
   error = SetupComm(h232Port,
                     (DWORD)2048, (DWORD)2048);

   msg.Format("Port I/O buffers configured.\n");
   //OutputDebugString(msg);
   RSDataMessage(msg);
   RSStateChanged(RSPORTCURRENTLY_IDLE);

   m_lastCharIncommingtime = GetTickCount() + PORT_MAX_IDLETIME*5;
   return (TRUE);
} // OpenPort

void CRS232Port::OnHWError(DWORD dwCommError)
{
   // do nothing
}


// ----------------------- ReConfigurePort ------------------------------
//
BOOL CRS232Port::ReConfigurePort()
{
   return (ConfigurePort(dcb.BaudRate, dcb.ByteSize, dcb.Parity, dcb.fRtsControl, (NOPARITY==dcb.Parity?FALSE:TRUE)));
}

// ---------------------------------- ConfigurePort ---------------------
//
BOOL CRS232Port::ConfigurePort(DWORD  baud, 
                               DWORD byteSize, 
                               DWORD parity, 
                               DWORD stopBits,
                               DWORD rts,
                               DWORD checkParity)
{
BOOL error;
COMMTIMEOUTS timeout;

   if (INVALID_HANDLE_VALUE==h232Port)
   {
   CString errMsg("Error: Could not set up RS232 port. Port not open!");

      RSDataMessage(errMsg);
      AfxMessageBox(errMsg, MB_OK|MB_ICONEXCLAMATION);
      return FALSE;
   }
   
   m_lastModemStatus = 0xFFFF;

   // Set up the DCB with our settings
   // Get it first so we fill all members
   error = GetCommState(h232Port,
                           &dcb);
   dcb.BaudRate = baud;
   dcb.ByteSize = (BYTE)byteSize;
   dcb.Parity = (BYTE)parity;
   dcb.fParity = checkParity;
   dcb.StopBits = (BYTE)stopBits;

   // set the default parameters
   dcb.fOutxDsrFlow = FALSE;
//   ASSERT(0);
   dcb.fDsrSensitivity = FALSE;   // SCM22 appears to be DSR sensing = TRUE;//
   dcb.fOutxCtsFlow = FALSE; // TRUE;

   // set the port for hardware handshaking
   dcb.fRtsControl = rts;
   dcb.fDtrControl = DTR_CONTROL_ENABLE; //DTR_CONTROL_HANDSHAKE;   was DTR_CONTROL_DISABLE;//
   dcb.fAbortOnError = TRUE;
   dcb.fBinary = TRUE;
   dcb.fTXContinueOnXoff  = FALSE;
   dcb.fOutX = FALSE;
   dcb.fInX = FALSE;
   dcb.fErrorChar = 0;
   dcb.fNull = 0;
   dcb.fDummy2 = 0;

   // assign it
   error = SetCommState(h232Port,
                           &dcb);
   CString paramsSet;
   if (!error)
   {
   CHAR  errorMsg[MAX_ERROR_STR_LEN];
   CHAR *errorMsgPtr = errorMsg;
   DWORD ntError = GetLastError();

      // call the API using the default system language
      errorMsg[0] = '\0';
      FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 
                    NULL,                    // ignored, search the system only
                    ntError,                 // error code passed in
                    GetSystemDefaultLangID(),// English ,English US
                    errorMsg,                // message buffer
                    sizeof(errorMsg),        // length
                    NULL);                   // optional parameter list
      // 
      while(*errorMsgPtr)                    // Find any '\r' and replace with ' '
      {
         errorMsgPtr++;
         if (( *errorMsgPtr == '\r') | ( *errorMsgPtr == '\n'))
            *errorMsgPtr = ' ';  
      }
      paramsSet.Format("Error configuring port for %d,%d,%c,%s : (error %d) - %s", 
                                                      baud, 
                                                      byteSize,
                                                      commsParityStr[parity], 
                                                      commsStopStr[stopBits],
                                                      ntError,
                                                      errorMsg);
      RSDataMessage(paramsSet);
      AfxMessageBox( paramsSet, MB_OK | MB_ICONEXCLAMATION);
      ClosePort();
      return FALSE;
   }
   else
   {
      paramsSet.Format("Port configured %d,%d,%c,%s", baud, 
                                                      byteSize,
                                                      commsParityStr[parity], 
                                                      commsStopStr[stopBits]);
      RSDataMessage(paramsSet);
   }


   // Set up the timeouts to use, they are quite short, since we will loop anyway.
   // Do not make them zero, else we will have a CPU load problem. Too large a value, 
   // and we have to wait for comms to time out when shutting down

   // fill timeout structure
   GetCommTimeouts(h232Port, &timeout);
   timeout.ReadIntervalTimeout = 100;           // 500ms between incomming chars.
   timeout.ReadTotalTimeoutConstant = 500;
   timeout.ReadTotalTimeoutMultiplier = 0;      // #chars to read does not add to timeout amount

⌨️ 快捷键说明

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