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

📄 bcb_n9.htm

📁 C++Builder教学大全
💻 HTM
📖 第 1 页 / 共 2 页
字号:
 

<html>

<head>

<title>用BuilderC++如何对串行口COM1或COM2进行读写操作</title>

<meta http-equiv="目录类型" content="文本/html; 字符集=gb2312">

</head>

<body bgcolor="#FFFFFF">

<table width="100%" border="0" height="285">

  <tr> 

    <td height="35"> 

      <div align="center" class="p14"><font color="#000000">用Builder C++如何对串行口COM1或COM2进行读写操作</font></div> 

    </td> 

  </tr> 

  <tr valign="top">  

    <td>一个通讯类(对串口的读写),可以不用做修改就用在程序中 <br> 

      <br> 

      TSerialPort.h <br> 

      <br> 

      #ifndef __SERIALPORT_H__ <br> 

      #define __SERIALPORT_H__ <br> 

      <br> 

      #define WM_COMM_BREAK_DETECTED WM_USER+1 // A break was detected on input.  

      <br> 

      #define WM_COMM_CTS_DETECTED WM_USER+2 // The CTS (clear-to-sennd) sig <br> 

      nal changed state. <br> 

      #define WM_COMM_DSR_DETECTED WM_USER+3 // The DSR (data-set-reaady) si <br> 

      gnal changed state. <br> 

      #define WM_COMM_ERR_DETECTED WM_USER+4 // A line-status error ooccurre <br> 

      d. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY. <br> 

      <br> 

      #define WM_COMM_RING_DETECTED WM_USER+5 // A ring indicator was etec ted.  

      <br> 

      #define WM_COMM_RLSD_DETECTED WM_USER+6 // The RLSD (receive-lin <br> 

      -sig <br> 

      nal-detect) signal changed state. <br> 

      #define WM_COMM_RXCHAR WM_USER+7 // A character w <br> 

      s received and pl <br> 

      aced in the input buffer. <br> 

      #define WM_COMM_RXFLAG_DETECTED WM_USER+8 // The event character w <br> 

      s <br> 

      received and placed in the input buffer. <br> 

      #define WM_COMM_TXEMPTY_DETECTED WM_USER+9 // The last character in <br> 

      th <br> 

      e output buffer was sent. <br> 

      <br> 

      class TSerialPort <br> 

      { <br> 

      public: <br> 

      // contruction and destruction <br> 

      TSerialPort(); <br> 

      virtual ~TSerialPort(); <br> 

      <br> 

      // port initialisation <br> 

      BOOL InitPort(TForm* pPortOwner, UINT portnr = 1, UINT baud = <br> 

      19200, <br> 

      char parity = 'N', UINT databits = 8, UINT stopsbits = 1, DWORD dwCom <br> 

      mEvents = EV_RXCHAR | EV_CTS, UINT nBufferSize = 512); <br> 

      <br> 

      // start/stop comm watching <br> 

      BOOL StartMonitoring(); <br> 

      BOOL RestartMonitoring(); <br> 

      BOOL StopMonitoring(); <br> 

      <br> 

      DWORD GetWriteBufferSize(); <br> 

      DWORD GetCommEvents(); <br> 

      DCB GetDCB(); <br> 

      <br> 

      void WriteToPort(char* string); <br> 

      <br> 

      protected: <br> 

      // protected memberfunctions <br> 

      void ProcessErrorMessage(char* ErrorText); <br> 

      static DWORD _stdcall CommThread(LPVOID pParam); <br> 

      static void ReceiveChar(TSerialPort* port, COMSTAT comstat); <br> 

      static void WriteChar(TSerialPort* port); <br> 

      <br> 

      // thread <br> 

      HANDLE m_HThread; <br> 

      <br> 

      // synchronisation objects <br> 

      CRITICAL_SECTION m_csCommunicationSync; <br> 

      BOOL m_bThreadAlive; <br> 

      <br> 

      // handles <br> 

      HANDLE m_hShutdownEvent; <br> 

      HANDLE m_hComm; <br> 

      HANDLE m_hWriteEvent; <br> 

      <br> 

      // Event array. <br> 

      // One element is used for each event. There are two event handles fo <br> 

      r each port. <br> 

      // A Write event and a receive character event which is located in th <br> 

      e overlapped structure (m_ov.hEvent). <br> 

      // There is a general shutdown when the port is closed. <br> 

      HANDLE m_hEventArray[3]; <br> 

      <br> 

      // structures <br> 

      OVERLAPPED m_ov; <br> 

      COMMTIMEOUTS m_CommTimeouts; <br> 

      DCB m_dcb; <br> 

      <br> 

      // owner window <br> 

      TForm* m_pOwner; <br> 

      <br> 

      // misc <br> 

      UINT m_nPortNr; <br> 

      char* m_szWriteBuffer; <br> 

      DWORD m_dwCommEvents; <br> 

      DWORD m_nWriteBufferSize; <br> 

      }; <br> 

      <br> 

      #endif __SERIALPORT_H__ <br> 

      <br> 

      <br> 

      TSerialPort.cpp <br> 

      <br> 

      #include <br> 

      #pragma hdrstop <br> 

      #include "SerialPort.h" <br> 

      #include <br> 

      #include <br> 

      #pragma package(smart_init) <br> 

      // <br> 

      // Constructor <br> 

      // <br> 

      TSerialPort::TSerialPort() <br> 

      { <br> 

      m_hComm = NULL; <br> 

      <br> 

      // initialize overlapped structure members to zero <br> 

      m_ov.Offset = 0; <br> 

      m_ov.OffsetHigh = 0; <br> 

      <br> 

      // create events <br> 

      m_ov.hEvent = NULL; <br> 

      m_hWriteEvent = NULL; <br> 

      m_hShutdownEvent = NULL; <br> 

      <br> 

      m_szWriteBuffer = NULL; <br> 

      <br> 

      m_bThreadAlive = false; <br> 

      } <br> 

      <br> 

      // <br> 

      // Delete dynamic memory <br> 

      // <br> 

      TSerialPort::~TSerialPort() <br> 

      { <br> 

      do <br> 

      { <br> 

      SetEvent(m_hShutdownEvent); <br> 

      } while (m_bThreadAlive); <br> 

      <br> 

      delete [] m_szWriteBuffer; <br> 

      } <br> 

      <br> 

      // <br> 

      // Initialize the port. This can be port 1 to 4. <br> 

      // <br> 

      BOOL TSerialPort::InitPort(TForm* pPortOwner, // the owner (CWnd) of t <br> 

      he port (receives message) <br> 

      UINT portnr, <br> 

      / portnumber (1..4) <br> 

      UINT baud, <br> 

      / baudrate <br> 

      char parity, <br> 

      / parity <br> 

      UINT databits, <br> 

      / databits <br> 

      UINT stopbits, <br> 

      / stopbits <br> 

      DWORD dwCommEvents, // EV_RX <br> 

      HAR, EV_CTS etc <br> 

      UINT writebuffersize) <br> 

      / size to the writebuffer <br> 

      { <br> 

      assert(portnr &gt; 0 &amp;&amp; portnr &lt; 5); <br> 

      assert(pPortOwner != NULL); <br> 

      <br> 

      // if the thread is alive: Kill <br> 

      if (m_bThreadAlive) <br> 

      { <br> 

      do <br> 

      { <br> 

      SetEvent(m_hShutdownEvent); <br> 

      } while (m_bThreadAlive); <br> 

      } <br> 

      <br> 

      // create events <br> 

      if (m_ov.hEvent != NULL) <br> 

      ResetEvent(m_ov.hEvent); <br> 

      m_ov.hEvent = CreateEvent(NULL, true, false, NULL); <br> 

      <br> 

      if (m_hWriteEvent != NULL) <br> 

      ResetEvent(m_hWriteEvent); <br> 

      m_hWriteEvent = CreateEvent(NULL, true, false, NULL); <br> 

      <br> 

      if (m_hShutdownEvent != NULL) <br> 

      ResetEvent(m_hShutdownEvent); <br> 

      m_hShutdownEvent = CreateEvent(NULL, true, false, NULL); <br> 

      <br> 

      // initialize the event objects <br> 

      m_hEventArray[0] = m_hShutdownEvent; // highest priority <br> 

      m_hEventArray[1] = m_ov.hEvent; <br> 

      m_hEventArray[2] = m_hWriteEvent; <br> 

      <br> 

      // initialize critical section <br> 

      InitializeCriticalSection(&amp;m_csCommunicationSync); <br> 

      <br> 

      // set buffersize for writing and save the owner <br> 

      m_pOwner = pPortOwner; <br> 

      <br> 

      if (m_szWriteBuffer != NULL) <br> 

      delete [] m_szWriteBuffer; <br> 

      m_szWriteBuffer = new char[writebuffersize]; <br> 

      <br> 

      m_nPortNr = portnr; <br> 

      <br> 

      m_nWriteBufferSize = writebuffersize; <br> 

      m_dwCommEvents = dwCommEvents; <br> 

      <br> 

      BOOL bResult = false; <br> 

      char *szPort = new char[50]; <br> 

      char *szBaud = new char[50]; <br> 

      <br> 

      // now it critical! <br> 

      EnterCriticalSection(&amp;m_csCommunicationSync); <br> 

      <br> 

      // if the port is already opened: close it <br> 

      if (m_hComm != NULL) <br> 

      { <br> 

      CloseHandle(m_hComm); <br> 

      m_hComm = NULL; <br> 

      } <br> 

      <br> 

      // prepare port strings <br> 

      sprintf(szPort, "COM%d", portnr); <br> 

      sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, da <br> 

      tabits, stopbits); <br> 

      <br> 

      // get a handle to the port <br> 

      m_hComm = CreateFile(szPort, <br> 

      / communication port string (COMX) <br> 

      <br> 

      GENERIC_READ | GENERIC_WRITE, <br> 

      / read/write types <br> 

      0, <br> 

      / comm devices must be opened with exclusive acce <br> 

      ss <br> 

      ss <br> 

      NULL, <br> 

      / no security attributes <br> 

      OPEN_EXISTING, <br> 

      / comm devices must use OPEN_EXISTING <br> 

      FILE_FLAG_OVERLAPPED, <br> 

      / Async I/O <br> 

      0); <br> 

      / template must be 0 for comm devices <br> 

      <br> 

      if (m_hComm == INVALID_HANDLE_VALUE) <br> 

      { <br> 

      // port not found <br> 

      delete [] szPort; <br> 

      delete [] szBaud; <br> 

      <br> 

      return false; <br> 

      } <br> 

      <br> 

      // set the timeout values <br> 

      m_CommTimeouts.ReadIntervalTimeout = 1000; <br> 

      m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000; <br> 

      m_CommTimeouts.ReadTotalTimeoutConstant = 1000; <br> 

      m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000; <br> 

      m_CommTimeouts.WriteTotalTimeoutConstant = 1000; <br> 

      <br> 

      // configure <br> 

      if (SetCommTimeouts(m_hComm, &amp;m_CommTimeouts)) <br> 

      { <br> 

      if (SetCommMask(m_hComm, dwCommEvents)) <br> 

      { <br> 

      if (GetCommState(m_hComm, &amp;m_dcb)) <br> 

      { <br> 

      m_dcb.fRtsControl = RTS_CONTROL_ENABLE; <br> 

      / set RTS bit high! <br> 

      if (BuildCommDCB(szBaud, &amp;m_dcb)) <br> 

      { <br> 

      if (SetCommState(m_hComm, &amp;m_dcb)) <br> 

      ; // normal operation... continu <br> 

      <br> 

      else <br> 

      ProcessErrorMessage("SetCommStat <br> 

      ()"); <br> 

      } <br> 

      else <br> 

      ProcessErrorMessage("BuildCommDCB()"); <br> 

      } <br> 

      else <br> 

      ProcessErrorMessage("GetCommState()"); <br> 

      } <br> 

      else <br> 

      ProcessErrorMessage("SetCommMask()"); <br> 

      } <br> 

      else <br> 

      ProcessErrorMessage("SetCommTimeouts()"); <br> 

      <br> 

      delete [] szPort; <br> 

      delete [] szBaud; <br> 

      <br> 

      // flush the port <br> 

      PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PU <br> 

      RGE_TXABORT); <br> 

      <br> 

      // release critical section <br> 

      LeaveCriticalSection(&amp;m_csCommunicationSync); <br> 

      <br> 

      return true; <br> 

      } <br> 

      <br> 

      // <br> 

      // The CommThread Function. <br> 

      // <br> 

      DWORD _stdcall TSerialPort::CommThread(LPVOID pParam) <br> 

      { <br> 

      // Cast the void pointer passed to the thread back to <br> 

      // a pointer of TSerialPort class <br> 

      TSerialPort *port = (TSerialPort*)pParam; <br> 

      <br> 

      // Set the status variable in the dialog class to <br> 

      // TRUE to indicate the thread is running. <br> 

      port-&gt;m_bThreadAlive = true; <br> 

      <br> 

      // Misc. variables <br> 

      DWORD BytesTransfered = 0; <br> 

      DWORD Event = 0; <br> 

      DWORD CommEvent = 0; <br> 

      DWORD dwError = 0; <br> 

      COMSTAT comstat; <br> 

      BOOL bResult = true; <br> 

      <br> 

      // Clear comm buffers at startup <br> 

      if (port-&gt;m_hComm) // check if the port is opened <br> 

      PurgeComm(port-&gt;m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_R <br> 

      ABO <br> 

      RT | PURGE_TXABORT); <br> 

      <br> 

      // begin forever loop. This loop will run as long as the thread is a <br> 

      live. <br> 

      for (;;) <br> 

      { <br> 

      <br> 

      // Make a call to WaitCommEvent(). This call will return immedi <br> 

      tly <br> 

      <br> 

      // because our port was created as an async port (FILE_FLAG_OVER <br> 

      APP <br> 

      ED <br> 

      // and an m_OverlappedStructerlapped structure specified). This <br> 

      cal <br> 

      l will cause the <br> 

      // m_OverlappedStructerlapped element m_OverlappedStruct.hEvent, <br> 

      whi <br> 

      ch is part of the m_hEventArray to <br> 

      // be placed in a non-signeled state if there are no bytes avail <br> 

      ble <br> 

      to be read, <br> 

      // or to a signeled state if there are bytes available. If this <br> 

      eve <br> 

      nt handle <br> 

      // is set to the non-signeled state, it will be set to signeled <br> 

      hen <br> 

      a <br> 

      // character arrives at the port. <br> 

      <br> 

      // we do this for each port! <br> 

      <br> 

      bResult = WaitCommEvent(port-&gt;m_hComm, &amp;Event, &amp;port-&gt;m_ov);  

      <br> 

      <br> 

      if (!bResult) <br> 

      { <br> 

      // If WaitCommEvent() returns FALSE, process the last er <br> 

      or to dete <br> 

      rmin <br> 

      rmin <br> 

      // the reason.. <br> 

      switch (dwError = GetLastError()) <br> 

      { <br> 

      case ERROR_IO_PENDING: <br> 

      { <br> 

      // This is a normal return value if ther <br> 

      are no bytes <br> 

      // to read at the port. <br> 

      // Do nothing and continue <br> 

      break; <br> 

      } <br> 

      case 87: <br> 

      { <br> 

      // Under Windows NT, this value is retur <br> 

      ed for some reason. <br> 

      // I have not investigated why, but it i <br> 

      also a valid reply <br> 

      // Also do nothing and continue. <br> 

      break; <br> 

      } <br> 

      default: <br> 

      { <br> 

      // All other error codes indicate a seri <br> 

      us error has <br> 

      // occured. Process this error. <br> 

      port-&gt;ProcessErrorMessage("WaitCommEvent <br> 

      )"); <br> 

      break; <br> 

      } <br> 

      } <br> 

      } <br> 

      else <br> 

      { <br> 

      // If WaitCommEvent() returns TRUE, check to be sure the <br> 

      e are <br> 

      // actually bytes in the buffer to read. <br> 

      // <br> 

      // If you are reading more than one byte at a time from <br> 

      he buffer <br> 

      <br> 

      // (which this program does not do) you will have the si <br> 

      uation occ <br> 

      ur <br> 

      // where the first byte to arrive will cause the WaitFor <br> 

      ultipleObj <br> 

      ects() <br> 

      // function to stop waiting. The WaitForMultipleObjects <br> 

      ) function <br> 

      <br> 

      // resets the event handle in m_OverlappedStruct.hEvent <br> 

      o the non- <br> 

      signelead state <br> 

      // as it returns. <br> 

      // <br> 

      // If in the time between the reset of this event and th <br> 

      call to <br> 

      // ReadFile() more bytes arrive, the m_OverlappedStruct. <br> 

      Event hand <br> 

      le will be set again <br> 

      // to the signeled state. When the call to ReadFile() oc <br> 

      urs, it wi <br> 

      ll <br> 

      // read all of the bytes from the buffer, and the progra <br> 

      will <br> 

      // loop back around to WaitCommEvent(). <br> 

      // <br> 

      // At this point you will be in the situation where m_Ov <br> 

⌨️ 快捷键说明

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