📄 serialport.cpp
字号:
/*
Module : SERIALPORT.CPP
Copyright (c) 1996 - 2002 by db
*/
///////////////////////////////// Includes //////////////////////////////////
#include "stdafx.h"
#include "serialport.h"
#include "winerror.h"
///////////////////////////////// defines /////////////////////////////////////
static BOOL g_bOverlapped = FALSE;
//////////////////////////////// Implementation ///////////////////////////////
////////// The actual serial port code
extern "C" HANDLE FAR FAR PASCAL RS_Open(int nPort, DWORD dwBaud, Parity parity, BYTE DataBits, StopBits stopbits, FlowControl fc, BOOL bOverlapped)
{
HANDLE hComm;
//Validate our parameters
ASSERT(nPort>0 && nPort<=255);
//Call CreateFile to open up the comms port
CString sPort;
sPort.Format(_T("\\\\.\\COM%d"), nPort);
hComm = CreateFile(sPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, bOverlapped ? FILE_FLAG_OVERLAPPED : 0, NULL);
if (hComm == INVALID_HANDLE_VALUE)
{
TRACE(_T("Failed to open up the comms port\n"));
return INVALID_HANDLE_VALUE;
}
g_bOverlapped = bOverlapped;
//Get the current state prior to changing it
DCB dcb;
RS_GetState(hComm, dcb);
//Setup the baud rate
dcb.BaudRate = dwBaud;
//Setup the Parity
switch (parity)
{
case EvenParity:
dcb.Parity = EVENPARITY;
break;
case MarkParity:
dcb.Parity = MARKPARITY;
break;
case NoParity:
dcb.Parity = NOPARITY;
break;
case OddParity:
dcb.Parity = ODDPARITY;
break;
case SpaceParity:
dcb.Parity = SPACEPARITY;
break;
default:
ASSERT(FALSE);
break;
}
//Setup the data bits
dcb.ByteSize = DataBits;
//Setup the stop bits
switch (stopbits)
{
case OneStopBit:
dcb.StopBits = ONESTOPBIT;
break;
case OnePointFiveStopBits:
dcb.StopBits = ONE5STOPBITS;
break;
case TwoStopBits:
dcb.StopBits = TWOSTOPBITS;
break;
default:
ASSERT(FALSE);
break;
}
//Setup the flow control
dcb.fDsrSensitivity = FALSE;
switch (fc)
{
case NoFlowControl:
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
break;
case CtsRtsFlowControl:
dcb.fOutxCtsFlow = TRUE;
dcb.fOutxDsrFlow = FALSE;
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
break;
case CtsDtrFlowControl:
dcb.fOutxCtsFlow = TRUE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
break;
case DsrRtsFlowControl:
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = TRUE;
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
break;
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
RS_SetState(hComm, dcb);
return hComm;
}
extern "C" BOOL FAR PASCAL RS_Close(HANDLE hComm)
{
ASSERT(hComm != INVALID_HANDLE_VALUE);
//Close down the comms port
BOOL bSuccess = CloseHandle(hComm);
hComm = INVALID_HANDLE_VALUE;
if (!bSuccess)
TRACE(_T("Failed to close up the comms port, GetLastError:%d\n"), GetLastError());
g_bOverlapped = FALSE;
return bSuccess;
}
extern "C" DWORD FAR PASCAL RS_Read(HANDLE hComm, void* lpBuf, DWORD dwCount)
{
ASSERT(hComm != INVALID_HANDLE_VALUE);
ASSERT(!g_bOverlapped);
DWORD dwBytesRead = 0;
if (!ReadFile(hComm, lpBuf, dwCount, &dwBytesRead, NULL))
{
TRACE(_T("Failed in call to ReadFile\n"));
return -1;
}
return dwBytesRead;
}
extern "C" BOOL FAR PASCAL RS_ReadOv(HANDLE hComm, void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped, DWORD* pBytesRead)
{
ASSERT(hComm != INVALID_HANDLE_VALUE);
ASSERT(g_bOverlapped);
DWORD dwBytesRead = 0;
BOOL bSuccess = ReadFile(hComm, lpBuf, dwCount, &dwBytesRead, &overlapped);
if (!bSuccess)
{
if (GetLastError() != ERROR_IO_PENDING)
{
TRACE(_T("Failed in call to ReadFile\n"));
return false;
}
}
if (pBytesRead)
*pBytesRead = dwBytesRead;
return bSuccess;
}
extern "C" DWORD FAR PASCAL RS_Write(HANDLE hComm, const void* lpBuf, DWORD dwCount)
{
ASSERT(hComm != INVALID_HANDLE_VALUE);
ASSERT(!g_bOverlapped);
DWORD dwBytesWritten = 0;
if (!WriteFile(hComm, lpBuf, dwCount, &dwBytesWritten, NULL))
{
TRACE(_T("Failed in call to WriteFile\n"));
return -1;
}
return dwBytesWritten;
}
extern "C" BOOL FAR PASCAL RS_WriteOv(HANDLE hComm, const void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped)
{
ASSERT(hComm != INVALID_HANDLE_VALUE);
ASSERT(g_bOverlapped);
DWORD dwBytesWritten = 0;
BOOL bSuccess = WriteFile(hComm, lpBuf, dwCount, &dwBytesWritten, &overlapped);
if (!bSuccess)
{
if (GetLastError() != ERROR_IO_PENDING)
{
TRACE(_T("Failed in call to WriteFile\n"));
return bSuccess;
}
}
return bSuccess;
}
extern "C" BOOL FAR PASCAL RS_GetOverlappedResult(HANDLE hComm, OVERLAPPED& overlapped, DWORD& dwBytesTransferred, BOOL bWait)
{
ASSERT(hComm != INVALID_HANDLE_VALUE);
ASSERT(g_bOverlapped);
if (!::GetOverlappedResult(hComm, &overlapped, &dwBytesTransferred, bWait))
{
if (GetLastError() != ERROR_IO_PENDING)
{
TRACE(_T("Failed in call to GetOverlappedResult\n"));
return false;
}
}
return true;
}
extern "C" DWORD FAR PASCAL RS_BytesWaiting(HANDLE hComm)
{
//Check to see how many characters are unread
COMSTAT stat;
RS_GetStatus(hComm, stat);
return stat.cbInQue;
}
extern "C" BOOL FAR PASCAL RS_TransmitChar(HANDLE hComm, char cChar)
{
ASSERT(hComm != INVALID_HANDLE_VALUE);
if (!TransmitCommChar(hComm, cChar))
{
TRACE(_T("Failed in call to TransmitCommChar\n"));
return FALSE;
}
return TRUE;
}
extern "C" BOOL FAR PASCAL RS_GetConfig(HANDLE hComm, COMMCONFIG& config)
{
ASSERT(hComm != INVALID_HANDLE_VALUE);
DWORD dwSize = sizeof(COMMCONFIG);
if (!GetCommConfig(hComm, &config, &dwSize))
{
TRACE(_T("Failed in call to GetCommConfig\n"));
return FALSE;
}
return TRUE;
}
extern "C" BOOL FAR PASCAL RS_SetConfig(HANDLE hComm, COMMCONFIG& config)
{
ASSERT(hComm != INVALID_HANDLE_VALUE);
DWORD dwSize = sizeof(COMMCONFIG);
if (!SetCommConfig(hComm, &config, dwSize))
{
TRACE(_T("Failed in call to SetCommConfig\n"));
return FALSE;
}
return TRUE;
}
extern "C" BOOL FAR PASCAL RS_SetBreak(HANDLE hComm)
{
ASSERT(hComm != INVALID_HANDLE_VALUE);
if (!SetCommBreak(hComm))
{
TRACE(_T("Failed in call to SetCommBreak\n"));
return FALSE;
}
return TRUE;
}
extern "C" BOOL FAR PASCAL RS_ClearBreak(HANDLE hComm)
{
ASSERT(hComm != INVALID_HANDLE_VALUE);
if (!ClearCommBreak(hComm))
{
TRACE(_T("Failed in call to SetCommBreak\n"));
return FALSE;
}
return TRUE;
}
extern "C" BOOL FAR PASCAL RS_ClearError(HANDLE hComm, DWORD& dwErrors)
{
ASSERT(hComm != INVALID_HANDLE_VALUE);
if (!ClearCommError(hComm, &dwErrors, NULL))
{
TRACE(_T("Failed in call to ClearCommError\n"));
return FALSE;
}
return TRUE;
}
extern "C" BOOL FAR PASCAL RS_GetDefaultConfig(int nPort, COMMCONFIG& config)
{
//Validate our parameters
ASSERT(nPort>0 && nPort<=255);
//Create the device name as a string
CString sPort;
sPort.Format(_T("COM%d"), nPort);
DWORD dwSize = sizeof(COMMCONFIG);
if (!GetDefaultCommConfig(sPort, &config, &dwSize))
{
TRACE(_T("Failed in call to GetDefaultCommConfig\n"));
return FALSE;
}
return TRUE;
}
extern "C" BOOL FAR PASCAL RS_SetDefaultConfig(int nPort, COMMCONFIG& config)
{
//Validate our parameters
ASSERT(nPort>0 && nPort<=255);
//Create the device name as a string
CString sPort;
sPort.Format(_T("COM%d"), nPort);
DWORD dwSize = sizeof(COMMCONFIG);
if (!SetDefaultCommConfig(sPort, &config, dwSize))
{
TRACE(_T("Failed in call to GetDefaultCommConfig\n"));
return FALSE;
}
return TRUE;
}
extern "C" BOOL FAR PASCAL RS_GetStatus(HANDLE hComm, COMSTAT& stat)
{
ASSERT(hComm != INVALID_HANDLE_VALUE);
DWORD dwErrors;
if (!ClearCommError(hComm, &dwErrors, &stat))
{
TRACE(_T("Failed in call to ClearCommError\n"));
return FALSE;
}
return TRUE;
}
extern "C" BOOL FAR PASCAL RS_GetState(HANDLE hComm, DCB& dcb)
{
ASSERT(hComm != INVALID_HANDLE_VALUE);
if (!GetCommState(hComm, &dcb))
{
TRACE(_T("Failed in call to GetCommState\n"));
return FALSE;
}
return TRUE;
}
extern "C" BOOL FAR PASCAL RS_SetState(HANDLE hComm, DCB& dcb)
{
ASSERT(hComm != INVALID_HANDLE_VALUE);
if (!SetCommState(hComm, &dcb))
{
TRACE(_T("Failed in call to SetCommState\n"));
return FALSE;
}
return TRUE;
}
extern "C" BOOL FAR PASCAL RS_Escape(HANDLE hComm, DWORD dwFunc)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -