본문 바로가기
#컴퓨터 과학 [Computer Science]/C/C++

[C/C++] 시리얼 통신 (Serial Communication)

by cy_mos 2019. 9. 4.
반응형

[C/C++] 시리얼 통신 (Serial Communication)

 

  • In telecommunication and data transmission, serial communication is the process of sending data one bit at a time, sequentially, over a communication channel or computer bus. This is in contrast to parallel communication, where several bits are sent as a whole, on a link with several parallel channels.

    Serial communication is used for all long-haul communication and most computer networks, where the cost of cable and synchronization difficulties make parallel communication impractical. Serial computer buses are becoming more common even at shorter distances, as improved signal integrity and transmission speeds in newer serial technologies have begun to outweigh the parallel bus's advantage of simplicity (no need for serializer and deserializer, or SerDes) and to outstrip its disadvantages (clock skew, interconnect density). The migration from PCI to PCI Express is an example.

  • 전기 통신과 컴퓨터 과학 분야에서 직렬 통신(Serial Bus,시리얼버스)은 연속적으로 통신 채널이나 컴퓨터 버스를 거쳐 한 번에 하나의 비트 단위로 데이터를 전송하는 과정을 말한다. 이 용어는 여러 개의 병렬 채널을 갖춘 링크 위에서 동시에 여러 개의 비트를 보내는 병렬 통신과 대조된다.

    컴퓨터에서 데이터 처리가 병렬로 되는데, 통신을 위해 병렬 통신을 하려면 여러개의 채널이 필요하다. 거리와 비용을 고려하면 많을 경우 병렬 통신은 문제가 될 수 있다. 결국 병렬로 처리되는 데이터를 통신할 때 시간으로 나누어 차례대로 전송함으로써 문제를 해결할 수 있다.

    직렬 통신에서 데이터가 계속되어 전송되면, 각 비트를 구별할 방법이 필요하다. 디지털 회로의 입장에서 수신된 데이터의 비트가 시간적으로 어디서 부터 시작이고 끝인지를 알 필요가 있다. 이렇게 데이터 비트를 복구하기 위해 데이터의 시간적 위치를 알리기 위해 동기신호를 보내는 경우와 동기 신호 없이 신호 자체에서 데이터 비트를 복원하는 방식으로 나눌 수 있다.


🔍 시리얼 통신 순서 (Serial Communication Logic)

1️⃣ CreateFile

Creates or opens a file or I/O device. The most commonly used I/O devices are as follows: file, file stream, directory, physical disk, volume, console buffer, tape drive, communications resource, mailslot, and pipe. The function returns a handle that can be used to access the file or device for various types of I/O depending on the file or device and the flags and attributes specified.

 

📋 CreateFile Syntax

HANDLE CreateFileA(
  LPCSTR                lpFileName,
  DWORD                 dwDesiredAccess,
  DWORD                 dwShareMode,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  DWORD                 dwCreationDisposition,
  DWORD                 dwFlagsAndAttributes,
  HANDLE                hTemplateFile
);

📋 CreateFile Source Code

this->handler = CreateFileA(static_cast<LPCSTR>(port.second.c_str()),
            GENERIC_READ | GENERIC_WRITE,
            0,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
            NULL);

if (this->handler == INVALID_HANDLE_VALUE) {
    if (GetLastError() == ERROR_FILE_NOT_FOUND) {
        // here CreateFile error (SETUP_SERIAL_PORT_ERROR)
    }
    // here CreateFile error (CREATE_FILE_HANDLE_ERROR)
}
2️⃣ DCB

Defines the control setting for a serial communications device.

 

📋 DCB Syntax

