2,644
社区成员




// Serial.h
#ifndef __SERIAL_H__
#define __SERIAL_H__
#define FC_DTRDSR 0x01
#define FC_RTSCTS 0x02
#define FC_XONXOFF 0x04
#define ASCII_BEL 0x07
#define ASCII_BS 0x08
#define ASCII_LF 0x0A
#define ASCII_CR 0x0D
#define ASCII_XON 0x11
#define ASCII_XOFF 0x13
class CSerial
{
public:
CSerial();
~CSerial();
BOOL Open(int nPort=1,int nBaud= 38400);
BOOL Close(void);
int ReadData( void *,int );
int SendData( const char *,int);
int ReadDataWaiting(void);
BOOL IsOpened(void)
{
return m_bOpened;
}
protected:
BOOL WriteCommByte(unsigned char);
HANDLE m_hIDComDev;
OVERLAPPED m_OverlappedRead,m_OverlappedWrite;
BOOL m_bOpened;
};
#endif
// Serial.cpp
#include "stdafx.h"
#include "Serial.h"
CSerial::CSerial()
{
memset(&m_OverlappedRead,0,sizeof(OVERLAPPED));
memset(&m_OverlappedWrite, 0, sizeof(OVERLAPPED));
m_hIDComDev= NULL;
m_bOpened=FALSE;
}
CSerial::~CSerial()
{
Close();
}
BOOL CSerial::Open(int nPort,int nBaud)
{
if(m_bOpened)
return TRUE;
char szPort[15];
char szComParams[50];
DCB dcb;
wsprintf(szPort,"COM%d",nPort);
m_hIDComDev=CreateFile(szPort, GENERIC_READ|GENERIC_WRITE,0,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL);
if(m_hIDComDev==NULL)
return FALSE;
memset(&m_OverlappedRead,0,sizeof(OVERLAPPED));
memset(&m_OverlappedWrite,0,sizeof(OVERLAPPED));
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout=0xFFFFFFFF;
CommTimeOuts.ReadTotalTimeoutMultiplier=0;
CommTimeOuts.ReadTotalTimeoutConstant=0;
CommTimeOuts.WriteTotalTimeoutMultiplier=0;
CommTimeOuts.WriteTotalTimeoutConstant=5000;
SetCommTimeouts(m_hIDComDev,&CommTimeOuts );
wsprintf(szComParams,"COM%d:%d,n,8,1",nPort,nBaud);
m_OverlappedRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
m_OverlappedWrite.hEvent= CreateEvent(NULL,TRUE,FALSE,NULL);
dcb.DCBlength=sizeof(DCB);
GetCommState(m_hIDComDev,&dcb);
dcb.BaudRate=nBaud;
dcb.ByteSize=8;
unsigned char ucSet;
ucSet=(unsigned char)((FC_RTSCTS & FC_DTRDSR)!=0);
ucSet=(unsigned char)((FC_RTSCTS & FC_RTSCTS)!=0);
ucSet=(unsigned char)((FC_RTSCTS & FC_XONXOFF)!=0);
if(!SetCommState(m_hIDComDev,&dcb) || !SetupComm(m_hIDComDev,10000,10000)
|| m_OverlappedRead.hEvent==NULL ||m_OverlappedWrite.hEvent==NULL)
{
DWORD dwError=GetLastError();
if(m_OverlappedRead.hEvent!=NULL)
CloseHandle(m_OverlappedRead.hEvent);
if(m_OverlappedWrite.hEvent!=NULL)
CloseHandle(m_OverlappedWrite.hEvent);
CloseHandle(m_hIDComDev);
return FALSE;
}
m_bOpened=TRUE;
return m_bOpened;
}
BOOL CSerial::Close(void)
{
if(!m_bOpened || m_hIDComDev==NULL)
return TRUE;
if(m_OverlappedRead.hEvent!=NULL)
CloseHandle(m_OverlappedRead.hEvent);
if(m_OverlappedWrite.hEvent!=NULL)
CloseHandle(m_OverlappedWrite.hEvent);
CloseHandle(m_hIDComDev);
m_bOpened=FALSE;
m_hIDComDev=NULL;
return TRUE;
}
BOOL CSerial::WriteCommByte(unsigned char ucByte)
{
BOOL bWriteStat;
DWORD dwBytesWritten;
bWriteStat=WriteFile(m_hIDComDev,(LPSTR)&ucByte,1,&dwBytesWritten,&m_OverlappedWrite);
if(!bWriteStat && (GetLastError()==ERROR_IO_PENDING))
{
if(WaitForSingleObject(m_OverlappedWrite.hEvent,1000))
dwBytesWritten=0;
else
{
GetOverlappedResult(m_hIDComDev,&m_OverlappedWrite,&dwBytesWritten,FALSE);
m_OverlappedWrite.Offset+= dwBytesWritten;
}
}
return TRUE;
}
int CSerial::SendData(const char *buffer,int size)
{
if(!m_bOpened || m_hIDComDev==NULL)
return 0;
DWORD dwBytesWritten=0;
int i;
for(i=0;i<size;i++)
{
WriteCommByte(buffer[i]);
dwBytesWritten++;
}
return (int)dwBytesWritten;
}
int CSerial::ReadDataWaiting(void)
{
if(!m_bOpened ||m_hIDComDev== NULL)
return 0;
DWORD dwErrorFlags;
COMSTAT ComStat;
ClearCommError(m_hIDComDev,&dwErrorFlags,&ComStat);
return (int)ComStat.cbInQue;
}
int CSerial::ReadData(void *buffer,int limit)
{
if(!m_bOpened || m_hIDComDev==NULL)
return 0;
BOOL bReadStatus;
DWORD dwBytesRead,dwErrorFlags;
COMSTAT ComStat;
ClearCommError(m_hIDComDev,&dwErrorFlags,&ComStat);
if(!ComStat.cbInQue)
return 0;
dwBytesRead=(DWORD)ComStat.cbInQue;
if(limit<(int)dwBytesRead)
dwBytesRead=(DWORD)limit;
bReadStatus=ReadFile(m_hIDComDev,buffer,dwBytesRead,&dwBytesRead,&m_OverlappedRead);
if(!bReadStatus)
{
if(GetLastError()==ERROR_IO_PENDING)
{
WaitForSingleObject(m_OverlappedRead.hEvent,2000);
return (int)dwBytesRead;
}
return 0;
}
return (int)dwBytesRead;
}