📄 serial.cpp
字号:
// Serial.cpp
#include "stdafx.h"
#include "serial.h"
#include "time.h"
#include "stdio.h"
CSerial::CSerial()
{
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
m_hIDComDev = NULL;
m_bOpened = FALSE;
m_bConnected = 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 = 0;
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.fParity = FALSE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fDsrSensitivity = FALSE;
dcb.fTXContinueOnXoff = FALSE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
dcb.fAbortOnError = FALSE;
dcb.XonLim = 512;
dcb.XoffLim = 1024;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
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 );
}
DWORD dwMask;
if(GetCommMask(m_hIDComDev,&dwMask))
{
dwMask =dwMask | EV_RXCHAR ;
if(!SetCommMask(m_hIDComDev,dwMask))
return FALSE;
}
m_bOpened = TRUE;
return( TRUE );
}
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 );
}
BOOL CSerial::WriteCommStr(const char* buf,int len )
{
BOOL bWriteStat;
DWORD dwBytesWritten;
bWriteStat = WriteFile( m_hIDComDev, buf, len, &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;
}
}
else
return FALSE;
return( TRUE );
}
int CSerial::SendData(const char *buffer, int size,int opt )
{
if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );
DWORD dwBytesWritten = 0;
int i;
PurgeComm(m_hIDComDev,PURGE_TXCLEAR | PURGE_RXCLEAR);
DWORD dwError;
COMSTAT cs;
ClearCommError(m_hIDComDev,&dwError,&cs);
if(opt==0)
{
for( i=0; i<size; i++ ){
WriteCommByte( buffer[i] );
dwBytesWritten++;
}
}
else
{
if(WriteCommStr(buffer,size))
dwBytesWritten=size;
else
dwBytesWritten=0;
}
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 );
}
int CSerial::ReadEvent(char* buffer,int limit)
{
DWORD nBytesRead,dwError;
COMSTAT cs;
short rc=0;
ClearCommError(m_hIDComDev,&dwError,&cs);
if( !cs.cbInQue ) return( 0 );
nBytesRead = (DWORD) cs.cbInQue;
if( limit > (int) nBytesRead ) nBytesRead = (DWORD) limit;
if(ReadFile(m_hIDComDev,buffer,nBytesRead ,&nBytesRead,&m_OverlappedRead))
rc=(short)nBytesRead;
else
rc=0;
return rc;
}
/*
int CSerial::ReadEvent(char* buffer,int limit)
{
DWORD nBytesRead,dwEvent,dwError;
COMSTAT cs;
DWORD idx;
short rc=0;
// while(m_bReading){
if(!WaitCommEvent(m_hIDComDev,&dwEvent,&m_OverlappedRead)){
if(GetLastError()==ERROR_IO_PENDING)
{
idx=WaitForSingleObject(m_OverlappedRead.hEvent,3000);
if(idx==WAIT_OBJECT_0)
{
//ResetEvent(m_OverlappedRead.hEvent);
ClearCommError(m_hIDComDev,&dwError,&cs);
if( !cs.cbInQue ) return( 0 );
nBytesRead = (DWORD) cs.cbInQue;
if( limit > (int) nBytesRead ) nBytesRead = (DWORD) limit;
if((dwEvent & EV_RXCHAR) && cs.cbInQue ){
if(ReadFile(m_hIDComDev,buffer,nBytesRead ,&nBytesRead,&m_OverlappedRead))
{
rc=(short)nBytesRead;
}
else
{
if( GetLastError() == ERROR_IO_PENDING ){
WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
rc= (short)nBytesRead ;
}
else
rc=0;
}
}
}
else
rc=0;
}
else
rc=0;
}
return rc;
}
*/
int CSerial::GetModemstatus()
{
COMSTAT cs;
int rc;
DWORD ModemStatus=0,dwstatus;
ClearCommError(m_hIDComDev,&dwstatus,&cs);
if(GetCommModemStatus(m_hIDComDev,&ModemStatus))
{
if(!(ModemStatus & MS_RLSD_ON))
rc=0;
else
rc=1;
}
else
rc=-1;
return rc;
}
short CSerial::InitialModem(int opt)
{
ReadTillFound("ATZ\r",4,"OK",3);
{
switch(opt)
{
case 0: //起呼拨号modem;
ReadTillFound("ATE1V1Q0S0=0S7=40&C1&W\r",23,"OK",3);
break;
case 1: //反向拨号MODEM;
ReadTillFound("ATE1V1Q0S0=1&C1&W\r",18,"OK",3);
break;
case 2:
break;
}
}
return 0;
}
short CSerial::ReadTillFound(const char* cmd,int len,const char* endstr,int s)
{
char retv[50];
int retlen=0;
short rc=-1;
PurgeComm(m_hIDComDev,PURGE_TXCLEAR | PURGE_RXCLEAR);
SendData(cmd,len,0);
//int start=0,end=0;
time_t end,start=time(0);
while(1)
{
//end++;
end=time(0);
retlen=ReadData(retv,1);
if(retlen>0)
{
if(strstr(retv,endstr)!=NULL)
{
rc=0;break;
}
else if(strstr(retv,"NO CARRIER")!=NULL)
{
HangupModem();
m_bConnected=FALSE;
break;
//continue;
}
else if(strstr(retv,"BUSY")!=NULL)
{
HangupModem();
m_bConnected=FALSE;
break;
}
}
else if(end-start>s)
{
rc=1; //timeout;
break;
}
end=time(0);
Sleep(100);
}
return rc;
}
void CSerial::HangupModem()
{
Sleep(1000);
SendData("+++",3,0);
Sleep(2000);
SendData("ath0\r",5,0);
Sleep(1000);
}
short CSerial::ModifyBaud(int port, int nbaud)
{
DCB dcb;
char msg[50];
if(m_hIDComDev==NULL)
{
m_bOpened=FALSE;
return -1;
}
GetCommState(m_hIDComDev,&dcb);
wsprintf(msg,"COM%d:%d,n,8,1",port,nbaud);
if(BuildCommDCB(msg,&dcb))
{
if(SetCommState(m_hIDComDev,&dcb))
return 0;
}
else
return -1;
return -1;
}
short CSerial::ReadModem(char *buffer, int limit)
{
DWORD dwEvent; //,dwError;
// COMSTAT cs;
// DWORD idx;
short rc=0;
while(1)
{
if(WaitCommEvent(m_hIDComDev,&dwEvent,&m_OverlappedRead)){
if(dwEvent & EV_RLSD)
{
rc=0;break;
}
else
rc=1;
}
/*
ClearCommError(m_hIDComDev,&dwError,&cs);
if( !cs.cbInQue ) return( 0 );
nBytesRead = (DWORD) cs.cbInQue;
if( limit > (int) nBytesRead ) nBytesRead = (DWORD) limit;
if((dwEvent & EV_RXCHAR) && cs.cbInQue ){
if(ReadFile(m_hIDComDev,buffer,nBytesRead ,&nBytesRead,&m_OverlappedRead))
{
rc=(short)nBytesRead;
}
else
{
if( GetLastError() == ERROR_IO_PENDING ){
WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
rc= (short)nBytesRead ;
}
else
rc=0;
}
}
*/ }
return rc;
}
BOOL CSerial::IsConnected()
{
unsigned long st;
GetCommModemStatus(m_hIDComDev, &st);
if (!(st&MS_RLSD_ON))
m_bConnected = FALSE;
else
m_bConnected=TRUE;
return m_bConnected;
}/*
int CSerial::Connect(char* phone,LPCTSTR answer)
{
int rc=-1,waitcnt=0;
DWORD dwError;
COMSTAT cs; char msg[50];
if(m_bConnected)
HangupModem();
//DWORD dwstatus;
time_t end ,start;
// GetCommModemStatus(m_hIDComDev,&dwstatus);
sprintf(msg,"atdt%s\r\x00",phone);
int len=strlen(msg);
PurgeComm(m_hIDComDev,PURGE_TXCLEAR | PURGE_RXCLEAR);
// ClearCommError(m_hIDComDev,&dwError,&cs);
SendData((const char*)msg,len,0);
start=time(0);
DWORD dwEvent;
waitcnt=0;
while(1)
{
end=time(0);
WaitCommEvent(m_hIDComDev,&dwEvent,&m_OverlappedRead);
if(dwEvent & EV_RLSD)
{
m_bConnected=true;
rc=0;
break;
}
else if(end-start>=40)
{
m_bConnected=false;
rc=1;
break;
}
else
{
char c[50];
if(ReadData(c,ReadDataWaiting())>0)
{
if(strstr(c,"BUSY")!=NULL)
{
rc=-1;
break;
}
else if(strstr(c,"CARRIER")!=NULL)
{
rc=-1;break;
}
else if(strstr(c,"CONNECT")!=NULL)
{
rc=0; break;
}
}
}
Sleep(100);
PurgeComm(m_hIDComDev,PURGE_RXCLEAR);
}
PurgeComm(m_hIDComDev,PURGE_RXCLEAR);
// ResetEvent(m_OverlappedRead.hEvent);
return rc;
}*/
int CSerial::Connect(char* phone,LPTSTR answer)
{
int rc=4;
char msg[50];
if(m_bConnected)
HangupModem();
//DWORD dwstatus;
time_t end ,start;
// GetCommModemStatus(m_hIDComDev,&dwstatus);
sprintf(msg,"atdt%s\r\x00",phone);
int len=strlen(msg);
PurgeComm(m_hIDComDev,PURGE_TXCLEAR | PURGE_RXCLEAR);
SendData((const char*)msg,len,0);
start=time(0);
while(1)
{
end=time(0);
if(IsConnected())
{
rc=0;
break;
}
else if(end-start>=40)
{
rc=1;
// SendData("ath0\r",5,1);
break;
}
else if(end-start>=20)
{
char *c=(char*)answer;
short rc=ReadEvent(c,1);
rc=-1;
if(rc>len)
break;
}
Sleep(1000);
// PurgeComm(m_hIDComDev,PURGE_RXCLEAR);
}
PurgeComm(m_hIDComDev,PURGE_RXCLEAR);
return rc;
}
int CSerial::SendCmd(const char* cmd,int len)
{
PurgeComm(m_hIDComDev,PURGE_RXCLEAR);
if(SendData(cmd, len,1)==len)
return 0;
else
return -1;
}
void CSerial::RTSControl(BOOL State)
{
if(State)
EscapeCommFunction(m_hIDComDev,SETRTS);
else
EscapeCommFunction(m_hIDComDev,CLRRTS);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -