Visual C++에서 시리얼 통신 소스는 다음과 같다.
BOOL PortOpen(CString sPortName, DWORD dwBaud, BYTE Data, BYTE Parity, BYTE Stop, BYTE Flow)
{
COMMTIMEOUTS timeouts;
DCB dcb;
DWORD dwThreadID;
m_bConnected = FALSE;
// Overlapped structure
m_osRead.Offset = 0;
m_osRead.OffsetHigh = 0;
if (!(m_osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) return FALSE;
m_osWrite.Offset = 0;
m_osWrite.OffsetHigh = 0;
if (!(m_osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) return FALSE;
// Open port
m_sPortName = sPortName;
m_hComm = CreateFile( m_sPortName,
GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
if (m_hComm==(HANDLE)-1) return FALSE;
// EV_RXCHAR event
SetCommMask( m_hComm, EV_RXCHAR);
// InQueue, OutQueue size
SetupComm(m_hComm, 1024*32, 1024*32);
// Purge com
PurgeComm(m_hComm, PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR);
// Timeout
timeouts.ReadIntervalTimeout = 0xFFFFFFFF;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 2*CBR_9600 / dwBaud;
timeouts.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(m_hComm, &timeouts);
// DCB
dcb.DCBlength = sizeof(DCB);
GetCommState(m_hComm, &dcb);
dcb.BaudRate = dwBaud;
dcb.ByteSize = Data;
dcb.Parity = Parity;
dcb.StopBits = Stop; // Stop Bit : 0=1, 1=1.5, 2=2
dcb.fInX = dcb.fOutX = 0; // Xon, Xoff 미사용.
dcb.XonChar = ASCII_XON;
dcb.XoffChar = ASCII_XOFF;
dcb.XonLim = 100;
dcb.XoffLim = 100;
// flow
if (Flow==0)
{
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
}
if (! SetCommState( m_hComm, &dcb)) return FALSE;
// Event
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
// Flag
m_bConnected = TRUE;
return TRUE;
}
void PortClose()
{
SetCommMask(m_hComm, 0);
PurgeComm(m_hComm, PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR);
CloseHandle(m_hComm);
// Flag
m_bConnected = FALSE;
}
DWORD PortWrite(BYTE *pBuff, DWORD nToWrite)
{
DWORD dwWritten, dwError, dwErrorFlags;
COMSTAT comstat;
if (!WriteFile(m_hComm, pBuff, nToWrite, &dwWritten, &m_osWrite))
{
if (GetLastError()==ERROR_IO_PENDING)
{
while (!GetOverlappedResult(m_hComm, &m_osWrite, &dwWritten, TRUE))
{
dwError = GetLastError();
if (dwError!= ERROR_IO_INCOMPLETE)
{
ClearCommError(m_hComm, &dwErrorFlags, &comstat);
break;
}
}
}
else
{
dwWritten = 0;
ClearCommError(m_hComm, &dwErrorFlags, &comstat);
}
}
return dwWritten;
}
DWORD PortRead(BYTE *pBuff, DWORD nToRead)
{
DWORD dwRead, dwError, dwErrorFlags;
COMSTAT comstat;
ClearCommError(m_hComm, &dwErrorFlags, &comstat);
dwRead = comstat.cbInQue;
if (dwRead > 0)
{
if (! ReadFile(m_hComm, pBuff, nToRead, &dwRead, &m_osRead))
{
if (GetLastError()==ERROR_IO_PENDING)
{
while (!GetOverlappedResult(m_hComm, &m_osRead, &dwRead, TRUE))
{
dwError = GetLastError();
if (dwError!= ERROR_IO_INCOMPLETE)
{
ClearCommError(m_hComm, &dwErrorFlags, &comstat);
break;
}
}
}
else
{
dwRead = 0;
ClearCommError(m_hComm, &dwErrorFlags, &comstat);
}
}
}
return dwRead;
}
void PortPurge(void)
{
PurgeComm(m_hComm, PURGE_RXCLEAR);
PurgeComm(m_hComm, PURGE_TXCLEAR);
}
'컴퓨터 > C' 카테고리의 다른 글
C 구조체 (0) | 2022.05.02 |
---|---|
C 변수 선언명 변경하기 (0) | 2022.05.02 |
널 포인터(NULL pointer) (0) | 2021.08.01 |
C의 괄호 스타일 (0) | 2021.07.10 |
[C] __weak 명령어 (0) | 2021.06.22 |
댓글