WIN-API写串口通讯
头文件如下:
代码
//---------------------------------------------------------------------------
#ifndef CommPortH
#define CommPortH
//---------------------------------------------------------------------------
#endif
#include "windows.h"
class CCommPort
{
public:
CCommPort(void);
~CCommPort(void);
private:
DCB dcb;
COMMTIMEOUTS ct;
HANDLE hCommDevice;
bool m_portopen;
OVERLAPPED m_ovread,m_ovwrite,m_ovwait;
public :
bool InitPort(LPCSTR comm);
bool WritePort(LPCSTR lpszSendBuffer,DWORD dwLength);
int ReadPort(LPSTR lpszRcvBuffer,int iMaxLen);
bool ClosePort(void);
};
#ifndef CommPortH
#define CommPortH
//---------------------------------------------------------------------------
#endif
#include "windows.h"
class CCommPort
{
public:
CCommPort(void);
~CCommPort(void);
private:
DCB dcb;
COMMTIMEOUTS ct;
HANDLE hCommDevice;
bool m_portopen;
OVERLAPPED m_ovread,m_ovwrite,m_ovwait;
public :
bool InitPort(LPCSTR comm);
bool WritePort(LPCSTR lpszSendBuffer,DWORD dwLength);
int ReadPort(LPSTR lpszRcvBuffer,int iMaxLen);
bool ClosePort(void);
};
源文件如下:
代码
//---------------------------------------------------------------------------
#pragma hdrstop
#include "CommPort.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
CCommPort::CCommPort(void)
{
hCommDevice = NULL;
m_portopen = false;
memset(&m_ovread,0,sizeof(OVERLAPPED));
memset(&m_ovwrite,0,sizeof(OVERLAPPED));
memset(&m_ovwait,0,sizeof(OVERLAPPED));
m_ovwait.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
m_ovwrite.hEvent= CreateEvent(NULL,TRUE,FALSE,NULL);
m_ovread.hEvent= CreateEvent(NULL,TRUE,FALSE,NULL);
}
//---------------------------------------------------------------------------
CCommPort::~CCommPort(void)
{
if (hCommDevice)
CloseHandle(hCommDevice);
CloseHandle(m_ovwait.hEvent);
CloseHandle(m_ovwrite.hEvent);
CloseHandle(m_ovread.hEvent);
}
//---------------------------------------------------------------------------
bool CCommPort::InitPort(LPCSTR comm)
{
if (m_portopen)
return m_portopen;
bool result = false;
hCommDevice = CreateFile(comm,
GENERIC_WRITE|GENERIC_READ,
0, /* comm devices must be opened w/exclusive-access */
NULL, /* no security attrs */
OPEN_EXISTING, /* comm devices must use OPEN_EXISTING */
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, /* not overlapped I/O */
NULL /* hTemplate must be NULL for comm devices */
); /* handle error */
if(hCommDevice == INVALID_HANDLE_VALUE)
{
result = false;
}
else
{
//Get the config of the modem connection
GetCommState(hCommDevice, &dcb);
//Set to 8 bits, no parity, 1 stopbit
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.Parity = EVENPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fBinary = 1;
dcb.fDtrControl = 1;
dcb.fRtsControl = 1;
//Actually set the config
SetCommState(hCommDevice, &dcb);
if (!SetupComm(hCommDevice, 256, 256))
{
CloseHandle(hCommDevice);
result = false;
}
else
{
//Get timeout information for the communications channel
GetCommTimeouts(hCommDevice, &ct);
ct.ReadIntervalTimeout=100;
ct.ReadTotalTimeoutMultiplier=0;
ct.ReadTotalTimeoutConstant=100;
ct.WriteTotalTimeoutMultiplier=50;
ct.WriteTotalTimeoutConstant=100;
SetCommTimeouts(hCommDevice, &ct);
COMSTAT com;
DWORD Errors;
ClearCommError(hCommDevice,&Errors,&com);
if (com.cbInQue>0)
PurgeComm(hCommDevice,PURGE_RXCLEAR|PURGE_TXCLEAR);
SetCommMask(hCommDevice,EV_RXCHAR);
result = true;
m_portopen = true;
}
}
return result;
}
//---------------------------------------------------------------------------
bool CCommPort::WritePort(LPCSTR lpszSendBuffer,DWORD dwLength)
{
BOOL fWriteStat = 0;
DWORD dwBytesWritten = 0;
DWORD dwErrorFlags = 0;
DWORD dwBytesSent=0;
COMSTAT ComStat;
ClearCommError( hCommDevice, &dwErrorFlags, &ComStat ) ;
PurgeComm(hCommDevice,PURGE_RXCLEAR|PURGE_TXCLEAR);
m_ovwrite.Offset=0;
fWriteStat = WriteFile(hCommDevice, lpszSendBuffer,dwLength,&dwBytesWritten, &m_ovwrite) ;
if (!fWriteStat)
{
if(::GetLastError() == ERROR_IO_PENDING)
{
if (!GetOverlappedResult(hCommDevice,&m_ovwrite, &dwBytesWritten, true))
{
ClearCommError( hCommDevice, &dwErrorFlags, &ComStat ) ;
return FALSE;
}
dwBytesSent += dwBytesWritten;
if( dwBytesSent != dwLength)
return FALSE;
else
return TRUE;
}//Io pending Error
else
{
ClearCommError( hCommDevice, &dwErrorFlags, &ComStat ) ;
PurgeComm(hCommDevice,PURGE_RXCLEAR|PURGE_TXCLEAR);
return FALSE;
}
}
return TRUE ;
}
//---------------------------------------------------------------------------
int CCommPort::ReadPort(LPSTR lpszRcvBuffer,int iMaxLen)
{
DWORD comEvent = NULL;
if (!WaitCommEvent(hCommDevice,&comEvent,&m_ovwait))
{
if (WaitForSingleObject(m_ovwait.hEvent,500) == WAIT_OBJECT_0)
{
if ((comEvent & EV_RXCHAR) != EV_RXCHAR)
return 0;
}
else
return 0;
}
else
{
if ((comEvent & EV_RXCHAR) != EV_RXCHAR)
return 0;
}
BOOL fReadStat ;
COMSTAT ComStat ;
DWORD dwErrorFlags;
DWORD dwLengthrd;
DWORD dwLength;
dwLength = iMaxLen;
if (dwLength > 0)
{
m_ovread.Offset=0;
fReadStat = ReadFile( hCommDevice, lpszRcvBuffer,dwLength, &dwLengthrd, &m_ovread) ;
if (!fReadStat)
{
if (GetLastError() == ERROR_IO_PENDING)
{
if (!GetOverlappedResult(hCommDevice,&m_ovread, &dwLengthrd, true))
{
ClearCommError(hCommDevice , &dwErrorFlags, &ComStat ) ;
PurgeComm(hCommDevice,PURGE_RXCLEAR|PURGE_TXCLEAR);
}
}
else // Io pending Error
{
dwLengthrd = 0 ;
ClearCommError( hCommDevice, &dwErrorFlags, &ComStat ) ;
PurgeComm(hCommDevice,PURGE_RXCLEAR|PURGE_TXCLEAR);
}
}
}
return (dwLengthrd) ;
}
//---------------------------------------------------------------------------
bool CCommPort::ClosePort(void)
{
if (m_portopen)
{
if (CloseHandle(hCommDevice))
{
hCommDevice = NULL;
m_portopen = false;
}
}
return false;
}
//---------------------------------------------------------------------------
#pragma hdrstop
#include "CommPort.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
CCommPort::CCommPort(void)
{
hCommDevice = NULL;
m_portopen = false;
memset(&m_ovread,0,sizeof(OVERLAPPED));
memset(&m_ovwrite,0,sizeof(OVERLAPPED));
memset(&m_ovwait,0,sizeof(OVERLAPPED));
m_ovwait.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
m_ovwrite.hEvent= CreateEvent(NULL,TRUE,FALSE,NULL);
m_ovread.hEvent= CreateEvent(NULL,TRUE,FALSE,NULL);
}
//---------------------------------------------------------------------------
CCommPort::~CCommPort(void)
{
if (hCommDevice)
CloseHandle(hCommDevice);
CloseHandle(m_ovwait.hEvent);
CloseHandle(m_ovwrite.hEvent);
CloseHandle(m_ovread.hEvent);
}
//---------------------------------------------------------------------------
bool CCommPort::InitPort(LPCSTR comm)
{
if (m_portopen)
return m_portopen;
bool result = false;
hCommDevice = CreateFile(comm,
GENERIC_WRITE|GENERIC_READ,
0, /* comm devices must be opened w/exclusive-access */
NULL, /* no security attrs */
OPEN_EXISTING, /* comm devices must use OPEN_EXISTING */
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, /* not overlapped I/O */
NULL /* hTemplate must be NULL for comm devices */
); /* handle error */
if(hCommDevice == INVALID_HANDLE_VALUE)
{
result = false;
}
else
{
//Get the config of the modem connection
GetCommState(hCommDevice, &dcb);
//Set to 8 bits, no parity, 1 stopbit
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.Parity = EVENPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fBinary = 1;
dcb.fDtrControl = 1;
dcb.fRtsControl = 1;
//Actually set the config
SetCommState(hCommDevice, &dcb);
if (!SetupComm(hCommDevice, 256, 256))
{
CloseHandle(hCommDevice);
result = false;
}
else
{
//Get timeout information for the communications channel
GetCommTimeouts(hCommDevice, &ct);
ct.ReadIntervalTimeout=100;
ct.ReadTotalTimeoutMultiplier=0;
ct.ReadTotalTimeoutConstant=100;
ct.WriteTotalTimeoutMultiplier=50;
ct.WriteTotalTimeoutConstant=100;
SetCommTimeouts(hCommDevice, &ct);
COMSTAT com;
DWORD Errors;
ClearCommError(hCommDevice,&Errors,&com);
if (com.cbInQue>0)
PurgeComm(hCommDevice,PURGE_RXCLEAR|PURGE_TXCLEAR);
SetCommMask(hCommDevice,EV_RXCHAR);
result = true;
m_portopen = true;
}
}
return result;
}
//---------------------------------------------------------------------------
bool CCommPort::WritePort(LPCSTR lpszSendBuffer,DWORD dwLength)
{
BOOL fWriteStat = 0;
DWORD dwBytesWritten = 0;
DWORD dwErrorFlags = 0;
DWORD dwBytesSent=0;
COMSTAT ComStat;
ClearCommError( hCommDevice, &dwErrorFlags, &ComStat ) ;
PurgeComm(hCommDevice,PURGE_RXCLEAR|PURGE_TXCLEAR);
m_ovwrite.Offset=0;
fWriteStat = WriteFile(hCommDevice, lpszSendBuffer,dwLength,&dwBytesWritten, &m_ovwrite) ;
if (!fWriteStat)
{
if(::GetLastError() == ERROR_IO_PENDING)
{
if (!GetOverlappedResult(hCommDevice,&m_ovwrite, &dwBytesWritten, true))
{
ClearCommError( hCommDevice, &dwErrorFlags, &ComStat ) ;
return FALSE;
}
dwBytesSent += dwBytesWritten;
if( dwBytesSent != dwLength)
return FALSE;
else
return TRUE;
}//Io pending Error
else
{
ClearCommError( hCommDevice, &dwErrorFlags, &ComStat ) ;
PurgeComm(hCommDevice,PURGE_RXCLEAR|PURGE_TXCLEAR);
return FALSE;
}
}
return TRUE ;
}
//---------------------------------------------------------------------------
int CCommPort::ReadPort(LPSTR lpszRcvBuffer,int iMaxLen)
{
DWORD comEvent = NULL;
if (!WaitCommEvent(hCommDevice,&comEvent,&m_ovwait))
{
if (WaitForSingleObject(m_ovwait.hEvent,500) == WAIT_OBJECT_0)
{
if ((comEvent & EV_RXCHAR) != EV_RXCHAR)
return 0;
}
else
return 0;
}
else
{
if ((comEvent & EV_RXCHAR) != EV_RXCHAR)
return 0;
}
BOOL fReadStat ;
COMSTAT ComStat ;
DWORD dwErrorFlags;
DWORD dwLengthrd;
DWORD dwLength;
dwLength = iMaxLen;
if (dwLength > 0)
{
m_ovread.Offset=0;
fReadStat = ReadFile( hCommDevice, lpszRcvBuffer,dwLength, &dwLengthrd, &m_ovread) ;
if (!fReadStat)
{
if (GetLastError() == ERROR_IO_PENDING)
{
if (!GetOverlappedResult(hCommDevice,&m_ovread, &dwLengthrd, true))
{
ClearCommError(hCommDevice , &dwErrorFlags, &ComStat ) ;
PurgeComm(hCommDevice,PURGE_RXCLEAR|PURGE_TXCLEAR);
}
}
else // Io pending Error
{
dwLengthrd = 0 ;
ClearCommError( hCommDevice, &dwErrorFlags, &ComStat ) ;
PurgeComm(hCommDevice,PURGE_RXCLEAR|PURGE_TXCLEAR);
}
}
}
return (dwLengthrd) ;
}
//---------------------------------------------------------------------------
bool CCommPort::ClosePort(void)
{
if (m_portopen)
{
if (CloseHandle(hCommDevice))
{
hCommDevice = NULL;
m_portopen = false;
}
}
return false;
}
//---------------------------------------------------------------------------