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

📄 serialport.cpp

📁 简单的串口调试
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    case DsrDtrFlowControl:
    {
      dcb.fOutxCtsFlow = FALSE;
      dcb.fOutxDsrFlow = TRUE;
      dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
      dcb.fOutX = FALSE;
      dcb.fInX = FALSE;
      break;
    }
    case XonXoffFlowControl:
    {
      dcb.fOutxCtsFlow = FALSE;
      dcb.fOutxDsrFlow = FALSE;
      dcb.fOutX = TRUE;
      dcb.fInX = TRUE;
      dcb.XonChar = 0x11;
      dcb.XoffChar = 0x13;
      dcb.XoffLim = 100;
      dcb.XonLim = 100;
      break;
    }
    default:
    {
      ASSERT(FALSE);
      break;
    }
  }
  
  //Now that we have all the settings in place, make the changes
  SetState(dcb);
}

void CSerialPort::Close()
{
  if (IsOpen())
  {
    //Close down the comms port
    BOOL bSuccess = CloseHandle(m_hComm);
    m_hComm = INVALID_HANDLE_VALUE;
    if (!bSuccess)
      TRACE(_T("CSerialPort::Close, Failed to close up the comms port, Error:%d\n"), GetLastError());

    //Free the event object we are using
    if (m_hEvent)
    {
      CloseHandle(m_hEvent);
      m_hEvent = NULL;
    }
  }
}

void CSerialPort::Attach(HANDLE hComm)
{
  Close();

  //Validate our parameters, now that the port has been closed
  ASSERT(m_hComm == INVALID_HANDLE_VALUE);
  ASSERT(m_hEvent == NULL);

  m_hComm = hComm;  

  //Create the event we need for later synchronisation use
  m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  if (m_hEvent == NULL)
  {
    DWORD dwLastError = GetLastError();
    Close();
    TRACE(_T("CSerialPort::Attach, Failed in call to CreateEvent in Attach, Error:%d\n"), dwLastError);
    ThrowSerialException(dwLastError);
  }
}

HANDLE CSerialPort::Detach()
{
  //What will be the return value from this function
  HANDLE hrVal = m_hComm;

  m_hComm = INVALID_HANDLE_VALUE;

  if (m_hEvent)
  {
    CloseHandle(m_hEvent);
    m_hEvent = NULL;
  }

  return hrVal;
}

DWORD CSerialPort::Read(void* lpBuf, DWORD dwCount)
{
  //Validate our parameters
  ASSERT(IsOpen());

  DWORD dwBytesRead = 0;
  if (!ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, NULL))
  {
    DWORD dwLastError = GetLastError();
    TRACE(_T("CSerialPort::Read, Failed in call to ReadFile, Error:%d\n"), dwLastError);
    ThrowSerialException(dwLastError);
  }

  return dwBytesRead;
}

BOOL CSerialPort::Read(void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped, DWORD* pBytesRead)
{
  //Validate our parameters
  ASSERT(IsOpen());

  DWORD dwBytesRead = 0;
  BOOL bSuccess = ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, &overlapped);
  if (!bSuccess)
  {
    DWORD dwLastError = GetLastError();
    if (dwLastError != ERROR_IO_PENDING)
    {
      TRACE(_T("CSerialPort::Read, Failed in call to ReadFile, Error:%d\n"), dwLastError);
      ThrowSerialException(dwLastError);
    }
  }
  else
  {
    if (pBytesRead)
      *pBytesRead = dwBytesRead;
  }
  return bSuccess;
}

DWORD CSerialPort::Write(const void* lpBuf, DWORD dwCount)
{
  //Validate our parameters
  ASSERT(IsOpen());

  DWORD dwBytesWritten = 0;
  if (!WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, NULL))
  {
    DWORD dwLastError = GetLastError();
    TRACE(_T("CSerialPort::Write, Failed in call to WriteFile, Error:%d\n"), dwLastError);
    ThrowSerialException(dwLastError);
  }

  return dwBytesWritten;
}

BOOL CSerialPort::Write(const void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped, DWORD* pBytesWritten)
{
  //Validate our parameters
  ASSERT(IsOpen());

  DWORD dwBytesWritten = 0;
  BOOL bSuccess = WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, &overlapped);
  if (!bSuccess)
  {
    DWORD dwLastError = GetLastError();
    if (dwLastError != ERROR_IO_PENDING)
    {
      TRACE(_T("CSerialPort::Write, Failed in call to WriteFile, Error:%d\n"), dwLastError);
      ThrowSerialException(dwLastError);
    }
  }
  else
  {
    if (pBytesWritten)
      *pBytesWritten = dwBytesWritten;
  }

  return bSuccess;
}

void CSerialPort::GetOverlappedResult(OVERLAPPED& overlapped, DWORD& dwBytesTransferred, BOOL bWait)
{
  //Validate our parameters
  ASSERT(IsOpen());

  if (!::GetOverlappedResult(m_hComm, &overlapped, &dwBytesTransferred, bWait))
  {
    DWORD dwLastError = GetLastError();
    if (dwLastError != ERROR_IO_INCOMPLETE)
    {
      TRACE(_T("CSerialPort::GetOverlappedResult, Failed in call to GetOverlappedResult, Error:%d\n"), dwLastError);
      ThrowSerialException(dwLastError);
    }
  }
}

