各位同行好:
本人初入该网站,对该站的一些话题很感兴趣,对于WINDOWS的串行通讯,我认为采用异步
方式可能会更好,下面是一段用vc++ 写的通讯程序,本人曾用在多个项目中,供大家参考。
/////////////
CComm::CComm()
{
}
CComm::~CComm()
{
}
void CComm::SetCommByteSize(BYTE bByteSize)
{
m_bByteSize=bByteSize;
}
void CComm::SetCommParity(BYTE bParity)
{
m_bParity=bParity;
}
void CComm::SetCommStopBits(BYTE bStopBit)
{
m_bStopBits=bStopBit;
}
BOOL CComm::OpenCommConnect(COMMINFO commInfo)
{
if(m_osRead.hEvent==NULL){return FALSE;}
COMMTIMEOUTS CommTimeOuts ;
char szPort[15],szTemp[64];
wsprintf(szPort,"COM%d",commInfo.bPort);
m_idComDev=CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_OVERLAPPED,
NULL );
if(!m_idComDev )
{
wsprintf(szTemp,"Open %s Fail",szPort);
MessageBox(NULL,szTemp,"Ininital Com Error",MB_OK);
return FALSE;
}
if(SetupCommConnect(commInfo))
{
m_fConnected=true;
CommTimeOuts.ReadIntervalTimeout = 0;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;
CommTimeOuts.ReadTotalTimeoutConstant = 200;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant =50 ;
SetCommTimeouts( m_idComDev, &CommTimeOuts ) ;
SetupComm(m_idComDev,256,256);// set the len of buffer for tansfer
PurgeComm(m_idComDev,PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
EscapeCommFunction( m_idComDev, SETDTR ) ;
return TRUE;
}
else
{
m_fConnected=false;
CloseHandle(m_idComDev);
return FALSE;
}
}
BOOL CComm::SetupCommConnect(COMMINFO commInfo)
{
BOOL fRetVal ;
DCB dcb ;
dcb.DCBlength = sizeof( DCB ) ;
GetCommState(m_idComDev, &dcb ) ;
dcb.BaudRate = commInfo.dwBaudRate;
dcb.ByteSize = commInfo.bByteSize;
dcb.Parity =commInfo.bParity;
dcb.StopBits =commInfo.bStopBits ;
fRetVal = SetCommState(m_idComDev,&dcb) ;
return ( fRetVal ) ;
}
BOOL CComm::CloseConnect()
{
if(!m_fConnected)
return TRUE;
m_fConnected=false;
SetCommMask( m_idComDev, 0 ) ;
PurgeComm( m_idComDev , PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
EscapeCommFunction(m_idComDev, CLRDTR ) ;
CloseHandle(m_osRead.hEvent);
CloseHandle(m_osWrite.hEvent);
CloseHandle( m_idComDev ) ;
return TRUE;
}
int CComm::ReadFromComm(unsigned char* lpszRcvBuffer,int iMaxLen,DWORD& error )
{
DWORD dwLengthrd;
DWORD dwLength;
if(m_idComDev==(HANDLE)-1)
return 0;
dwLength =iMaxLen;
if(!waitonread)
{
if(!ReadFile( m_idComDev, lpszRcvBuffer, dwLength, &dwLengthrd, &m_osRead))
{
if (GetLastError() != ERROR_IO_PENDING)
{ Sleep(1000);
error=1;
return 0;}
waitonread=true;
}
else
{ error=0;
return dwLengthrd;}
}
if(waitonread)
{
if(WaitForSingleObject(m_osRead.hEvent,500)!=WAIT_OBJECT_0)
{ error=3;
return 0;}
if(!GetOverlappedResult( m_idComDev,&m_osRead, &dwLengthrd, FALSE ))
{
return 0;
}
waitonread=false;
}
error=0;
return ( dwLengthrd ) ;
}
int CComm::WriteToComm(char* lpszSendBuffer,DWORD dwLength,DWORD& error)
{
DWORD dwBytesWritten ;
if(m_idComDev==(HANDLE)-1)
return 0;
if(!waitonwrite)
{
if(!WriteFile( m_idComDev, lpszSendBuffer, dwLength, &dwBytesWritten, &m_osWrite))
{
if (GetLastError() != ERROR_IO_PENDING)
{
error=1;
Sleep(1000);
return 0;
}
waitonwrite=true;
}
else
{ error=0;
return dwBytesWritten;}
}
if(waitonwrite)
{
if(WaitForSingleObject(m_osWrite.hEvent,500)!=WAIT_OBJECT_0)
{ error=2 ;
return 0;}
if(!GetOverlappedResult( m_idComDev,&m_osWrite, &dwBytesWritten, FALSE ))
{
return 0;
}
waitonwrite=false;
}
error=0;
return (dwBytesWritten ) ;
}
HANDLE CComm::GetComDev()
{
return m_idComDev;
}
BOOL CComm::GetConnected()
{
return m_fConnected;
}
void CComm::SetBaudRate(DWORD dwBaudRate)
{
m_dwBaudRate=dwBaudRate;
}
void CComm::SetCommPort(BYTE bPort)
{
m_bPort=bPort;
}
BOOL CComm::ChangeBaudRate(DWORD dwBaudRate)
{
BOOL fRetVal;
DCB dcb;
dcb.DCBlength = sizeof( DCB ) ;
GetCommState(m_idComDev, &dcb ) ;
m_dwBaudRate=dwBaudRate;
dcb.BaudRate = m_dwBaudRate;
fRetVal = SetCommState(m_idComDev,&dcb) ;
return ( fRetVal ) ;
}
BOOL CComm::ChangeCommByteSize(BYTE bByteSize)
{
BOOL fRetVal;
DCB dcb;
dcb.DCBlength = sizeof( DCB ) ;
GetCommState(m_idComDev, &dcb ) ;
m_bByteSize=bByteSize;
dcb.ByteSize = m_bByteSize;
fRetVal = SetCommState(m_idComDev,&dcb) ;
return ( fRetVal );
}
BOOL CComm::ChangeCommParity(BYTE bParity)
{
BOOL fRetVal;
DCB dcb;
dcb.DCBlength = sizeof( DCB ) ;
GetCommState(m_idComDev, &dcb ) ;
m_bParity=bParity;
dcb.Parity = m_bParity;
fRetVal = SetCommState(m_idComDev,&dcb) ;
return ( fRetVal );
}
BOOL CComm::ChangeCommStopBits(BYTE bStopBit)
{
BOOL fRetVal;
DCB dcb;
dcb.DCBlength = sizeof( DCB ) ;
GetCommState(m_idComDev, &dcb ) ;
m_bStopBits=bStopBit;
dcb.StopBits = m_bStopBits;
fRetVal = SetCommState(m_idComDev,&dcb) ;
return ( fRetVal );
}
void CComm::purge()
{
PurgeComm(m_idComDev,PURGE_RXCLEAR|PURGE_TXCLEAR);
}
void CComm::InitParam()
{
m_fConnected=false;
}