typedef struct _DCB {
  DWORD DCBlength;
  DWORD BaudRate;
  DWORD fBinary : 1;
  DWORD fParity : 1;
  DWORD fOutxCtsFlow : 1;
  DWORD fOutxDsrFlow : 1;
  DWORD fDtrControl : 2;
  DWORD fDsrSensitivity : 1;
  DWORD fTXContinueOnXoff : 1;
  DWORD fOutX : 1;
  DWORD fInX : 1;
  DWORD fErrorChar : 1;
  DWORD fNull : 1;
  DWORD fRtsControl : 2;
  DWORD fAbortOnError : 1;
  DWORD fDummy2 : 17;
  WORD  wReserved;
  WORD  XonLim;
  WORD  XoffLim;
  BYTE  ByteSize;
  BYTE  Parity;
  BYTE  StopBits;
  char  XonChar;
  char  XoffChar;
  char  ErrorChar;
  char  EofChar;
  char  EvtChar;
  WORD  wReserved1;
} DCB, *LPDCB;

📋 DCB Source Code

DCB dcbSerialParameters = { 0 };

if (!GetCommState(this->handler, &dcbSerialParameters)) {
    // here CreateFile error (CREATE_DCB_PADDING_ERROR)
} else {

    dcbSerialParameters.DCBlength    = sizeof(dcbSerialParameters);
    dcbSerialParameters.BaudRate    = CBR_9600; // BandWidth
    dcbSerialParameters.ByteSize    = 8;
    dcbSerialParameters.StopBits    = ONESTOPBIT;
    dcbSerialParameters.Parity    = NOPARITY;
    dcbSerialParameters.fDtrControl    = DTR_CONTROL_ENABLE;

    if (!SetCommState(handler, &dcbSerialParameters)) {
        // here CreateFile error (SETUP_DCB_PADDING_ERROR)
    }
2️⃣ ↔️ 1️⃣ GetCommState

Retrieves the current control settings for a specified communications device.

BOOL GetCommState(
  HANDLE hFile,
  LPDCB  lpDCB
);
2️⃣ ↔️ 2️⃣ SetCommState

Configures a communications device according to the specifications in a device-control block (a DCB structure). The function reinitializes all hardware and control settings, but it does not empty output or input queues.

BOOL SetCommState(
  HANDLE hFile,
  LPDCB  lpDCB
);

3️⃣ COMMTIMEOUTS

Contains the time-out parameters for a communications device. The parameters determine the behavior of ReadFile, WriteFile, ReadFileEx, and WriteFileEx operations on the device.

 

📋 COMMTIMEOUTS Syntax

typedef struct _COMMTIMEOUTS {
  DWORD ReadIntervalTimeout;
  DWORD ReadTotalTimeoutMultiplier;
  DWORD ReadTotalTimeoutConstant;
  DWORD WriteTotalTimeoutMultiplier;
  DWORD WriteTotalTimeoutConstant;
} COMMTIMEOUTS, *LPCOMMTIMEOUTS;

📋 COMMTIMEOUTS Source Code

// MARK: http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNo=20&no=232925&ref=232925
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout                = 0xFFFFFFFF; // 0xFFFFFFFF
timeouts.ReadTotalTimeoutMultiplier            = 0;
timeouts.ReadTotalTimeoutConstant            = 0;
timeouts.WriteTotalTimeoutConstant            = 5000;
timeouts.WriteTotalTimeoutMultiplier            = 0;

SetCommTimeouts(this->handler, &timeouts);
3️⃣ ↔️ 1️⃣ SetCommTimeouts

Sets the time-out parameters for all read and write operations on a specified communications device.

BOOL SetCommTimeouts(
  HANDLE         hFile,
  LPCOMMTIMEOUTS lpCommTimeouts
);

4️⃣ OVERLAPPED

Contains information used in asynchronous (or overlapped) input and output (I/O).

 

📋 OVERLAPPED Syntax

typedef struct _OVERLAPPED {
  ULONG_PTR Internal;
  ULONG_PTR InternalHigh;
  union {
    struct {
      DWORD Offset;
      DWORD OffsetHigh;
    } DUMMYSTRUCTNAME;
    PVOID Pointer;
  } DUMMYUNIONNAME;
  HANDLE    hEvent;
} OVERLAPPED, *LPOVERLAPPED;

📋 OVERLAPPED Source Code

// MARK: https://wwwi.tistory.com/215
this->overlaped_event.second.Offset            = 0;
this->overlaped_event.second.OffsetHigh            = 0;
this->overlaped_event.second.hEvent            = CreateEvent(0, 1, 0, 0);

this->overlaped_event.first.Offset            = 0;
this->overlaped_event.first.OffsetHigh            = 0;
this->overlaped_event.first.hEvent            = CreateEvent(0, 1, 0, 0);

5️⃣ SetCommMask

Specifies a set of events to be monitored for a communications device.

 

📋 SetCommMask Syntax

BOOL SetCommMask(
  HANDLE hFile,
  DWORD  dwEvtMask
);

📋 SetCommMask Source Code

/* 
    EV_BREAK: A break was detected on input.
    EV_CTS: The CTS (clear-to-send) signal changed state.
    EV_DSR: The DSR (data-set-ready) signal changed state.
    EV_ERR: A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
    EV_RING: A ring indicator was detected.
    EV_RLSD: The RLSD (receive-line-signal-detect) signal changed state.
    EV_RXCHAR: A character was received and placed in the input buffer.
    EV_RXFLAG: The event character was received and placed in the input buffer. The event character is specified in the         device's DCB structure, which is applied to a serial port by using the SetCommState function.
    EV_TXEMPTY: The last character in the output buffer was sent.
*/

SetCommMask(this->handler, EV_RXCHAR);

6️⃣ WriteFile

Writes data to the specified file or input/output (I/O) device. This function is designed for both synchronous and asynchronous operation. For a similar function designed solely for asynchronous operation, see WriteFileEx.

 

📋 WriteFile Syntax

BOOL WriteFile(
  HANDLE       hFile,
  LPCVOID      lpBuffer,
  DWORD        nNumberOfBytesToWrite,
  LPDWORD      lpNumberOfBytesWritten,
  LPOVERLAPPED lpOverlapped
);

7️⃣ ReadFile

Reads data from the specified file or input/output (I/O) device. Reads occur at the position specified by the file pointer if supported by the device. This function is designed for both synchronous and asynchronous operations. For a similar function designed solely for asynchronous operation, see ReadFileEx.

 

📋 ReadFile Syntax

BOOL ReadFile(
  HANDLE       hFile,
  LPVOID       lpBuffer,
  DWORD        nNumberOfBytesToRead,
  LPDWORD      lpNumberOfBytesRead,
  LPOVERLAPPED lpOverlapped
);

📋 ReadFile Source Code

// MARK: https://github.com/xanthium-enterprises/Serial-Programming-Win32API-C/blob/master/USB2SERIAL_Read/Reciever%20(PC%20Side)/USB2SERIAL_Read_W32.c
std::string message = std::string();

while (true) {

    if (WaitCommEvent(handle->handler, &handle->dwEventMask, 0)) {
        DWORD read_Byte = 0;
        message.clear();

        if (handle->dwEventMask & EV_RXCHAR) {

            char temp;
            while (ReadFile(handle->handler, &temp, sizeof(char), &read_Byte, &handle->overlaped_event.first) && temp != EOF) {
                Sleep(SERIAL_SLEEP_TIME), message.push_back(temp);
            }

            // here receive message processing.
        }
    }
}

8️⃣ CloseHandle

Closes an open object handle.

 

📋 CloseHandle Syntax

BOOL CloseHandle(
  HANDLE hObject
);

📋 CloseHandle Source Code

// MARK: http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNo=20&no=232925&ref=232925
PurgeComm(this->handler, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
CloseHandle(this->handler);
8️⃣ ↔️ 1️⃣ PurgeComm

Discards all characters from the output or input buffer of a specified communications resource. It can also terminate pending read or write operations on the resource.

 

📋 PurgeComm Syntax

BOOL PurgeComm(
  HANDLE hFile,
  DWORD  dwFlags
);

📂 Windows Seiral Source Code Files


🚀 REFERENCE

 

기술 문서, API 및 코드 예제

최종 사용자, 개발자 및 IT 전문가를 위한 최신 Microsoft 문서 받기: API 참조, 코드 예제, 기술 문서 등

docs.microsoft.com

 

ChangYeop-Yang - Overview

Do you want to spend the rest of your life selling sugared water or do you want a chance to change the world? - ChangYeop-Yang

github.com

 

직렬 포트 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전.

ko.wikipedia.org

 

반응형

댓글