void CSerialPort::_OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped)
{
  //Validate our parameters
  ASSERT(lpOverlapped);

  //Convert back to the C++ world
  CSerialPort* pSerialPort = static_cast<CSerialPort*>(lpOverlapped->hEvent);
  ASSERT(pSerialPort);

  //Call the C++ function
  pSerialPort->OnCompletion(dwErrorCode, dwCount, lpOverlapped);
}

void CSerialPort::OnCompletion(DWORD /*dwErrorCode*/, DWORD /*dwCount*/, LPOVERLAPPED lpOverlapped)
{
  //Just free the memory which was previously allocated for the OVERLAPPED structure
  delete lpOverlapped;

  //Your derived classes can do something useful in OnCompletion, but don't forget to
  //call CSerialPort::OnCompletion to ensure the memory is freed
}

void CSerialPort::CancelIo()
{
  //Validate our parameters
  ASSERT(IsOpen());

  if (m_lpfnCancelIo == NULL)
  {
    TRACE(_T("CSerialPort::CancelIo, CancelIo function is not supported on this OS. You need to be running at least NT 4 or Win 98 to use this function\n"));
    ThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED);  
  }

  if (!m_lpfnCancelIo(m_hComm))
  {
    DWORD dwLastError = GetLastError();
    TRACE(_T("Failed in call to CancelIO, Error:%d\n"), dwLastError);
    ThrowSerialException(dwLastError);
  }
}

DWORD CSerialPort::BytesWaiting()
{
  //Validate our parameters
  ASSERT(IsOpen());

  //Check to see how many characters are unread
  COMSTAT stat;
  GetStatus(stat);
  return stat.cbInQue;
}

BOOL CSerialPort::DataWaiting(DWORD dwTimeout)
{
  //Validate our parameters
  ASSERT(IsOpen());

  //Setup to wait for incoming data
  DWORD dwOldMask;
  GetMask(dwOldMask);
  SetMask(EV_RXCHAR);

  //Setup the overlapped structure
  OVERLAPPED o;
  o.hEvent = m_hEvent;

  //Assume the worst;
  BOOL bSuccess = FALSE;

  DWORD dwEvent;
  bSuccess = WaitEvent(dwEvent, o);
  if (!bSuccess)
  {
    if (WaitForSingleObject(o.hEvent, dwTimeout) == WAIT_OBJECT_0)
    {
      DWORD dwBytesTransferred;
      GetOverlappedResult(o, dwBytesTransferred, FALSE);
      bSuccess = TRUE;
    }
  }

  //Reset the event mask
  SetMask(dwOldMask);

  return bSuccess;
}

void CSerialPort::WriteEx(const void* lpBuf, DWORD dwCount)
{
  //Validate our parameters
  ASSERT(IsOpen());

  OVERLAPPED* pOverlapped = new OVERLAPPED;
  memset(pOverlapped, 0, sizeof(OVERLAPPED));
  pOverlapped->hEvent = static_cast<HANDLE>(this);
  if (!WriteFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
  {
    DWORD dwLastError = GetLastError();
    delete pOverlapped;
    TRACE(_T("CSerialPort::WriteEx, Failed in call to WriteFileEx, Error:%d\n"), dwLastError);
    ThrowSerialException(dwLastError);
  }
}

void CSerialPort::ReadEx(void* lpBuf, DWORD dwCount)
{
  //Validate our parameters
  ASSERT(IsOpen());

  OVERLAPPED* pOverlapped = new OVERLAPPED;
  memset(pOverlapped, 0, sizeof(OVERLAPPED));
  pOverlapped->hEvent = static_cast<HANDLE>(this);
  if (!ReadFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
  {
    DWORD dwLastError = GetLastError();
    delete pOverlapped;
    TRACE(_T("CSerialPort::ReadEx, Failed in call to ReadFileEx, Error:%d\n"), dwLastError);
    ThrowSerialException(dwLastError);
  }
}

void CSerialPort::TransmitChar(char cChar)
{
  //Validate our parameters
  ASSERT(IsOpen());

  if (!TransmitCommChar(m_hComm, cChar))
  {
    DWORD dwLastError = GetLastError();
    TRACE(_T("CSerialPort::TransmitChar, Failed in call to TransmitCommChar, Error:%d\n"), dwLastError);
    ThrowSerialException(dwLastError);
  }
}

void CSerialPort::GetConfig(COMMCONFIG& config)
{
  //Validate our parameters
  ASSERT(IsOpen());

  DWORD dwSize = sizeof(COMMCONFIG);
  if (!GetCommConfig(m_hComm, &config, &dwSize))
  {
    DWORD dwLastError = GetLastError();
    TRACE(_T("CSerialPort::GetConfig, Failed in call to GetCommConfig, Error:%d\n"), dwLastError);
    ThrowSerialException(dwLastError);
  }
}

void CSerialPort::SetConfig(COMMCONFIG& config)
{
  //Validate our parameters
  ASSERT(IsOpen());

  DWORD dwSize = sizeof(COMMCONFIG);
  if (!SetCommConfig(m_hComm, &config, dwSize))
  {
    DWORD dwLastError = GetLastError();
    TRACE(_T("CSerialPort::SetConfig, Failed in call to SetCommConfig, Error:%d\n"), dwLastError);
    ThrowSerialException(dwLastError);
  }
}

void CSerialPort::SetBreak()

⌨️ 快捷键说明

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