반응형
250x250
Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

폴크(FOLC)

MFC 테크닉 - 시리얼 통신 ( RS232 ) 본문

C, C++, MFC/C, C++, MFC 테크닉

MFC 테크닉 - 시리얼 통신 ( RS232 )

folcjin 2021. 12. 14. 21:43
728x90
반응형

# 통신 채널이나 컴퓨터 버스를 거쳐 하나의 비트 단위로 연속적으로 데이터를 전송하는 과정
   > 시간으로 나누어 차례대로 전송
   > 전송 방식은 동기/비동기 방식으로 나뉜다.
      - 동기 방식 : 데이터 신호와는 별도로 동기신호를 보낸다.
      - 비동기 방식 : 데이터 신호만 보내고 각각의 방식에 따라 데이터 비트를 찾는다.

# 소스 코드
bool CRS232Serial::OpenPort(CString strPort)
{
   m_osRead.Offset = 0;
   m_osRead.OffsetHigh = 0;
   m_osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
   if (m_osRead.hEvent == NULL) return false;
   
   m_osWrite.Offset = 0;
   m_osWrite.OffsetHigh = 0;
   m_osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
   if (m_osWrite.hEvent == NULL) return false;

   // Serial Port가 2자리 이상이면 포트 번호 앞에 "\\\\.\\"를 붙여준다.
   if (9 < strPort.GetLength()) strPort.Format(_T("\\\\.\\%s"), strPort.GetString());
   m_hComm = CreateFile(strPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
   if (m_hComm == INVALID_HANDLE_VALUE)
   {
     CloseHandle(m_hComm);
     m_hComm = nullptr;
     return false;
   }

   SetCommMask(m_hComm, EV_RXCHAR);
   SetupComm(m_hComm, QUEUE_BUFF_SIZE, QUEUE_BUFF_SIZE);
   PurgeComm(m_hComm, PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR);
   COMMTIMEOUTS timeouts;
   timeouts.ReadIntervalTimeout = 0xFFFFFFFF;
   timeouts.ReadTotalTimeoutMultiplier = 0;
   timeouts.ReadTotalTimeoutConstant = 0;
   timeouts.WriteTotalTimeoutMultiplier = 2 * CBR_9600 / _ttoi(m_pConfig->GetParam_BaudRate());
   timeouts.WriteTotalTimeoutConstant = 0;
   SetCommTimeouts(m_hComm, &timeouts);

   DCB dcb;
   dcb.DCBlength = sizeof(DCB);
   GetCommState(m_hComm, &dcb);
   dcb.BaudRate = _ttoi(m_pConfig->GetParam_BaudRate());
   dcb.ByteSize = _ttoi(m_pConfig->GetParam_DataBits());
   dcb.Parity = m_pConfig->GetSerialStringToValue(m_pConfig->GetParam_Parity());
   dcb.StopBits = m_pConfig->GetSerialStringToValue(m_pConfig->GetParam_StopBits());
   if (SetCommState(m_hComm, &dcb) == FALSE)
   {
     CloseHandle(m_hComm);
     m_hComm = nullptr;
     CloseHandle(m_osRead.hEvent);
     CloseHandle(m_osWrite.hEvent);
     return false;
   }
   Initialize();
   return true;
}

void CRS232Serial::ClosePort()
{
   SetCommMask(m_hComm, 0);
   PurgeComm(m_hComm, PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR);
   if (CloseHandle(m_hComm) == FALSE)
   {
     return;
   }
   CloseHandle(m_osRead.hEvent);
   CloseHandle(m_osWrite.hEvent);
   m_hComm = nullptr;
}

DWORD CRS232Serial::WriteComm(CStringA strData)
{
   BYTE WriteBuff[COMM_BUFF_SIZE] = { 0, };
   memset(WriteBuff, 0, COMM_BUFF_SIZE);
   memcpy(WriteBuff, strData.GetString(), strData.GetLength());
   DWORD dwWritten, dwErrorFlags;
   COMSTAT comstat;
   if (WriteFile(m_hComm, (BYTE *)WriteBuff, dwToWrite, &dwWritten, &m_osWrite) == FALSE)
   {
     DWORD dwError = GetLastError();
      if (dwError == ERROR_IO_PENDING)
      {
         while (GetOverlappedResult(m_hComm, &m_osWrite, &dwWritten, TRUE) == FALSE)
         {
            dwError = GetLastError();
            if (dwError != ERROR_IO_INCOMPLETE)

            {
               ClearCommError(m_hComm, &dwErrorFlags, &comstat);
               break;
            }
         }
      }
      else
      {
         dwWritten = 0;
         ClearCommError(m_hComm, &dwErrorFlags, &comstat);
      }
   }
   return dwWritten;
}

DWORD CRS232Serial::ReadComm(BYTE *pBuff, DWORD dwToRead)
{
   DWORD dwErrorFlags;
   COMSTAT comstat;
   ClearCommError(m_hComm, &dwErrorFlags, &comstat);
   DWORD dwRead = comstat.cbInQue;
   if (0 < dwRead)
   {
      if (ReadFile(m_hComm, pBuff, dwToRead, &dwRead, &m_osRead) == FALSE)
      {
         DWORD dwError = GetLastError();
         if (dwError == ERROR_IO_PENDING)
         {
            while (GetOverlappedResult(m_hComm, &m_osRead, &dwRead, TRUE) == FALSE)
            {
               dwError = GetLastError();
               if (dwError != ERROR_IO_INCOMPLETE)
               {
                  ClearCommError(m_hComm, &dwErrorFlags, &comstat);
                  break;
               }
            }
         }
         else
         {
            dwRead = 0;
            ClearCommError(m_hComm, &dwErrorFlags, &comstat);
         }
      }
   }
   return dwRead;
}

728x90
반응형
사업자 정보 표시
사업자 등록번호 : -- | TEL : --